feat(background-agent): add smart circuit breaker for repeated tool calls#2639
Merged
code-yeongyu merged 3 commits intodevfrom Mar 17, 2026
Merged
feat(background-agent): add smart circuit breaker for repeated tool calls#2639code-yeongyu merged 3 commits intodevfrom
code-yeongyu merged 3 commits intodevfrom
Conversation
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
There was a problem hiding this comment.
2 issues found across 9 files
Confidence score: 2/5
- There is a high-confidence, high-severity logic issue in
src/features/background-agent/manager.ts: deduplication skips certain status updates (like "completed"), so the same tool call can be counted multiple times, which can directly skew agent behavior. - Because this affects core counting logic rather than just test quality, merge risk is elevated despite the rest of the PR being limited in size.
src/features/background-agent/loop-detector.test.tsalso has a validity gap: the "diverse tools" case passes due to early exit fromwindowSize, so it may not catch regressions in diversity evaluation.- Pay close attention to
src/features/background-agent/manager.tsandsrc/features/background-agent/loop-detector.test.ts- fix deduplication handling and make sure the test actually exercises tool-diversity logic.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/background-agent/manager.ts">
<violation number="1" location="src/features/background-agent/manager.ts:902">
P1: Custom agent: **Opencode Compatibility**
The deduplication logic fails for status updates like "completed", causing the same tool call to be counted multiple times. Remove the status check to correctly count each unique tool ID exactly once.</violation>
</file>
<file name="src/features/background-agent/loop-detector.test.ts">
<violation number="1" location="src/features/background-agent/loop-detector.test.ts:56">
P2: The 'diverse tools' test passes for the wrong reason: it exits early due to the default `windowSize` (20) being larger than the sample size (10). It never actually evaluates tool diversity.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Comment on lines
+902
to
+912
| !partInfo.id || | ||
| partInfo.state?.status !== "running" || | ||
| !countedToolPartIDs.includes(partInfo.id) | ||
|
|
||
| if (!shouldCountToolCall) { | ||
| return | ||
| } | ||
|
|
||
| if (partInfo.id && partInfo.state?.status === "running") { | ||
| task.progress.countedToolPartIDs = [...countedToolPartIDs, partInfo.id] | ||
| } |
There was a problem hiding this comment.
P1: Custom agent: Opencode Compatibility
The deduplication logic fails for status updates like "completed", causing the same tool call to be counted multiple times. Remove the status check to correctly count each unique tool ID exactly once.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/background-agent/manager.ts, line 902:
<comment>The deduplication logic fails for status updates like "completed", causing the same tool call to be counted multiple times. Remove the status check to correctly count each unique tool ID exactly once.</comment>
<file context>
@@ -876,10 +897,50 @@ export class BackgroundManager {
if (partInfo?.type === "tool" || partInfo?.tool) {
+ const countedToolPartIDs = task.progress.countedToolPartIDs ?? []
+ const shouldCountToolCall =
+ !partInfo.id ||
+ partInfo.state?.status !== "running" ||
+ !countedToolPartIDs.includes(partInfo.id)
</file context>
Suggested change
| !partInfo.id || | |
| partInfo.state?.status !== "running" || | |
| !countedToolPartIDs.includes(partInfo.id) | |
| if (!shouldCountToolCall) { | |
| return | |
| } | |
| if (partInfo.id && partInfo.state?.status === "running") { | |
| task.progress.countedToolPartIDs = [...countedToolPartIDs, partInfo.id] | |
| } | |
| !partInfo.id || | |
| !countedToolPartIDs.includes(partInfo.id) | |
| if (!shouldCountToolCall) { | |
| return | |
| } | |
| if (partInfo.id) { | |
| task.progress.countedToolPartIDs = [...countedToolPartIDs, partInfo.id] | |
| } |
| "read", | ||
| "grep", | ||
| "edit", | ||
| ]) |
There was a problem hiding this comment.
P2: The 'diverse tools' test passes for the wrong reason: it exits early due to the default windowSize (20) being larger than the sample size (10). It never actually evaluates tool diversity.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/background-agent/loop-detector.test.ts, line 56:
<comment>The 'diverse tools' test passes for the wrong reason: it exits early due to the default `windowSize` (20) being larger than the sample size (10). It never actually evaluates tool diversity.</comment>
<file context>
@@ -0,0 +1,117 @@
+ "read",
+ "grep",
+ "edit",
+ ])
+
+ const result = detectRepetitiveToolUse(window)
</file context>
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
maxToolCallslimit as a backstop and add schema coverage for the new nested circuit breaker settingsmessage.part.updatedevents for the same running tool part so one invocation is only counted onceTesting
bun test src/config/schema/background-task.test.ts src/config/schema/background-task-circuit-breaker.test.ts src/features/background-agent/loop-detector.test.ts src/features/background-agent/manager-circuit-breaker.test.ts src/features/background-agent/manager.test.tsbun run typecheckbun run buildloop-detectorandBackgroundManagerwith Bun scripts to verify repetition detection and duplicate tool-part dedupeRelated Issues
Summary by cubic
Add a smart, sliding‑window circuit breaker to
BackgroundManagerthat cancels tasks when one tool dominates recent calls, while keepingmaxToolCallsas a backstop. Addresses #2635 by preventing infinite tool loops and reducing wasted tokens.New Features
maxToolCalls: 200); cancels early with a clear reason.circuitBreakerconfig (maxToolCalls,windowSize,repetitionThresholdPercent) inBackgroundTaskConfigand JSON schema; added loop‑detector helpers and tests.Bug Fixes
message.part.updatedevents for the same running tool part so a single invocation is counted once.Written for commit ae3befb. Summary will update on new commits.