tools: promote reasoning_think to builtin

Zero-context-cost scratchpad tool. The thought is recorded in history
but returns empty — no output tokens wasted. Registered in ListTools
schema and builtins map.
This commit is contained in:
Levi Neely 2026-07-30 09:24:08 +02:00
parent 10bd60980a
commit 6fc2e001ac
3 changed files with 44 additions and 7 deletions

View File

@ -8,6 +8,7 @@ import "ollie/toolsrv"
func Builtins() map[string]toolsrv.Handler {
return map[string]toolsrv.Handler{
"shell": Shell,
"reasoning_think": Think,
"tool_list": ToolList,
"tool_load": ToolLoad,
"tool_active": ToolActive,

25
tools/reasoning.go Normal file
View File

@ -0,0 +1,25 @@
package tools
import (
"context"
"encoding/json"
"fmt"
"ollie/toolsrv"
)
// Think is a scratchpad for externalizing reasoning. The thought is recorded
// in conversation history but not shown to the user. Takes up practically
// zero context space — the value is in writing it.
func Think(ctx context.Context, srv *toolsrv.Server, args json.RawMessage) (string, error) {
var a struct {
Thought string `json:"thought"`
}
if err := json.Unmarshal(args, &a); err != nil {
return "", fmt.Errorf("reasoning_think: bad args: %w", err)
}
if a.Thought == "" {
return "", fmt.Errorf("reasoning_think: thought is required")
}
return "", nil
}

View File

@ -201,6 +201,17 @@ Returns tools with descriptions, one per line.`,
"properties": {}
}`),
},
{
Name: "reasoning_think",
Description: `Scratchpad for externalizing reasoning. Recorded in history but not shown to the user.`,
InputSchema: json.RawMessage(`{
"type": "object",
"required": ["thought"],
"properties": {
"thought": {"type": "string", "description": "Your reasoning."}
}
}`),
},
}
if e.toolRegistry != nil && e.sessionID != "" {