Repository navigation
Add runaway-loop guard to the agent loop (#97) - #106
Merged
Merged
Conversation
New opt-in UseChatController(maxIdenticalToolCalls:) halts the agent loop with a typed AgentLoopException when the model keeps requesting the same tool call (identical name + JSON args) after it has already run that many times in one turn — instead of looping to maxSteps and burning tokens. 0 (the default) disables it, so existing behavior is unchanged. Complements the existing tokenBudget token ceiling and per-call arg-validation containment. Signatures are tracked per turn and cleared on submit/ regenerate/edit. Closes #97 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Closes #97.
What
An opt-in agent guardrail on
UseChatController:maxIdenticalToolCalls(default0= off) halts the agent loop with a typedAgentLoopExceptionwhen the model keeps requesting the same tool call — identicaltoolNameand JSON-encodedargs— after it has already run that many times in a turn. Instead of looping up tomaxStepsand burning tokens on a runaway self-call, the turn ends witherrorset toAgentLoopException.Why this shape
The controller already had two of the three guardrails from #97:
tokenBudget.ToolResultPartback to the model.The missing piece was runaway-loop detection, added here. It's opt-in (like
tokenBudget) so existing behavior is byte-for-byte unchanged until you set it.Details
toolName(jsonEncode(args))), cleared on submit / regenerate / edit._onStreamDonebefore re-prompting; the count is incremented for the calls actually executed.AgentLoopExceptionis exported via the client barrel.Verification
flutter test packages/flutter_ai_client— 39 pass, incl. 2 new tests (guard trips withAgentLoopException; disabled-by-default path unaffected)flutter analyzeclean ·dart formatclean repo-wideVersion
flutter_ai_client0.2.2 (additive; no core constraint change)🤖 Generated with Claude Code