Problem
run_agent.py classifies API errors via fragile string matching against lowercased error messages (lines ~8105-8133). Phrases like 'invalid model', 'unauthorized', 'not found' etc are scattered inline. This is brittle — new providers can use different wording that slips through, causing retryable errors to be treated as permanent or vice versa.
Proposed Solution
Extract a ProviderError dataclass with a typed reason enum:
AUTH, AUTH_PERMANENT, RATE_LIMIT, OVERLOADED, BILLING
MODEL_NOT_FOUND, CONTEXT_OVERFLOW, PAYLOAD_TOO_LARGE
FORMAT_ERROR, TIMEOUT, SERVER_ERROR, STREAM_DROP, UNKNOWN
Add a classify_provider_error() function that maps status codes + error bodies to typed reasons. Replace inline string matching in the retry loop with typed dispatch.
Benefits
- New providers can be added by extending the classifier, not hunting through the retry loop
- Testable classification logic (each reason can be unit tested)
- Foundation for higher-level features (cooldown tracking, diagnostics)
Problem
run_agent.pyclassifies API errors via fragile string matching against lowercased error messages (lines ~8105-8133). Phrases like'invalid model','unauthorized','not found'etc are scattered inline. This is brittle — new providers can use different wording that slips through, causing retryable errors to be treated as permanent or vice versa.Proposed Solution
Extract a
ProviderErrordataclass with a typed reason enum:AUTH,AUTH_PERMANENT,RATE_LIMIT,OVERLOADED,BILLINGMODEL_NOT_FOUND,CONTEXT_OVERFLOW,PAYLOAD_TOO_LARGEFORMAT_ERROR,TIMEOUT,SERVER_ERROR,STREAM_DROP,UNKNOWNAdd a
classify_provider_error()function that maps status codes + error bodies to typed reasons. Replace inline string matching in the retry loop with typed dispatch.Benefits