v0.3.92 6d56e22

systemprompt.go RawHistoryFolder

1package agent
2
3import (
4	"fmt"
5	"runtime"
6	"strings"
7	"time"
8)
9
10// ToolSummary is a name+one-line description. Kept as part of the
11// public opts type for backwards compatibility with callers that
12// still pass tool summaries in; the default prompt no longer lists
13// them because the provider already advertises tools in the request
14// body's tools[] array, so listing them again in prose is pure
15// duplication.
16type ToolSummary struct {
17	Name        string
18	Description string
19}
20
21// SystemPromptOpts configures BuildSystemPrompt.
22type SystemPromptOpts struct {
23	CWD        string
24	Tools      []ToolSummary
25	Custom     string   // when CustomSet, replaces the built-in identity and docs guidance
26	CustomSet  bool     // preserves an intentionally empty custom prompt
27	Append     []string // extra text appended at the end
28	Now        time.Time
29	ZotDocsDir string
30	GOOS       string // defaults to runtime.GOOS; overridable for tests
31	GOARCH     string // defaults to runtime.GOARCH
32}
33
34// BuildSystemPrompt constructs the system prompt.
35//
36// Design note: kept intentionally small. Every byte here is part of
37// the cached prefix on every request, so bloat is cumulatively
38// expensive. We ship only:
39//
40//   - A one-paragraph identity (who zot is, what the name means,
41//     what the TUI expects for output format).
42//   - The date + cwd footer so the model has current-context.
43//
44// Everything else (tool listing, operating guidelines, "don't run
45// sudo", "prefer edit over write", etc.) is left out because the
46// current-generation frontier models already internalise it, and
47// the tool schemas sent alongside the request carry each tool's
48// own description.
49//
50// Users who want extra biasing can use --system-prompt (replace),
51// --append-system-prompt (additive, repeatable), or drop a
52// SYSTEM.md in $ZOT_HOME that overrides the default identity.
53func BuildSystemPrompt(o SystemPromptOpts) string {
54	if o.Now.IsZero() {
55		o.Now = time.Now()
56	}
57	date := o.Now.Format("2006-01-02")
58	cwd := o.CWD
59	if cwd == "" {
60		cwd = "."
61	}
62
63	var sb strings.Builder
64
65	if o.CustomSet || o.Custom != "" {
66		sb.WriteString(o.Custom)
67	} else {
68		sb.WriteString(defaultIdentity)
69		if strings.TrimSpace(o.ZotDocsDir) != "" {
70			sb.WriteString("\n\nZot's own docs are installed under ")
71			sb.WriteString(o.ZotDocsDir)
72			sb.WriteString("; use the read tool there when you need details about zot RPC, extensions, skills, or built-in behaviour.")
73		}
74	}
75
76	for _, a := range o.Append {
77		if strings.TrimSpace(a) == "" {
78			continue
79		}
80		sb.WriteString("\n\n")
81		sb.WriteString(a)
82	}
83
84	fmt.Fprintf(&sb, "\n\nCurrent date: %s\nCurrent working directory: %s\n", date, cwd)
85	sb.WriteString(platformLine(o.GOOS, o.GOARCH))
86	return sb.String()
87}
88
89// platformLine tells the model which OS and shell dialect its commands
90// run under. Without it models default to POSIX syntax, and on Windows
91// every failed grep/ls/&&-chain round-trip wastes a tool call and its
92// tokens. Kept to one or two lines because it sits in the cached prefix.
93func platformLine(goos, goarch string) string {
94	if goos == "" {
95		goos = runtime.GOOS
96	}
97	if goarch == "" {
98		goarch = runtime.GOARCH
99	}
100	line := fmt.Sprintf("Platform: %s/%s\n", goos, goarch)
101	if goos == "windows" {
102		line += windowsShellHint
103	}
104	return line
105}
106
107const windowsShellHint = `The bash tool runs cmd.exe /C, not a POSIX shell: use cmd syntax (dir, type, findstr, where, set, %VAR%, backslash paths); grep, ls, cat, sed, head, $VAR, and single quotes do not work. Keep commands simple: cmd's quoting breaks on nested double quotes, so prefer the read and glob tools for searching, git grep for code, and powershell -NoProfile -File <script.ps1> for anything complex.
108`
109
110const defaultIdentity = `You are an expert coding assistant operating inside zot, a coding agent harness. The name "zot" stands for "zero-overhead-tool"; if the user asks what zot means, answer exactly that.
111
112Your output renders in a TUI that understands markdown for prose and plain text for tool output. Use markdown freely, keep answers concise, and let tool calls speak for themselves rather than narrating them in prose before you invoke them. Act first, then summarise what you did.
113
114For focused changes to an existing file, inspect its current contents and use edit with verbatim oldText taken from that same file. Include only enough context to make each match unambiguous. Use write when creating a file or replacing it wholesale. Do not mutate files through bash redirections or commands such as cat, echo, sed, or tee, because those changes appear as opaque shell output instead of a readable edit diff.`

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 477

↑↓ moveenter openesc close