]> git.giacomolli.uk - onechat/commitdiff
Name the tool schemas of the prompt
authorAnderson A. Giacomolli <agiacomolli@gmail.com>
Sat, 7 Nov 2026 16:56:02 +0000 (13:56 -0300)
committerAnderson A. Giacomolli <agiacomolli@gmail.com>
Sat, 7 Nov 2026 16:56:02 +0000 (13:56 -0300)
The function tools that every model call sends are promptTools, and
their schema helpers start with prompt too. The turns and the
compactions send the same prompt and tools, so the tools are a part of
the prompt, and agentTools read as the tools of an agent next to the
agent config. The parts of the prompt text, such as the task sentence
and the clause on the instructions, start with prompt as well.

The declarations of prompt.go already follow the order of the go-code
skill. The behavior does not change.

Issue: 947bddb

compactor.go
compactor_test.go
prompt.go
prompt_test.go
turn.go

index 48b855b743ae56cf6793e175be5543e8ef4ba1d5..71d72c1bc651eb8209df813fa6e456d8822d836d 100644 (file)
@@ -42,7 +42,7 @@ func newCompactor(client *ModelClient, instructions func() (string, error), mode
                client:       client,
                model:        model,
                instructions: instructions,
-               tools:        agentTools(),
+               tools:        promptTools(),
        }
 }
 
index 8b14c81ff4423ed47f18f29d0b02bd3e0dc93aa3..5a4474c885d1ff08268502d4bea1d5d5ab43cb19 100644 (file)
@@ -33,7 +33,7 @@ func TestCompactorSendsThePromptToolsAndTask(t *testing.T) {
        require.Equal(t, map[string]any{"effort": "high"}, body["reasoning"])
        require.Equal(t, "agent-key", body["prompt_cache_key"])
 
-       tools, err := json.Marshal(agentTools())
+       tools, err := json.Marshal(promptTools())
        require.NoError(t, err)
 
        sent, err := json.Marshal(body["tools"])
index 546a86b4c2eec9aa7abf408614f14e351afbca32..c6df0575f5686ef8708b099ddf6d0046180690f0 100644 (file)
--- a/prompt.go
+++ b/prompt.go
@@ -9,17 +9,17 @@ const (
        // promptName stands for the name of the agent in promptText.
        promptName = "{name}"
 
-       // taskSentence is the sentence of promptText that gets instructionsClause
-       // when the user has instructions.
-       taskSentence = "Do the user's tasks yourself, with your tools."
+       // promptTaskSentence is the sentence of promptText that gets
+       // promptInstructionsClause when the user has instructions.
+       promptTaskSentence = "Do the user's tasks yourself, with your tools."
 
-       // instructionsClause points to the instructions of the user at the end
-       // of the prompt.
-       instructionsClause = ", following the user's instructions\nat the end of this prompt: who they are, how their files are organized and how\nthey want work done"
+       // promptInstructionsClause points to the instructions of the user at
+       // the end of the prompt.
+       promptInstructionsClause = ", following the user's instructions\nat the end of this prompt: who they are, how their files are organized and how\nthey want work done"
 
-       // instructionsHeading starts the instructions of the user after
+       // promptInstructionsHeading starts the instructions of the user after
        // promptText.
-       instructionsHeading = "\n\n# The user's instructions\n\n"
+       promptInstructionsHeading = "\n\n# The user's instructions\n\n"
 )
 
 // promptText is the system prompt of the reference design, nearly word for
@@ -126,23 +126,23 @@ func prompt(name, instructions string) string {
                return text
        }
 
-       text = strings.Replace(text, taskSentence, strings.TrimSuffix(taskSentence, ".")+instructionsClause+".", 1)
+       text = strings.Replace(text, promptTaskSentence, strings.TrimSuffix(promptTaskSentence, ".")+promptInstructionsClause+".", 1)
 
-       return text + instructionsHeading + instructions
+       return text + promptInstructionsHeading + instructions
 }
 
-// agentTools returns the function tools of every call: zoom, date, shell,
+// promptTools returns the function tools of every call: zoom, date, shell,
 // read, write, and edit. A compaction sends them too and never calls them,
 // because a change of the tools ends the shared prompt cache.
