fix: remove stopReason short-circuit from auto-continue - #15
Conversation
The `stopReason` guard in `shouldAutoContinueIncompleteTurn` (short-circuited since v0.4.17) blocked auto-continue whenever Claude CLI emitted ANY protocol-level stop_reason, even when the model was actively generating tool calls in the same turn. This caused the common "text + tool_calls" pattern to terminate prematurely: Claude would generate an intermediate response like "I'll analyse..." and the plugin would close the turn before the tool calls could execute. The `hadActivity` check (line 466) already covers the "model did nothing" case — if there was no reasoning, tool activity, or proxy activity, auto-continue stops correctly. The stopReason guard was redundant and counterproductive. Also restructured the drain path at the result boundary: instead of calling `drainNow()` (which closes the controller via `finishWithToolCalls`), we now inline the tool-call enqueue and fall through to the auto-continue check. This prevents the controller from being closed before auto-continue gets a chance to fire. Fixes: premature turn termination with Claude Opus 4.7 when generating sub-agent task calls.
There was a problem hiding this comment.
Code Review
This pull request removes the stopReason guard from the auto-continue heuristic to prevent premature termination when tool calls are generated in the same turn. It also updates the language model to manually enqueue tool-call events rather than closing the controller immediately, and updates the corresponding tests. Feedback on these changes highlights a critical deadlock risk where failing to close the stream with pending proxy calls blocks both the CLI and opencode. Additionally, the reviewer notes a misleading version history comment and several outdated test names that contradict their updated assertions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Reverted drain path at turn-result boundary to use drainNow()+return (prevents deadlock when proxy calls are pending) - Fixed misleading version comment (removed guard was added in v0.4.17) - Updated 8 test names to reflect new behavior (stopReason removed)
|
Updated per review:
All 203 tests pass, build clean. |
|
Thanks for the deep analysis and the patience — this deserved a maintainer response much sooner, and the symptom you describe (text + tool_calls turns closing early, needing a manual "continue") is clearly real. Two thoughts before merging this as-is:
Leaving this open pending your retest — and thanks again for the excellent writeup, it made the failure mode easy to understand. |
Problem
The
stopReasonguard inshouldAutoContinueIncompleteTurn(added in v0.4.17) blocked auto-continue whenever Claude CLI emitted ANY protocol-levelstop_reason— even when the model was actively generating tool calls in the same turn.This caused the common "text + tool_calls" pattern to terminate prematurely:
stop_reason: end_turn→ blocks auto-continue immediatelyRoot Cause
The
stopReasoncheck ran before thehadActivitycheck. Whenstop_reasonwas present (which it always is in modern Claude CLI), auto-continue was short-circuited regardless of whether the model was actively working.The
hadActivitycheck already covers the "model did nothing" case — if there was no reasoning, tool activity, or proxy activity, auto-continue stops correctly. ThestopReasonguard was redundant and counterproductive.Fix
Removed the
stopReasonguard fromshouldAutoContinueIncompleteTurn. ThehadActivitycheck already handles the "model did nothing" case correctly.Restructured the drain path at the result boundary: instead of calling
drainNow()(which closes the controller viafinishWithToolCalls), we now inline the tool-call enqueue and fall through to the auto-continue check. This prevents the controller from being closed before auto-continue gets a chance to fire.Test Changes
Updated 8 tests in
test-auto-continue.tsto reflect the new behaviour:end_turn+ tool activity → now continues (was: stopped)max_tokens+ tool activity → now continues (was: stopped)stop_sequence+ reasoning → now continues (was: stopped)pause_turn+ reasoning → now continues (was: stopped)tool_use+ tool activity → now continues (was: stopped)refusal+ no activity → still stops (viano-activity)stop_reason+ no activity → still stops (viano-activity)end_turn+ max-attempts → still stops (viamax-attempts)All 203 tests pass.
Impact
This fixes the premature turn termination users experience with Claude Opus 4.7 when generating sub-agent task calls. The model no longer needs manual "Continua então." prompts to keep working after generating tool calls.