From 6fc2e001acd72f7a8ecfcf615338fc2523e4e894 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Thu, 30 Jul 2026 09:24:08 +0200 Subject: [PATCH] tools: promote reasoning_think to builtin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- tools/builtins.go | 15 ++++++++------- tools/reasoning.go | 25 +++++++++++++++++++++++++ toolsrv/server.go | 11 +++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 tools/reasoning.go diff --git a/tools/builtins.go b/tools/builtins.go index d1db7e1..fc6d4e1 100644 --- a/tools/builtins.go +++ b/tools/builtins.go @@ -7,12 +7,13 @@ import "ollie/toolsrv" // Builtins returns the default set of built-in tool handlers. func Builtins() map[string]toolsrv.Handler { return map[string]toolsrv.Handler{ - "shell": Shell, - "tool_list": ToolList, - "tool_load": ToolLoad, - "tool_active": ToolActive, - "skill_list": SkillList, - "skill_load": SkillLoad, - "skill_active": SkillActive, + "shell": Shell, + "reasoning_think": Think, + "tool_list": ToolList, + "tool_load": ToolLoad, + "tool_active": ToolActive, + "skill_list": SkillList, + "skill_load": SkillLoad, + "skill_active": SkillActive, } } diff --git a/tools/reasoning.go b/tools/reasoning.go new file mode 100644 index 0000000..fa35ebd --- /dev/null +++ b/tools/reasoning.go @@ -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 +} diff --git a/toolsrv/server.go b/toolsrv/server.go index 6b5b84a..748c779 100644 --- a/toolsrv/server.go +++ b/toolsrv/server.go @@ -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 != "" {