Analyzed GitHub issue and related comments.
UnderstandTraced code path for error handling and context overflow.
UnderstandModified overflow detection to exclude 429 errors.
EditUpdated retry logic and changelog.
EditCommitted, pushed, and commented to close issue.
VerifyAnalyze GitHub issue(s): https://github.com/badlogic/pi-mono/issues/1038 figure out why we auto-compact on 429
For each issue:
Read the issue in full, including all comments and linked issues/PRs.
For bugs:
For feature requests:
Do NOT implement unless explicitly asked. Analyze and propose only.
Now let me trace the code path. I'll look at how errors are handled and where context overflow detection occurs.
Let me look at the isContextOverflow function to understand how context overflow is detected:
Let me check the retry error handling logic:
Let me read the full retry error detection logic:
429 HTTP status code (rate limiting) incorrectly triggers auto-compaction instead of retry with backoff.
File: packages/ai/src/utils/overflow.ts, lines 91-94
// Cerebras and Mistral return 400/413/429 with no body - check for status code pattern// 429 can indicate token-based rate limiting which correlates with context overflowif (/^4(00|13|29)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) { return true;}The code treats 429 status code (no body) as context overflow. The comment's reasoning is flawed:
These are completely different concepts. 429 = "Too Many Requests" = rate limiting, NOT context overflow.
429 status code (no body) (rate limited)isContextOverflow() returns true (matches regex)_isRetryableError() in agent-session.ts:1879 returns false:
if (isContextOverflow(message, contextWindow)) return false;_checkCompaction() triggers auto-compaction because isContextOverflow() is trueChange in packages/ai/src/utils/overflow.ts:
// Before:if (/^4(00|13|29)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) {
// After:if (/^4(00|13)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) {Keep:
Remove:
The retry logic already handles 429 correctly. In agent-session.ts:1886-1888:
return /overloaded|rate.?limit|too many requests|429|500|502|503|504|.../i.test(err);Once isContextOverflow() stops returning true for 429, _isRetryableError() will correctly return true, and 429 errors will be retried with exponential backoff as expected.
packages/ai/src/utils/overflow.ts - Remove 429 from overflow regexpackages/ai/CHANGELOG.md - Document the fixdo it
Done. Changes made:
packages/ai/src/utils/overflow.ts:
/^4(00|13|29) to /^4(00|13) to exclude 429 from context overflow detectionpackages/ai/CHANGELOG.md:
[Unreleased]The fix ensures 429 errors are now correctly handled by the retry logic (exponential backoff) in agent-session.ts instead of triggering auto-compaction. The existing retry regex already matches 429:
/overloaded|rate.?limit|too many requests|429|500|502|503|504|.../commit and push, leave a comment explaining the fix. close issue in commit message
Done. Committed, pushed, and commented on the issue. The issue will be auto-closed by GitHub due to fixes #1038 in the commit message.
// Cerebras and Mistral return 400/413/429 with no body - check for status code pattern// 429 can indicate token-based rate limiting which correlates with context overflowif (/^4(00|13|29)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) { return true;}if (isContextOverflow(message, contextWindow)) return false;// Before:if (/^4(00|13|29)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) {
// After:if (/^4(00|13)\s*(status code)?\s*\(no body\)/i.test(message.errorMessage)) {return /overloaded|rate.?limit|too many requests|429|500|502|503|504|.../i.test(err);/overloaded|rate.?limit|too many requests|429|500|502|503|504|.../