fix: classify provider code-only failover errors#95729
Conversation
a61efbd to
e9974d1
Compare
4ad2b4a to
de94cb1
Compare
|
Codex review: needs real behavior proof before merge. Reviewed July 10, 2026, 1:50 PM ET / 17:50 UTC. Summary PR surface: Source +53, Tests +186. Total +239 across 9 files. Reproducibility: yes. Maintainer Crabbox validation exercised a message-less Anthropic structured error through Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Rebase onto current Do we have a high-confidence way to reproduce the issue? Yes. Maintainer Crabbox validation exercised a message-less Anthropic structured error through Is this the best way to solve the issue? Yes. Provider-native meanings belong in the owning provider hooks, while core should retain only portable codes and generic structured-signal handling; the final implementation follows that boundary without duplicating policy. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 61893247ec7d. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +53, Tests +186. Total +239 across 9 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (4 earlier review cycles)
|
|
@clawsweeper re-review Added real behavior proof:
Real behavior proof CI check passed. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review Fixed P1: moved provider-native code mappings (OpenAI/Google/Anthropic) from core classifyFailoverReasonFromCode into each provider's classifyFailoverReason hook. Core now keeps only generic classification. 196 tests passed. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
dba3773 to
36f61d1
Compare
Co-authored-by: Altay <[email protected]>
36f61d1 to
df4e823
Compare
Maintainer live validationValidated PR head Deterministic structured-error proof
Genuine upstream Anthropic exhaustion proof
ResultThe exact provider-structured classification path and the model-fallback path pass end to end. Separately, a real Anthropic rate-limit event is correctly surfaced and classified by the runtime. The upstream run did not independently demonstrate cross-model fallback because the primary recovered during its bounded same-model retry sequence. |
|
Maintainer landing proof for
No remaining proof gap found. Strong related-item search found no duplicate for these specific provider-native code mappings. |
|
Merged via squash.
|
* fix(agents): classify provider-native failover errors Co-authored-by: Altay <[email protected]> * fix(agents): scope provider failover codes * docs(changelog): credit provider failover fix * style(anthropic): format failover classifier * docs(changelog): defer release-owned entry --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Altay <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Structured assistant errors that only carry an error
code(no HTTP status, no body message) fell through tonullin the failover reason classifier and were reported asempty_response, so model failover/cooldown never ran. Provider-native codes like OpenAISERVER_ERROR/INSUFFICIENT_QUOTA, GoogleUNAVAILABLE/DEADLINE_EXCEEDED/INTERNAL, and AnthropicRATE_LIMIT_ERROR/API_ERRORwere not recognized.Why This Change Was Made
Provider-native code→reason mappings now live in each provider plugin's
classifyFailoverReasonhook (OpenAI, the Google family coveringgoogle/google-vertex/google-antigravity, and Anthropic), keeping coreclassifyFailoverReasonFromCodegeneric (cross-provider codes only).classifyFailoverSignalalready dispatches code-only structured signals to the matching provider hook, so the previous corePROVIDER_CODE_REASON_MAPwas redundant duplication of plugin-owned policy that could drift from each provider as it evolves (AGENTS.mdprovider-boundary policy). The generic guard — message-less structured-code signals must not be reported asempty_response— stays in core where it belongs.User Impact
Code-only provider errors correctly trigger model failover. When the primary provider returns a structured code with no message (e.g. OpenAI
SERVER_ERROR, GoogleDEADLINE_EXCEEDED, AnthropicAPI_ERROR), the classifier maps it to the right failover reason and attempts a fallback model instead of treating the turn as an empty response.Evidence
Boundary fix: removed the 13-entry
PROVIDER_CODE_REASON_MAPfrom coresrc/agents/embedded-agent-helpers/errors.ts(now generic); addedclassifyFailoverReasonhooks toextensions/openai/openai-provider.ts,extensions/google/provider-hooks.ts(sharedGOOGLE_GEMINI_PROVIDER_HOOKS), andextensions/anthropic/register.runtime.ts. Provider-specific assertions moved to each plugin's test; the core test keeps theempty_responseregression.Typecheck + lint (clean):
Core + sibling failover tests:
Provider hook tests (each plugin owns its codes):
SERVER_ERROR→server_error,INSUFFICIENT_QUOTA→billing,API_ERROR→undefined (not OpenAI's)UNAVAILABLE→overloaded,DEADLINE_EXCEEDED→timeout,INTERNAL→server_errorRATE_LIMIT_ERROR→rate_limit,API_ERROR→timeout,INSUFFICIENT_QUOTA→undefinedRebased on latest
origin/mainbefore push.