diff --git a/litellm/llms/azure/chat/gpt_5_transformation.py b/litellm/llms/azure/chat/gpt_5_transformation.py index 7e8625ad4cf..a4992128adc 100644 --- a/litellm/llms/azure/chat/gpt_5_transformation.py +++ b/litellm/llms/azure/chat/gpt_5_transformation.py @@ -15,6 +15,17 @@ class AzureOpenAIGPT5Config(AzureOpenAIConfig, OpenAIGPT5Config): GPT5_SERIES_ROUTE = "gpt5_series/" + @classmethod + def _supports_reasoning_effort_level(cls, model: str, level: str) -> bool: + """Strip the gpt5_series/ routing prefix and pass azure as provider.""" + from litellm.utils import _supports_factory + + return _supports_factory( + model=model.replace(cls.GPT5_SERIES_ROUTE, ""), + custom_llm_provider="azure", + key=f"supports_{level}_reasoning_effort", + ) + @classmethod def is_model_gpt_5_model(cls, model: str) -> bool: """Check if the Azure model string refers to a gpt-5 variant. @@ -43,10 +54,15 @@ class AzureOpenAIGPT5Config(AzureOpenAIConfig, OpenAIGPT5Config): if "tool_choice" not in params: params.append("tool_choice") - # Only gpt-5.2 has been verified to support logprobs on Azure + # Only gpt-5.2 has been verified to support logprobs on Azure. + # The OpenAI base class may include logprobs for gpt-5.1 (supported on openai.com), + # but we enforce the Azure-specific constraint here. if self.is_model_gpt_5_2_model(model): - azure_supported_params = ["logprobs", "top_logprobs"] - params.extend(azure_supported_params) + for p in ("logprobs", "top_logprobs"): + if p not in params: + params.append(p) + else: + params = [p for p in params if p not in ("logprobs", "top_logprobs")] return params diff --git a/tests/test_litellm/llms/openai/test_gpt5_transformation.py b/tests/test_litellm/llms/openai/test_gpt5_transformation.py index 1fc984510ef..89578e3e7c4 100644 --- a/tests/test_litellm/llms/openai/test_gpt5_transformation.py +++ b/tests/test_litellm/llms/openai/test_gpt5_transformation.py @@ -1,8 +1,8 @@ import pytest import litellm -from litellm.llms.openai.openai import OpenAIConfig from litellm.llms.openai.chat.gpt_5_transformation import OpenAIGPT5Config +from litellm.llms.openai.openai import OpenAIConfig @pytest.fixture() @@ -260,19 +260,21 @@ def test_gpt5_drops_reasoning_effort_xhigh_when_requested(config: OpenAIConfig): # GPT-5.1 temperature handling tests def test_gpt5_1_model_detection(gpt5_config: OpenAIGPT5Config): - """Test that GPT-5.1 models are correctly detected.""" - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.1") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.1-codex") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.1-codex-max") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.1-chat") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.2") - assert gpt5_config.is_model_gpt_5_1_model("gpt-5.2-2025-12-11") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-chat") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-chat-latest") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5.2-pro") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5-mini") - assert not gpt5_config.is_model_gpt_5_1_model("gpt-5-codex") + """Test that models supporting reasoning_effort='none' are correctly detected via model map.""" + # gpt-5.1 and gpt-5.2 chat variants support none + assert gpt5_config._supports_reasoning_effort_level("gpt-5.1", "none") + assert gpt5_config._supports_reasoning_effort_level("gpt-5.1-2025-11-13", "none") + assert gpt5_config._supports_reasoning_effort_level("gpt-5.1-chat-latest", "none") + assert gpt5_config._supports_reasoning_effort_level("gpt-5.2", "none") + assert gpt5_config._supports_reasoning_effort_level("gpt-5.2-2025-12-11", "none") + # codex/pro/chat variants do not support none + assert not gpt5_config._supports_reasoning_effort_level("gpt-5.1-codex", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5.1-codex-max", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5.2-chat-latest", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5.2-pro", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5-mini", "none") + assert not gpt5_config._supports_reasoning_effort_level("gpt-5-codex", "none") def test_gpt5_1_temperature_with_reasoning_effort_none(config: OpenAIConfig):