For pseudocode conventions, see the README.
ProviderError::classify (src/provider/traits.rs)
Purpose: Map an HTTP error response to the correct ProviderError variant.
FUNCTION ProviderError::classify(status: u16, message: String) -> ProviderError
IF is_context_overflow(status, message) THEN
RETURN ContextOverflow { message }
END IF
IF status == 429 THEN
RETURN RateLimited { retry_after_ms: None }
END IF
IF status == 401 OR status == 403 THEN
RETURN Auth(message)
END IF
RETURN Api(message)
END FUNCTION
FUNCTION is_context_overflow(status: u16, message: String) -> bool
// Some providers (Cerebras, Mistral) return 400/413 with empty body
IF (status == 400 OR status == 413) AND message.trim() is empty THEN
RETURN true
END IF
lower ← message.to_lowercase()
RETURN any of OVERFLOW_PHRASES is a substring of lower
// OVERFLOW_PHRASES includes:
// "prompt is too long" (Anthropic)
// "input is too long" (Bedrock)
// "exceeds the context window" (OpenAI)
// "exceeds the maximum" (Google)
// "maximum prompt length" (xAI)
// "reduce the length of the messages" (Groq)
// "maximum context length" (OpenRouter)
// "context length exceeded" (generic)
// "too many tokens" (generic)
// ... 15 phrases total
END FUNCTION