fix: auto-continue circuit breaker + node timeout - #244
Merged
Conversation
When the model generates thinking content but hits the output token limit, committedContent remains empty and the auto-continue logic fires repeatedly, adding more context and making it harder for the model to produce text. This creates a feedback loop that results in empty messages in the TUI. Fix: - Track consecutive auto-continue attempts with a ref counter - Circuit breaker: stop after 3 consecutive empty responses - Update committedContent during auto-continue (was only updating responseContent, causing the final message to render empty) - Add isAutoContinuingRef to distinguish auto-continue text from the initial response, preventing premature counter reset - Show a system message when the circuit breaker triggers, alerting the user that the model may be stuck in a reasoning loop Inspired by LangGraph's fault tolerance primitives: RetryPolicy, TimeoutPolicy, and error_handler patterns.
With auto-compaction active, context bloat is not a concern. Increase the circuit breaker from 3 to 1000 to allow the model more room to work through complex reasoning cycles.
Add agent.nodeTimeout (default 600000ms / 10 minutes) to config.yaml and the config schema. This will be used to set the superstep timeout on the LangGraph agent.
Add agent.nodeTimeout: 600000 (10 minutes) to config.yaml.
Add optional timeout parameter (default 10 minutes) to createReactAgent. Sets stepTimeout on the compiled graph to prevent nodes from hanging indefinitely. This is LangGraph's mechanism for capping superstep execution time.
Pass config.agent.nodeTimeout to createReactAgent so the LangGraph agent gets a 10-minute superstep timeout by default. This prevents nodes from hanging indefinitely.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
When the model generates thinking content but hits the output token limit, the auto-continue logic fires repeatedly. With auto-compaction active, context bloat is not a concern, but the model can still get stuck in a reasoning loop producing no text output.
Auto-Continue Circuit Breaker:
agent.autoContinueLimit, default 1000) that stops auto-continue and alerts the usercommittedContentduring auto-continue (was only updatingresponseContent, causing the final message to render empty)isAutoContinuingRefto prevent premature counter resetNode Timeout:
agent.nodeTimeout(default 600000ms / 10 minutes) toconfig.yamland the config schemacreateReactAgentas astepTimeouton the compiled LangGraph agentTemperature Adjustment:
0.7to0.4for more deterministic responsesDocumentation:
AGENT_AUTO_CONTINUE_LIMITandAGENT_NODE_TIMEOUTenvironment variablesThe circuit breaker threshold is configurable in
config.yamlunderagent.autoContinueLimitto allow tuning without code changes.Inspired by LangGraph fault tolerance primitives: RetryPolicy, TimeoutPolicy, and error_handler.
Type of Change
Testing
oxlint) passes with 0 warnings and 0 errorsCoverage
Checklist
npm run lintpasses