From 939f41013ef1340af7b1e83346e46df0ef8becc2 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Tue, 7 Apr 2026 10:51:10 +0200 Subject: [PATCH] agent: fix stall state always firing on normal text responses The "no tools" stall condition (totalToolCalls==0 && hadContent) fired whenever the bot replied in plain text without calling any tools, which is the normal completion path. The UI would then see agentStalled before the done message and never transition back to agentIdle. Removed the "no tools" stall; only the max-steps limit case is a real stall worth surfacing. Co-Authored-By: Claude Sonnet 4.6 --- agent/loop.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/agent/loop.go b/agent/loop.go index e028f10..0a64480 100644 --- a/agent/loop.go +++ b/agent/loop.go @@ -45,7 +45,6 @@ func Run(ctx context.Context, cfg Config, state State) error { } var totalToolCalls int - var hadContent bool hitLimit := false for step := range maxSteps { @@ -97,9 +96,6 @@ func Run(ctx context.Context, cfg Config, state State) error { if !done { return fmt.Errorf("step %d: stream ended without done event", step) } - if content.Len() > 0 { - hadContent = true - } totalToolCalls += len(toolCalls) // Announce and execute tool calls. @@ -163,11 +159,9 @@ func Run(ctx context.Context, cfg Config, state State) error { } } - // Surface stall conditions so the UI can indicate them. + // Surface stall: only when the step limit was hit without completing. if hitLimit { emit(cfg, OutputMsg{Role: "stalled", Content: "max steps"}) - } else if totalToolCalls == 0 && hadContent { - emit(cfg, OutputMsg{Role: "stalled", Content: "no tools"}) } return nil