systemprompt.go RawHistoryFolder
1package agent
2
3import (
4 "fmt"
5 "strings"
6 "time"
7)
8
9// ToolSummary is a name+one-line description. Kept as part of the
10// public opts type for backwards compatibility with callers that
11// still pass tool summaries in; the default prompt no longer lists
12// them because the provider already advertises tools in the request
13// body's tools[] array, so listing them again in prose is pure
14// duplication.
15type ToolSummary struct {
16 Name string
17 Description string
18}
19
20// SystemPromptOpts configures BuildSystemPrompt.
21type SystemPromptOpts struct {
22 CWD string
23 Tools []ToolSummary
24 Custom string // if set, replaces the default identity entirely
25 Append []string // extra text appended at the end
26 Now time.Time
27}
28
29// BuildSystemPrompt constructs the system prompt.
30//
31// Design note: kept intentionally small. Every byte here is part of
32// the cached prefix on every request, so bloat is cumulatively
33// expensive. We ship only:
34//
35// - A one-paragraph identity (who zot is, what the name means,
36// what the TUI expects for output format).
37// - The date + cwd footer so the model has current-context.
38//
39// Everything else (tool listing, operating guidelines, "don't run
40// sudo", "prefer edit over write", etc.) is left out because the
41// current-generation frontier models already internalise it, and
42// the tool schemas sent alongside the request carry each tool's
43// own description.
44//
45// Users who want extra biasing can use --system-prompt (replace),
46// --append-system-prompt (additive, repeatable), or drop a
47// SYSTEM.md in $ZOT_HOME that overrides the default identity.
48func BuildSystemPrompt(o SystemPromptOpts) string {
49 if o.Now.IsZero() {
50 o.Now = time.Now()
51 }
52 date := o.Now.Format("2006-01-02")
53 cwd := o.CWD
54 if cwd == "" {
55 cwd = "."
56 }
57
58 var sb strings.Builder
59
60 if o.Custom != "" {
61 sb.WriteString(o.Custom)
62 } else {
63 sb.WriteString(defaultIdentity)
64 }
65
66 for _, a := range o.Append {
67 if strings.TrimSpace(a) == "" {
68 continue
69 }
70 sb.WriteString("\n\n")
71 sb.WriteString(a)
72 }
73
74 fmt.Fprintf(&sb, "\n\nCurrent date: %s\nCurrent working directory: %s\n", date, cwd)
75 return sb.String()
76}
77
78const 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.
79
80Your 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.
81
82When changing file contents, prefer the edit tool for in-place changes and the write tool for creating or fully replacing files. Do not use bash with cat/echo/sed/tee redirections to mutate files; those changes render as opaque shell output while edit renders as a readable diff.`