Repository navigation
fix(failover): skip same-model retries for Chinese quota exhaustion - #172173
Conversation
A provider that reports an exhausted usage window in Chinese (MiniMax Token Plan 2056: "已达到 Token Plan 用量上限:请升级 Token Plan 套餐或购买积分补充用量。", no Retry-After header) was classified as an ordinary transient rate limit, so the run burned the same-model retry spiral on a provider that cannot recover until the window resets. The English periodic wording already classified correctly. Extend the periodic-usage predicate with the Chinese usage/quota cap phrasing, keeping length/context caps and transient rate-limit messages out of that path.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs real behavior proof before merge. What this changesThis PR recognizes Chinese quota-exhaustion messages and skips futile same-model retries. Example: MiniMax returns HTTP 429 with “已达到 Token Plan 用量上限” and error 2056, without Retry-After.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 1 item remains Keep this PR open: it fixes a concrete current-main quota-classification gap, resolves the earlier retry-owner finding, and introduces no identified correctness defect. Priority: P2 Before merge
FindingsNone. Tests
Agent review detailsHow this fits togetherProvider errors enter shared classification and retry evidence; the embedded recovery controller consumes those facts to choose retries or eligible fallback, and reply formatting consumes the same message matcher. flowchart TD
A[Provider error] --> B[Canonical message matcher]
B --> C[Failover classification]
B --> D[Retry evidence]
C --> E[Attempt recovery]
D --> E
E --> F[Retry or eligible fallback]
B --> G[Terminal failure reply]
Technical reviewBest possible solution: Land the focused canonical-matcher repair after verifying the reported response through production recovery. Do we have a high-confidence way to reproduce the issue? Current-main source shows the reported Chinese 429 missing long-window evidence and entering the retry budget, consistent with the linked reporter's logs; no target code was executed during this review. Is this the best way to solve the issue? Reusing the existing periodic matcher fixes the owning retry decision without adding competing classification logic, configuration, or storage. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 02e70aba4762. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
Likely related people:
PR surfaceSource +13, Tests +37, Docs +2. Total +52 across 7 files. Added test files: 0. View PR surface stats
Review metrics
Root-cause clusterRelationship: Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. LabelsLabel changes: No label changes. Label justifications:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReviewed October 15, 2026, 2:45 AM ET / 06:45 UTC (Revision 3). |
Review finding (P2): classifying the MiniMax Token Plan 2056 message as a periodic usage limit did not stop the same-model retry spiral, because the retry-window owner (retry-evidence.ts) kept its English-only long-window evidence and the controller therefore still entered the retry budget. hasLongWindowRateLimitEvidence now also matches the Chinese usage/quota cap phrasing; CJK text has no word boundaries, so it checks separately from the ASCII pattern, the same way the short-window owner already handles its Chinese phrases.
|
@clawsweeper re-review — the P2 finding is addressed at the owner it named: hasLongWindowRateLimitEvidence in retry-evidence.ts now matches the Chinese usage-cap phrasing (checked separately from the ASCII pattern because CJK has no word boundaries), and the new regression drives the recovery controller with the exact reported 429 body — red before it returned { action: 'retry' }, green after with zero same-model retries. |
|
🦞👀 Re-review progress:
|
Recognize the reported MiniMax Token Plan 2056 wording and exhausted Chinese quotas at the canonical message-pattern owner. Reuse that predicate for retry decisions and retain transient-throttle negative controls at the recovery boundary. Fixes openclaw#172165. Original fix by @skyzhao1223; maintainer cleanup removes the duplicate matcher and replaces helper-only assertions with consumer coverage. Co-authored-by: skyzhao1223 <[email protected]>
Replace incorrect verbatim reply expectations with the reported MiniMax wording in the classification corpus, including its representative ID. Existing reply sanitization remains unchanged; the fix concerns retry and classification behavior.
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Merged via squash.
|
…penclaw#172173) * fix(failover): treat Chinese usage-cap messages as periodic limits A provider that reports an exhausted usage window in Chinese (MiniMax Token Plan 2056: "已达到 Token Plan 用量上限:请升级 Token Plan 套餐或购买积分补充用量。", no Retry-After header) was classified as an ordinary transient rate limit, so the run burned the same-model retry spiral on a provider that cannot recover until the window resets. The English periodic wording already classified correctly. Extend the periodic-usage predicate with the Chinese usage/quota cap phrasing, keeping length/context caps and transient rate-limit messages out of that path. * fix(failover): recognize the Chinese usage cap in the retry window Review finding (P2): classifying the MiniMax Token Plan 2056 message as a periodic usage limit did not stop the same-model retry spiral, because the retry-window owner (retry-evidence.ts) kept its English-only long-window evidence and the controller therefore still entered the retry budget. hasLongWindowRateLimitEvidence now also matches the Chinese usage/quota cap phrasing; CJK text has no word boundaries, so it checks separately from the ASCII pattern, the same way the short-window owner already handles its Chinese phrases. * fix(failover): share Chinese quota exhaustion evidence Recognize the reported MiniMax Token Plan 2056 wording and exhausted Chinese quotas at the canonical message-pattern owner. Reuse that predicate for retry decisions and retain transient-throttle negative controls at the recovery boundary. Fixes openclaw#172165. Original fix by @skyzhao1223; maintainer cleanup removes the duplicate matcher and replaces helper-only assertions with consumer coverage. Co-authored-by: skyzhao1223 <[email protected]> * test(failover): cover Chinese quota classification at its consumer Replace incorrect verbatim reply expectations with the reported MiniMax wording in the classification corpus, including its representative ID. Existing reply sanitization remains unchanged; the fix concerns retry and classification behavior. --------- Co-authored-by: skyzhao1223 <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
Fixes #172165
What Problem This Solves
MiniMax Token Plan's Chinese quota-exhaustion response (
已达到 Token Plan 用量上限, error 2056) withoutRetry-Afterenters ten same-model attempts before eligible fallback, delaying every turn by about 2.5 minutes as reported in the issue.User Impact
The reported MiniMax message and Chinese exhausted-quota wording now bypass same-model retries. Temporary
请求过于频繁throttles remain retryable, and unrelated context-length caps do not become exhausted usage windows. No configuration or migration is needed.Why This Change Was Made
The canonical periodic message matcher owns the exact MiniMax wording and existing
额度已用尽/配额已用尽phrases. Retry evidence consumes that predicate instead of maintaining a second Chinese regex. This keeps classification and the retry controller aligned without broad matching of arbitrary上限text.Original fix by @skyzhao1223; maintainer cleanup removes the duplicate matcher and helper-only test file, covers the issue's exhausted-quota wording, and adds consumer-level regression and negative cases.
Evidence
339bc009284962661e3bcf3fa31ae280e677300chas English-only long-window evidence; the retry controller checks it before spending its rate-limit budget. Historical owner changes preserve the distinction between general classification and same-request retryability.9a3644f978655d51bb732056f6c03bc335bdb052: 48 successful jobs, 29 skipped, zero failures, includingopenclaw/ci-gate, routed Node tests, production/test typechecks, lint, docs, and boundary checks. All applicable PR checks passed; no reruns or inherited-failure exception were needed.recovers Chinese rate limits without retrying exhausted quotas: %schecks the exact MiniMax 2056 body without Retry-After, exhausted quota phrases, and two temporary-throttle controls. Exhaustion must produceproceed, zero sleeps, and zero retries; temporary throttles must produceretry, one sleep call, and one retry.billing-minimax-chinese-usage-limitsupplies bare MiniMax wording so HTTP status/type evidence cannot hide a missing matcher; its ID is included inrepresentativeCorpusIds.keeps transient throttles and context caps out of long windows: %schecks short/unknown window results. These replace the standalone matcher tests.ui/**/*.tsxoverride, retaining all core rules.git diff --checkpasses.LOC against merged main: production +8/-3 (net +5), tests +45/-0, docs +2/-0. The five production lines wire the canonical predicate into retry evidence; further deletion would be unrelated cleanup. Compared with the contributor head, the duplicate regex and helper-only test file are removed. Main
2529bba0484e51a4e961eed87700351cd238ba8fwas merged immediately before push without rebase or conflict. The subsequent main merge did not change the reviewed owner files or patch. No detached/background effects were added; stale-fact revalidation is not applicable.