-func agentTools() []ModelTool {
+func promptTools() []ModelTool {
        return []ModelTool{
                {
                        Type:        "function",
                        Name:        "zoom",
                        Description: "Open the line id+n of the view into the two lines of n/2 under it; n = 1 gives the message whole.",
-                       Parameters: objectSchema(map[string]any{
-                               "id": integerSchema("The first message of the line: a multiple of n."),
-                               "n":  integerSchema("The number of messages of the line: a power of 2."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "id": promptIntegerSchema("The first message of the line: a multiple of n."),
+                               "n":  promptIntegerSchema("The number of messages of the line: a power of 2."),
                        }),
                        Strict: true,
                },
@@ -150,8 +150,8 @@ func agentTools() []ModelTool {
                        Type:        "function",
                        Name:        "date",
                        Description: "The date and time of message id.",
-                       Parameters: objectSchema(map[string]any{
-                               "id": integerSchema("The message."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "id": promptIntegerSchema("The message."),
                        }),
                        Strict: true,
                },
@@ -159,8 +159,8 @@ func agentTools() []ModelTool {
                        Type:        "function",
                        Name:        "shell",
                        Description: "Run a command with bash, as the user, in the working directory, with no input. Gives its output and error output, and its exit status when it fails.",
-                       Parameters: objectSchema(map[string]any{
-                               "command": stringSchema("The bash command."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "command": promptStringSchema("The bash command."),
                        }),
                        Strict: true,
                },
@@ -168,8 +168,8 @@ func agentTools() []ModelTool {
                        Type:        "function",
                        Name:        "read",
                        Description: "Read a text file.",
-                       Parameters: objectSchema(map[string]any{
-                               "path": stringSchema("The file, absolute or relative to the working directory."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "path": promptStringSchema("The file, absolute or relative to the working directory."),
                        }),
                        Strict: true,
                },
@@ -177,9 +177,9 @@ func agentTools() []ModelTool {
                        Type:        "function",
                        Name:        "write",
                        Description: "Write a text file whole, replacing it when it exists. Makes the missing directories.",
-                       Parameters: objectSchema(map[string]any{
-                               "path": stringSchema("The file, absolute or relative to the working directory."),
-                               "text": stringSchema("The whole new content."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "path": promptStringSchema("The file, absolute or relative to the working directory."),
+                               "text": promptStringSchema("The whole new content."),
                        }),
                        Strict: true,
                },
@@ -187,19 +187,19 @@ func agentTools() []ModelTool {
                        Type:        "function",
                        Name:        "edit",
                        Description: "Replace the one occurrence of old in a text file with new.",
-                       Parameters: objectSchema(map[string]any{
-                               "path": stringSchema("The file, absolute or relative to the working directory."),
-                               "old":  stringSchema("The exact text to replace. It must occur once in the file."),
-                               "new":  stringSchema("The text that replaces old."),
+                       Parameters: promptObjectSchema(map[string]any{
+                               "path": promptStringSchema("The file, absolute or relative to the working directory."),
+                               "old":  promptStringSchema("The exact text to replace. It must occur once in the file."),
+                               "new":  promptStringSchema("The text that replaces old."),
                        }),
                        Strict: true,
                },
        }
 }
 
-// objectSchema returns a strict JSON schema of an object whose properties are
-// all required.
-func objectSchema(properties map[string]any) map[string]any {
+// promptObjectSchema returns a strict JSON schema of an object whose properties
+// are all required.
+func promptObjectSchema(properties map[string]any) map[string]any {
        required := make([]string, 0, len(properties))
        for name := range properties {
                required = append(required, name)
@@ -215,16 +215,16 @@ func objectSchema(properties map[string]any) map[string]any {
        }
 }
 
-// integerSchema returns the JSON schema of an integer.
-func integerSchema(description string) map[string]any {
+// promptIntegerSchema returns the JSON schema of an integer.
+func promptIntegerSchema(description string) map[string]any {
        return map[string]any{
                "type":        "integer",
                "description": description,
        }
 }
 
-// stringSchema returns the JSON schema of a string.
-func stringSchema(description string) map[string]any {
+// promptStringSchema returns the JSON schema of a string.
+func promptStringSchema(description string) map[string]any {
        return map[string]any{
                "type":        "string",
                "description": description,
index c9d3691ba038ab6830a9de6925c497663a22dd76..902cb8677e7d3617f901e4b716c8237a229b701a 100644 (file)
@@ -47,7 +47,7 @@ func TestPromptWithoutInstructionsHasNoClause(t *testing.T) {
 }
 
 func TestAgentToolsAreStrictAndStable(t *testing.T) {
-       tools := agentTools()
+       tools := promptTools()
        names := make([]string, len(tools))
        for n, tool := range tools {
                names[n] = tool.Name
@@ -67,7 +67,7 @@ func TestAgentToolsAreStrictAndStable(t *testing.T) {
        require.NoError(t, err)
 
        for range 10 {
-               again, err := json.Marshal(agentTools())
+               again, err := json.Marshal(promptTools())
                require.NoError(t, err)
                require.Equal(t, first, again)
        }
diff --git a/turn.go b/turn.go
index 1593f434be72635911ef72958a43d960fc3fa7f1..c0a87e8d923a59e104dfe83a024e24331a268411 100644 (file)
--- a/turn.go
+++ b/turn.go
@@ -261,7 +261,7 @@ func (l *TurnLoop) chain(ctx context.Context) error {
                        Model:        l.agent.config.Model,
                        Effort:       l.agent.config.Effort,
                        Instructions: instructions,
-                       Tools:        agentTools(),
+                       Tools:        promptTools(),
                        Input:        input,
                        Turn:         turn,
                })