feat: add three-layer agent loop protection#2
Merged
Conversation
- Loop detection: track tool call history with a sliding window, inject warning messages at 5 repeats, halt at 8 (critical) or 10 (global circuit breaker) - Step-level retry: exponential backoff up to MAX_RETRIES=3 for retryable API errors (rate limit, timeout, network) - Token budget: accumulate input+output tokens across steps and force-stop when the limit is exceeded (default 15,000)
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
Adds three layers of protection to the agent loop to prevent runaway execution, API failures, and budget overruns.
Changes
New files
src/loop-detection.ts— Tool call history tracker with a 30-entry sliding window and three detectors:generic_repeat: same tool + same args repeated N timesping_pong: two different calls alternatingglobal_circuit_breaker: any call repeated without result changesrc/retry.ts— Step-level retry utilities:calculateDelay(exponential backoff),isRetryable,sleepsrc/mock-model.ts— Offline mock model for testing all three protection layers without a live API keyModified files
src/agent-loop.tsdetect/recordCall/recordResult)MAX_RETRIES = 3) with exponential backoffBudgetState(caller-owned, accumulated across steps)MAX_STEPSbumped 10 → 15 to accommodate retry headroomLanguageModelV3from@ai-sdk/providersrc/index.tsbudgettoagentLoop; auto-select mock model whenDASHSCOPE_API_KEYis absentaskQuestion→askpackage.json— Add@ai-sdk/provider; bump@ai-sdk/openaiandaiTesting
Start the agent without an API key to use the mock model:
Then try the prompts suggested on startup:
测试死循环— triggers loop detection测试重试— triggers retry logic测试预算— triggers token budget cutoff