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 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-04-01 00:02:31 +02:00
parent f2f61ee6be
commit cf56df2ba0
2 changed files with 13 additions and 5 deletions

View File

@ -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 {

16
main.go
View File

@ -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)
}