diff --git a/litellm/llms/openai/responses/transformation.py b/litellm/llms/openai/responses/transformation.py index 314a1d22508..2d430fbc5ce 100644 --- a/litellm/llms/openai/responses/transformation.py +++ b/litellm/llms/openai/responses/transformation.py @@ -373,6 +373,20 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): def _model_map_lookup_name(model: str) -> str: return model + @staticmethod + def _without_unsupported_o_series_temperature( + params: Mapping[str, object], model: str, drop_params: bool + ) -> Mapping[str, object]: + temperature: Final = params.get("temperature") + if ( + litellm.openaiOSeriesConfig.is_model_o_series_model(model=model) + and temperature is not None + and temperature != 1 + and (drop_params or litellm.drop_params) + ): + return {key: value for key, value in params.items() if key != "temperature"} + return params + @staticmethod def _supports_reasoning_effort_none(model: str) -> bool: """Return True if the model supports reasoning.effort='none'.""" @@ -589,8 +603,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): ), status_code=400, ) - - return params + return self._without_unsupported_o_series_temperature(params, lookup_name, drop_params) def transform_responses_api_request( self, diff --git a/tests/unit/llms/openai/responses/test_openai_responses_transformation.py b/tests/unit/llms/openai/responses/test_openai_responses_transformation.py index cd300d74b59..44d791ba7e8 100644 --- a/tests/unit/llms/openai/responses/test_openai_responses_transformation.py +++ b/tests/unit/llms/openai/responses/test_openai_responses_transformation.py @@ -2393,6 +2393,33 @@ class TestPromptCacheOptionsOnResponsesPath: } +@pytest.mark.parametrize( + ("model", "temperature", "drop_params", "global_drop_params", "expected"), + ( + ("o3-mini", 0.5, True, False, {"max_output_tokens": 128}), + ("o3-mini", 1, True, False, {"temperature": 1, "max_output_tokens": 128}), + ("o3-mini", 0.5, False, True, {"max_output_tokens": 128}), + ("o3-mini", 0.5, False, False, {"temperature": 0.5, "max_output_tokens": 128}), + ("gpt-4o", 0.5, True, False, {"temperature": 0.5, "max_output_tokens": 128}), + ), +) +def test_o_series_responses_drops_only_unsupported_temperature_when_enabled( + model: str, + temperature: float, + drop_params: bool, + global_drop_params: bool, + expected: Mapping[str, object], + monkeypatch: pytest.MonkeyPatch, +) -> None: + monkeypatch.setattr(litellm, "drop_params", global_drop_params) + mapped: Final = OpenAIResponsesAPIConfig().map_openai_params( + response_api_optional_params={"temperature": temperature, "max_output_tokens": 128}, + model=model, + drop_params=drop_params, + ) + assert mapped == expected + + class TestResponsesSurfaceSharesTheEffortRule: """The Responses API reaches the same gpt-5 models over a different wire, and the default /v1/messages bridge for openai models routes through it. It carried its own copy of the