fix(reasoning): extend max ceiling to OpenAI-family + cloud-hosted Claude lanes

Re-gate found 'max' still reached provider adapters that reject/mis-handle it on
lanes beyond openai-codex/native: direct openai + openai-api + azure-foundry
GPT-5 (APIs top out at xhigh), and Azure-Foundry/Bedrock-hosted LEGACY Claude
(the pre-adaptive classifier only matched native Anthropic provider names, so max
survived to the 8k manual-thinking budget). Extended the GPT-5/o-series ceiling
to all OpenAI-family lanes and the pre-adaptive-Claude ceiling to azure/bedrock/
vertex lanes (gated on 'claude' in the model id so non-Claude models on those
lanes are untouched). Regression tests for both lanes.
This commit is contained in:
nesquena-hermes 2026-07-11 04:06:36 +00:00
parent 381bcb4822
commit b779f0b777
2 changed files with 36 additions and 2 deletions

View file

@ -3246,7 +3246,9 @@ def _filter_reasoning_efforts_for_provider(
normalized = list(dict.fromkeys(normalized))
provider = _resolve_provider_alias(str(provider_id or "").strip().lower())
bare = _strip_provider_hint_for_reasoning(model_id).lower().rsplit("/", 1)[-1]
if provider == "openai-codex":
# OpenAI-family lanes (Codex, direct OpenAI, Azure Foundry) cap GPT-5 at xhigh
# and o-series at high — 'max' is a WebUI-only level none of them accept.
if provider in {"openai-codex", "openai", "openai-api", "azure-foundry", "azure-openai", "azure"}:
if bare.startswith(("o1", "o3", "o4")):
return [eff for eff in normalized if eff in {"low", "medium", "high"}]
if bare.startswith("gpt-5"):
@ -3258,7 +3260,14 @@ def _filter_reasoning_efforts_for_provider(
# Dropping 'max' here lets the existing downgrade ladder land on xhigh/high.
if provider in {"gemini", "google", "google-gemini", "google-vertex", "vertex"}:
return [eff for eff in normalized if eff != "max"]
if provider in {"anthropic", "claude", "anthropic-claude"} and _is_pre_adaptive_anthropic(bare):
# Legacy Claude is pre-adaptive whether served natively OR via Azure Foundry /
# Bedrock / Vertex — the ceiling follows the MODEL, not just the provider name.
_anthropic_lanes = {
"anthropic", "claude", "anthropic-claude",
"azure-foundry", "azure-openai", "azure", "bedrock", "aws-bedrock",
"vertex", "google-vertex",
}
if provider in _anthropic_lanes and "claude" in bare and _is_pre_adaptive_anthropic(bare):
return [eff for eff in normalized if eff != "max"]
return normalized

View file

@ -362,3 +362,28 @@ def test_max_effort_preserved_for_adaptive_anthropic_and_deepseek():
assert cfg.coerce_reasoning_effort_for_model(
"max", model_id="deepseek-reasoner", provider_id="deepseek"
) == "max"
def test_max_degrades_across_all_openai_family_lanes():
# 'max' is WebUI-only; direct OpenAI, openai-api, and Azure Foundry GPT-5 all
# cap at xhigh (o-series at high), not just openai-codex. (#4627 re-gate)
for prov in ("openai", "openai-api", "azure-foundry", "openai-codex"):
assert cfg.coerce_reasoning_effort_for_model(
"max", model_id="gpt-5.1", provider_id=prov
) == "xhigh", f"gpt-5 on {prov} must degrade max->xhigh"
assert cfg.coerce_reasoning_effort_for_model(
"max", model_id="o3", provider_id=prov
) == "high", f"o-series on {prov} must degrade max->high"
def test_max_degrades_for_azure_bedrock_hosted_legacy_claude():
# Legacy Claude via Azure Foundry / Bedrock is still pre-adaptive; the ceiling
# follows the model, not just the provider name. (#4627 re-gate)
for prov in ("azure-foundry", "bedrock"):
assert cfg.coerce_reasoning_effort_for_model(
"max", model_id="claude-sonnet-4-20250514", provider_id=prov
) == "xhigh", f"legacy Claude on {prov} must degrade max->xhigh"
# adaptive Claude via azure preserves max
assert cfg.coerce_reasoning_effort_for_model(
"max", model_id="claude-opus-4.6", provider_id="azure-foundry"
) == "max"