Merge origin/main (63279301bc): reasoning-mandatory 400 recovery folded into turn_recovery/error_classifier/models_reasoning_caps
This commit is contained in:
@@ -42,7 +42,10 @@ class FailoverReason(enum.Enum):
|
||||
content_policy_blocked = "content_policy_blocked" # Provider safety filter rejected this prompt — don't retry unchanged
|
||||
format_error = "format_error" # 400 bad request — abort or strip + retry
|
||||
invalid_encrypted_content = "invalid_encrypted_content" # Responses replay blob rejected — strip replay state and retry
|
||||
multimodal_tool_content_unsupported = "multimodal_tool_content_unsupported" # Provider rejected list content in tool messages — downgrade to text
|
||||
multimodal_tool_content_unsupported = "multimodal_tool_content_unsupported" # Provider rejected list-type content in tool messages (e.g. Xiaomi MiMo) — downgrade to text and retry
|
||||
reasoning_mandatory = "reasoning_mandatory" # Route rejects reasoning: {enabled: false} — send the disable no more this session and retry
|
||||
|
||||
# Provider-specific
|
||||
thinking_signature = "thinking_signature" # Anthropic thinking block sig invalid
|
||||
long_context_tier = "long_context_tier" # Anthropic "extra usage" tier gate
|
||||
oauth_long_context_beta_forbidden = "oauth_long_context_beta_forbidden" # Anthropic OAuth rejects 1M beta — disable beta and retry
|
||||
@@ -340,6 +343,9 @@ _V_PAYLOAD_TOO_LARGE = _v(_R.payload_too_large, should_compress=True)
|
||||
_V_OVERLOADED, _V_SERVER_ERROR, _V_TIMEOUT, _V_UNKNOWN = map(_v, (_R.overloaded, _R.server_error, _R.timeout, _R.unknown))
|
||||
_V_IMAGE_TOO_LARGE, _V_IMAGE_CORRUPT = _v(_R.image_too_large), _v(_R.image_corrupt)
|
||||
_V_MULTIMODAL, _V_INVALID_ENCRYPTED = _v(_R.multimodal_tool_content_unsupported), _v(_R.invalid_encrypted_content)
|
||||
_V_REASONING_MANDATORY = _v(_R.reasoning_mandatory, should_compress=False, should_fallback=False)
|
||||
# A reasoning-mandatory route answering ``reasoning: {enabled: false}`` (Nous Portal + OpenRouter wording).
|
||||
_REASONING_MANDATORY_PATTERN = "reasoning is mandatory"
|
||||
|
||||
|
||||
def _billing_hints(error_msg: str) -> Verdict:
|
||||
@@ -662,6 +668,11 @@ def _classify_400(c: _Ctx) -> Verdict:
|
||||
"encrypted content for item" in msg and "could not be verified" in msg
|
||||
) or "could not decrypt the provided encrypted_content" in msg:
|
||||
return _V_INVALID_ENCRYPTED
|
||||
# Reasoning-mandatory route rejecting a disable (GLM-5.3 on Nous Portal / OpenRouter). Deterministic
|
||||
# for the request shape, but the only bad field is ``reasoning: {enabled: false}`` — the loop drops
|
||||
# the disable and retries once. Must precede request-validation, which would abort as format_error.
|
||||
if _REASONING_MANDATORY_PATTERN in msg:
|
||||
return _V_REASONING_MANDATORY
|
||||
# 400 blaming a field this route never sent (Codex OAuth injects then rejects
|
||||
# prompt_cache_retention ~20% of the time): transient, retry identical request.
|
||||
if _is_server_injected_param_rejection(msg, c.provider_slug):
|
||||
|
||||
Reference in New Issue
Block a user