isRetryableStatusCode determines if an HTTP status code is retryable. Retryable means we should retry the SAME model with exponential backoff. Retryable status codes: - 5xx (server errors): 500, 502, 503, 504 - 529 (Anthropic overloaded) - 408 (request timeout) Non-retryable status codes (skip to
(statusCode int)
| 330 | // - 429 (rate limit) - provider is explicitly telling us to back off |
| 331 | // - 4xx client errors (400, 401, 403, 404) - won't get better with retry |
| 332 | func isRetryableStatusCode(statusCode int) bool { |
| 333 | switch statusCode { |
| 334 | case 500, 502, 503, 504: // Server errors |
| 335 | return true |
| 336 | case 529: // Anthropic overloaded |
| 337 | return true |
| 338 | case 408: // Request timeout |
| 339 | return true |
| 340 | case 429: // Rate limit - NOT retryable, skip to next model |
| 341 | return false |
| 342 | default: |
| 343 | return false |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | // transientStatusCodePatterns contains error message substrings that indicate |
| 348 | // a transient failure even when the HTTP status code would otherwise classify |
no outgoing calls