fix(circuit-breaker): treat unknown tool input as non-comparable to prevent false positives on flat events#2796
Merged
code-yeongyu merged 1 commit intocode-yeongyu:devfrom Mar 24, 2026
Conversation
There was a problem hiding this comment.
No issues found across 3 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Auto-approved: Fixes circuit breaker false positives on flat events by resetting consecutive count for calls with unknown inputs. Safety is maintained via the maxToolCalls backstop.
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.
Summary
d48ea025, specifically when events arrive in flat format withoutstate.inputundefined/null) is now treated as non-comparable — consecutive counter resets to 1 each time, instead of accumulating on bare tool name signaturesContext
#2655 introduced target-aware signatures (
toolName::sortedJson(input)) to fix false-positive cancellations. Thend48ea025refactored detection from sliding-window to consecutive-count. Both changes are correct individually, but together they leave a gap:createToolCallSignature()falls back to bare tool name whentoolInputisundefined/null:This matters because
resolveMessagePartInfo()has two event paths:state.inputproperties.partexistsread::{"filePath":"/a.ts"}— differentiatesproperties.partread— bare, all calls "identical"With consecutive-count detection, 20 flat-format
readevents (reading 20 different files) all produce signature"read", hitting the threshold. This is the exact scenario reported in #2652 — agents like Oracle/Explore/Librarian doing legitimate multi-file reads get cancelled.Changes
src/features/background-agent/loop-detector.tsEarly return in
recordToolCall()whentoolInputisundefined/null: returns a unique sentinel signature (toolName::__unknown-input__) withconsecutiveCount: 1. This means:maxToolCallscap → unaffected, still catches runaway agentssrc/features/background-agent/loop-detector.test.tsundefinedinput → does NOT triggernullinput → does NOT triggersrc/features/background-agent/manager-circuit-breaker.test.tsreadevents withoutstate.input→ task keeps runningmaxToolCallsTesting
Related Issues
Follow-up to #2655 / #2652
Summary by cubic
Fixes circuit breaker false positives on flat-format tool events with no input. Unknown tool input is now treated as non-comparable, so consecutive counts reset and valid multi-file reads aren’t cancelled.
recordToolCall(),undefined/nullinput returnstoolName::__unknown-input__withconsecutiveCount = 1.maxToolCallsbackstop unchanged.Written for commit b9fa2a3. Summary will update on new commits.