From cf56df2ba0fbdfdb63a508dca4f76494bf0ed64e Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Wed, 1 Apr 2026 00:02:31 +0200 Subject: [PATCH] Show tool invocations in chat; fix planning loop stall Emit a 'call' message before each tool execution so the UI shows execute_code(...) with full args before the result. Result lines are now indented with '= ' to visually pair with the call. System prompt now explicitly says to call execute_code immediately after planning, without pausing for confirmation, to prevent smaller models stalling after the planning step. Co-Authored-By: Claude Sonnet 4.6 --- agent/loop.go | 2 ++ main.go | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/agent/loop.go b/agent/loop.go index 6e12a43..dc25e87 100644 --- a/agent/loop.go +++ b/agent/loop.go @@ -68,6 +68,8 @@ func (l *Loop) Run(ctx context.Context, state State) error { var content string var isErr bool + l.emit(OutputMsg{Role: "call", Name: tc.Name, Content: string(tc.Arguments)}) + if l.cfg.Exec != nil { out, err := l.cfg.Exec(tc.Name, tc.Arguments) if err != nil { diff --git a/main.go b/main.go index 8fee16d..2acb7f4 100644 --- a/main.go +++ b/main.go @@ -65,13 +65,17 @@ If a relevant skill is found, load it: Read and follow the loaded skill's instructions before proceeding. Re-run discovery if the task domain shifts during execution. -## Step 2 — plan before acting +## Step 2 — plan, then execute immediately -After skill discovery, state a short numbered plan: +After skill discovery, write a short numbered plan, then execute it without +waiting for user input: 1. Restate the goal. 2. List the steps you will take. -Then execute the steps in order. Revise the plan if a step fails or reveals -new information.` +3. Call execute_code for the first step immediately after writing the plan. + +Do not stop after planning. Do not ask for confirmation. Execute each step +in sequence, calling execute_code as many times as needed. Revise the plan +if a step fails or reveals new information.` // executeCodeTool is the single built-in tool exposed to the model. var executeCodeTool = backend.Tool{ @@ -255,8 +259,10 @@ func (m model) runLoop(input string) tea.Cmd { switch msg.Role { case "assistant": lines = append(lines, "Bot: "+msg.Content) + case "call": + lines = append(lines, fmt.Sprintf("→ %s(%s)", msg.Name, msg.Content)) case "tool": - lines = append(lines, fmt.Sprintf("→ %s: %s", msg.Name, msg.Content)) + lines = append(lines, fmt.Sprintf(" = %s", msg.Content)) case "error": lines = append(lines, "Error: "+msg.Content) }