mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(responses): reject unsupported reasoning effort
This commit is contained in:
parent
5e4b3838aa
commit
e0027bdc53
2 changed files with 67 additions and 5 deletions
|
|
@ -121,9 +121,8 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
|
|||
) -> dict:
|
||||
"""No mapping applied since inputs are in OpenAI spec already.
|
||||
|
||||
GPT-5 models have restrictions on temperature (only temperature=1
|
||||
is accepted unless reasoning_effort='none' on models that support it).
|
||||
Apply the same validation used by the chat completions path.
|
||||
GPT-5 models have restrictions on temperature and reasoning effort.
|
||||
Apply the same capability checks used by the chat completions path.
|
||||
"""
|
||||
params: Final = dict(response_api_optional_params)
|
||||
|
||||
|
|
@ -131,10 +130,33 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
|
|||
params["max_output_tokens"] = self._enforce_min_max_output_tokens(params.get("max_output_tokens"))
|
||||
|
||||
if self._is_gpt_5_model(model=model):
|
||||
reasoning: Final = params.get("reasoning") or {}
|
||||
effort: Final = reasoning.get("effort") if isinstance(reasoning, dict) else None
|
||||
if isinstance(effort, str):
|
||||
from litellm.llms.openai.chat.gpt_5_transformation import OpenAIGPT5Config
|
||||
|
||||
unsupported_effort: Final = (
|
||||
effort == "xhigh" and not OpenAIGPT5Config._supports_reasoning_effort_level(model, effort)
|
||||
) or (
|
||||
effort in ("minimal", "low")
|
||||
and OpenAIGPT5Config._is_reasoning_effort_level_explicitly_disabled(model, effort)
|
||||
)
|
||||
if unsupported_effort:
|
||||
if drop_params or litellm.drop_params:
|
||||
updated_reasoning: Final = dict(reasoning)
|
||||
updated_reasoning.pop("effort", None)
|
||||
if updated_reasoning:
|
||||
params["reasoning"] = updated_reasoning
|
||||
else:
|
||||
params.pop("reasoning", None)
|
||||
else:
|
||||
raise litellm.UnsupportedParamsError(
|
||||
message=f"reasoning.effort={effort} is not supported for this model.",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
temperature: Final = params.get("temperature")
|
||||
if temperature is not None and temperature != 1:
|
||||
reasoning: Final = params.get("reasoning") or {}
|
||||
effort: Final = reasoning.get("effort") if isinstance(reasoning, dict) else None
|
||||
supports_none: Final = self._supports_reasoning_effort_none(model=model)
|
||||
if supports_none and self._effort_resolves_to_none(model, effort):
|
||||
pass # flexible temperature allowed
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import pytest
|
||||
|
||||
import litellm
|
||||
from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig
|
||||
|
||||
|
||||
@pytest.mark.parametrize("effort", ["minimal", "low"])
|
||||
def test_rejects_explicitly_unsupported_lower_reasoning_effort(effort: str) -> None:
|
||||
config = OpenAIResponsesAPIConfig()
|
||||
|
||||
with pytest.raises(litellm.UnsupportedParamsError, match=f"reasoning.effort={effort}"):
|
||||
config.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": effort}},
|
||||
model="gpt-5.5-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
|
||||
def test_keeps_supported_reasoning_effort() -> None:
|
||||
config = OpenAIResponsesAPIConfig()
|
||||
|
||||
result = config.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "medium"}},
|
||||
model="gpt-5.5-pro",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
assert result["reasoning"] == {"effort": "medium"}
|
||||
|
||||
|
||||
def test_drop_params_removes_only_unsupported_effort() -> None:
|
||||
config = OpenAIResponsesAPIConfig()
|
||||
|
||||
result = config.map_openai_params(
|
||||
response_api_optional_params={"reasoning": {"effort": "minimal", "summary": "detailed"}},
|
||||
model="gpt-5.5-pro",
|
||||
drop_params=True,
|
||||
)
|
||||
|
||||
assert result["reasoning"] == {"summary": "detailed"}
|
||||
Loading…
Add table
Reference in a new issue