fix(gpt-5): enforce supports_none_reasoning_effort for reasoning_effort=none

Adds a missing capability gate so that reasoning_effort="none" is dropped or refused when the model map marks supports_none_reasoning_effort=false (e.g. gpt-5, gpt-5-mini) instead of being forwarded to the provider and surfacing as a 400.
This commit is contained in:
Syed Ali Abbas Rahil 2026-09-11 12:03:26 +09:00
parent ff4b558243
commit 7fc9f1c34d
2 changed files with 74 additions and 0 deletions

View file

@ -300,6 +300,19 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
message=(f"reasoning_effort={effective_effort} is not supported for this model."),
status_code=400,
)
elif effective_effort == "none":
# "none" is a declared capability: if the model map says the model does not
# support it, drop or refuse rather than forwarding it to the provider.
# Example: gpt-5 and gpt-5-mini are marked supports_none_reasoning_effort=false.
if not self._supports_reasoning_effort_level(model, effective_effort):
if litellm.drop_params or drop_params:
non_default_params.pop("reasoning_effort", None)
optional_params.pop("reasoning_effort", None)
else:
raise litellm.utils.UnsupportedParamsError(
message=(f"reasoning_effort={effective_effort} is not supported for this model."),
status_code=400,
)
################################################################
# max_tokens is not supported for gpt-5 models on OpenAI API

View file

@ -0,0 +1,61 @@
import pytest
import litellm
from litellm.litellm_core_utils.get_model_cost_map import get_model_cost_map
from litellm.llms.openai.openai import OpenAIConfig
@pytest.fixture()
def config() -> OpenAIConfig:
return OpenAIConfig()
@pytest.fixture(autouse=True)
def use_local_model_cost_map(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
monkeypatch.setattr(litellm, "model_cost", get_model_cost_map(url=litellm.model_cost_map_url))
litellm.add_known_models(model_cost_map=litellm.model_cost)
def test_gpt5_rejects_reasoning_effort_none_for_unsupported_models(config: OpenAIConfig):
"""Models marked supports_none_reasoning_effort=false must not forward reasoning_effort=none."""
for model in ("gpt-5", "gpt-5-mini"):
with pytest.raises(litellm.utils.UnsupportedParamsError):
config.map_openai_params(
non_default_params={"reasoning_effort": "none"},
optional_params={},
model=model,
drop_params=False,
)
# Dict form {"effort": "none"} should be gated the same way.
with pytest.raises(litellm.utils.UnsupportedParamsError):
config.map_openai_params(
non_default_params={"reasoning_effort": {"effort": "none", "summary": "detailed"}},
optional_params={},
model=model,
drop_params=False,
)
def test_gpt5_drops_reasoning_effort_none_when_requested(config: OpenAIConfig):
"""drop_params=True should strip unsupported reasoning_effort=none instead of raising."""
for model in ("gpt-5", "gpt-5-mini"):
params = config.map_openai_params(
non_default_params={"reasoning_effort": "none"},
optional_params={},
model=model,
drop_params=True,
)
assert "reasoning_effort" not in params
def test_gpt5_1_passes_through_reasoning_effort_none(config: OpenAIConfig):
"""Models marked supports_none_reasoning_effort=true still forward reasoning_effort=none."""
params = config.map_openai_params(
non_default_params={"reasoning_effort": "none"},
optional_params={},
model="gpt-5.1",
drop_params=False,
)
assert params["reasoning_effort"] == "none"