v0.1.21 b2fa0e3

main.go RawHistoryFolder

1// weather — demonstrates a tool-providing extension.
2//
3// Registers ONE tool the LLM can call:
4//
5//	weather(city: string) -> short fake weather string
6//
7// Build it:
8//
9//	cd examples/extensions/weather
10//	go build -o weather .
11//
12// Then drop it next to its extension.json under
13// $ZOT_HOME/extensions/weather/, or run `zot ext install ./weather`
14// from this directory. After that, asking zot anything like
15// "what's the weather in Berlin?" makes the model call the tool.
16package main
17
18import (
19	"crypto/sha1"
20	"encoding/json"
21	"fmt"
22	"strings"
23
24	"github.com/patriceckhart/zot/pkg/zotext"
25)
26
27const weatherSchema = `{
28  "type": "object",
29  "properties": {
30    "city": {
31      "type": "string",
32      "description": "City name to look up the weather for."
33    }
34  },
35  "required": ["city"]
36}`
37
38func main() {
39	ext := zotext.New("weather", "1.0.0")
40
41	ext.Tool("weather", "Get the current weather for a city.", json.RawMessage(weatherSchema), func(args json.RawMessage) zotext.ToolResult {
42		var in struct {
43			City string `json:"city"`
44		}
45		if err := json.Unmarshal(args, &in); err != nil {
46			return zotext.TextErrorResult("invalid args: " + err.Error())
47		}
48		city := strings.TrimSpace(in.City)
49		if city == "" {
50			return zotext.TextErrorResult("city is required")
51		}
52		// Stable fake "weather": derive temperature + condition from a
53		// hash of the city name so the same city always reports the
54		// same thing. No API calls, no timezone math, no surprises.
55		return zotext.TextResult(fakeWeather(city))
56	})
57
58	if err := ext.Run(); err != nil {
59		ext.Logf("fatal: %v", err)
60	}
61}
62
63func fakeWeather(city string) string {
64	sum := sha1.Sum([]byte(strings.ToLower(city)))
65	temp := (int(sum[0])%30 - 5) // -5..24 °C
66	conditions := []string{"sunny", "cloudy", "drizzle", "rain", "thunderstorm", "fog", "snow", "windy"}
67	cond := conditions[int(sum[1])%len(conditions)]
68	return fmt.Sprintf("%s: %d°C, %s (this is a deterministic fake; the weather extension is a demo)", city, temp, cond)
69}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close