fix(gpt-5): respect model default reasoning effort when deciding temperature support

This commit is contained in:
mateo-berri 2026-07-21 18:10:51 -07:00
parent e967bc8c4f
commit 53cba0c185
10 changed files with 339 additions and 33 deletions

View file

@ -19,19 +19,12 @@ class AzureOpenAIGPT5Config(AzureOpenAIConfig, OpenAIGPT5Config):
GPT5_SERIES_ROUTE = "gpt5_series/"
@classmethod
def _supports_reasoning_effort_level(cls, model: str, level: str) -> bool:
"""Override to handle gpt5_series/ prefix used for Azure routing.
The parent class calls ``_supports_factory(model, custom_llm_provider=None)``
which fails to resolve ``gpt5_series/gpt-5.1`` to the correct Azure model
entry. Strip the prefix and prepend ``azure/`` so the lookup finds
``azure/gpt-5.1`` in model_prices_and_context_window.json.
"""
def _model_map_lookup_name(cls, model: str) -> str:
if model.startswith(cls.GPT5_SERIES_ROUTE):
model = "azure/" + model[len(cls.GPT5_SERIES_ROUTE) :]
elif not model.startswith("azure/"):
model = "azure/" + model
return super()._supports_reasoning_effort_level(model, level)
return "azure/" + model[len(cls.GPT5_SERIES_ROUTE) :]
if model.startswith("azure/"):
return model
return "azure/" + model
@classmethod
def is_model_gpt_5_model(cls, model: str) -> bool:

View file

@ -4,6 +4,7 @@ from typing import Optional, Union
import litellm
from litellm.utils import (
_default_reasoning_effort_factory,
_is_explicitly_disabled_factory,
_supports_factory,
)
@ -114,6 +115,10 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
except (ValueError, IndexError):
return False
@classmethod
def _model_map_lookup_name(cls, model: str) -> str:
return model
@classmethod
def _supports_reasoning_effort_level(cls, model: str, level: str) -> bool:
"""Check if the model supports a specific reasoning_effort level.
@ -123,11 +128,44 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
Returns False for unknown models (safe fallback).
"""
return _supports_factory(
model=model,
model=cls._model_map_lookup_name(model),
custom_llm_provider=None,
key=f"supports_{level}_reasoning_effort",
)
@classmethod
def _get_default_reasoning_effort(cls, model: str) -> "str | None":
return _default_reasoning_effort_factory(
model=cls._model_map_lookup_name(model),
custom_llm_provider=None,
)
@classmethod
def _effort_resolves_to_none(cls, model: str, effective_effort: "str | None", supports_none: bool) -> bool:
if effective_effort is not None:
return effective_effort == "none"
default_effort = cls._get_default_reasoning_effort(model)
if default_effort is not None:
return default_effort == "none"
return supports_none
@classmethod
def _unsupported_temperature_message(
cls, model: str, temperature_value: float, effective_effort: "str | None"
) -> str:
resolved_effort = effective_effort if effective_effort is not None else cls._get_default_reasoning_effort(model)
effort_clause = (
f"reasoning_effort resolves to '{resolved_effort}'"
if resolved_effort is not None
else "reasoning is active"
)
return (
f"{model} doesn't support temperature={temperature_value} because {effort_clause}. "
"Only temperature=1 is supported unless reasoning_effort resolves to 'none' "
"(explicitly set, or as the model's default). "
"To drop unsupported params set `litellm.drop_params = True`"
)
@classmethod
def _is_reasoning_effort_level_explicitly_disabled(cls, model: str, level: str) -> bool:
"""Return True only when the model map explicitly sets the capability to False.
@ -260,7 +298,7 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
if supports_none:
sampling_params = ["logprobs", "top_logprobs", "top_p"]
has_sampling = any(p in non_default_params for p in sampling_params)
if has_sampling and effective_effort not in (None, "none"):
if has_sampling and not self._effort_resolves_to_none(model, effective_effort, supports_none):
if litellm.drop_params or drop_params:
for p in sampling_params:
non_default_params.pop(p, None)
@ -268,17 +306,16 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
raise litellm.utils.UnsupportedParamsError(
message=(
"gpt-5.1/5.2/5.4 only support logprobs, top_p, top_logprobs when "
"reasoning_effort='none'. Current reasoning_effort='{}'. "
"reasoning_effort resolves to 'none'. Current reasoning_effort='{}'. "
"To drop unsupported params set `litellm.drop_params = True`"
).format(effective_effort),
).format(effective_effort or self._get_default_reasoning_effort(model)),
status_code=400,
)
if "temperature" in non_default_params:
temperature_value: Optional[float] = non_default_params.pop("temperature")
if temperature_value is not None:
# models supporting reasoning_effort="none" also support flexible temperature
if supports_none and (effective_effort == "none" or effective_effort is None):
if supports_none and self._effort_resolves_to_none(model, effective_effort, supports_none):
optional_params["temperature"] = temperature_value
elif temperature_value == 1:
optional_params["temperature"] = temperature_value
@ -286,12 +323,7 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
pass
else:
raise litellm.utils.UnsupportedParamsError(
message=(
"gpt-5 models (including gpt-5-codex) don't support temperature={}. "
"Only temperature=1 is supported. "
"For gpt-5.1, temperature is supported when reasoning_effort='none' (or not specified, as it defaults to 'none'). "
"To drop unsupported params set `litellm.drop_params = True`"
).format(temperature_value),
message=self._unsupported_temperature_message(model, temperature_value, effective_effort),
status_code=400,
)
return super()._map_openai_params(

View file

@ -113,22 +113,18 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig):
if self._is_gpt_5_model(model=model):
temperature = params.get("temperature")
if temperature is not None and temperature != 1:
from litellm.llms.openai.chat.gpt_5_transformation import OpenAIGPT5Config
reasoning = params.get("reasoning") or {}
effort = reasoning.get("effort") if isinstance(reasoning, dict) else None
supports_none = self._supports_reasoning_effort_none(model=model)
if supports_none and (effort == "none" or effort is None):
if supports_none and OpenAIGPT5Config._effort_resolves_to_none(model, effort, supports_none):
pass # flexible temperature allowed
elif drop_params or litellm.drop_params:
params.pop("temperature", None)
else:
raise litellm.UnsupportedParamsError(
message=(
"gpt-5 models don't support temperature={}. "
"Only temperature=1 is supported. "
"For models like gpt-5.1/5.4, temperature is supported "
"when reasoning.effort='none' (or not specified). "
"To drop unsupported params set `litellm.drop_params = True`"
).format(temperature),
message=OpenAIGPT5Config._unsupported_temperature_message(model, temperature, effort),
status_code=400,
)

View file

@ -3575,6 +3575,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.38e-06,
"litellm_provider": "azure",
@ -3877,6 +3878,7 @@
"supports_vision": true
},
"azure/global/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"input_cost_per_token": 1.25e-06,
"litellm_provider": "azure",
@ -4913,6 +4915,7 @@
"supports_audio_input": true
},
"azure/gpt-5.1-2025-11-13": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -5368,6 +5371,7 @@
"supports_vision": true
},
"azure/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"input_cost_per_token": 1.25e-06,
"litellm_provider": "azure",
@ -5526,6 +5530,7 @@
"supports_vision": true
},
"azure/gpt-5.2": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"input_cost_per_token": 1.75e-06,
"litellm_provider": "azure",
@ -5559,6 +5564,7 @@
"supports_vision": true
},
"azure/gpt-5.2-2025-12-11": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -5819,6 +5825,7 @@
"supports_web_search": true
},
"azure/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_priority": 5e-07,
@ -5860,6 +5867,7 @@
"supports_vision": true
},
"azure/us/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -5895,6 +5903,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -5930,6 +5939,7 @@
"supports_vision": true
},
"azure/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_priority": 5e-07,
@ -5971,6 +5981,7 @@
"supports_vision": true
},
"azure/us/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -6006,6 +6017,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -6627,6 +6639,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_priority": 1e-06,
@ -6672,6 +6685,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/us/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6714,6 +6728,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/eu/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6756,6 +6771,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_priority": 1e-06,
@ -6798,6 +6814,7 @@
"supports_web_search": true
},
"azure/us/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6837,6 +6854,7 @@
"supports_web_search": true
},
"azure/eu/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6876,6 +6894,7 @@
"supports_web_search": true
},
"azure/gpt-5.5-pro": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -6915,6 +6934,7 @@
"supports_low_reasoning_effort": false
},
"azure/gpt-5.5-pro-2026-04-23": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -8078,6 +8098,7 @@
"supports_vision": true
},
"azure/us/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.38e-06,
"litellm_provider": "azure",
@ -23023,6 +23044,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -23062,6 +23084,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.1-2025-11-13": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -23140,6 +23163,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.2": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -23180,6 +23204,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.2-2025-12-11": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -23576,6 +23601,7 @@
"supports_xhigh_reasoning_effort": true
},
"gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
@ -23625,6 +23651,7 @@
"supports_minimal_reasoning_effort": false
},
"gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
@ -23674,6 +23701,7 @@
"supports_minimal_reasoning_effort": false
},
"gpt-5.5-pro": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -23719,6 +23747,7 @@
"supports_low_reasoning_effort": false
},
"gpt-5.5-pro-2026-04-23": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -23764,6 +23793,7 @@
"supports_low_reasoning_effort": false
},
"gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_flex": 1.3e-07,
@ -23812,6 +23842,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_flex": 1.3e-07,

View file

@ -161,6 +161,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False):
supports_low_reasoning_effort: Optional[bool]
supports_xhigh_reasoning_effort: Optional[bool]
supports_max_reasoning_effort: Optional[bool]
default_reasoning_effort: Optional[Literal["none", "minimal", "low", "medium", "high", "xhigh"]]
supports_output_config: Optional[bool]
supports_image_size: Optional[bool]
bedrock_output_config_effort_ceiling: Optional[Literal["low", "medium", "high", "max", "xhigh"]]

View file

@ -2420,6 +2420,29 @@ def _is_explicitly_disabled_factory(model: str, custom_llm_provider: Optional[st
return False
def _default_reasoning_effort_factory(model: str, custom_llm_provider: str | None) -> str | None:
try:
resolved_model, resolved_provider, _, _ = litellm.get_llm_provider(
model=model, custom_llm_provider=custom_llm_provider
)
model_info = _get_model_info_helper(model=resolved_model, custom_llm_provider=resolved_provider)
value = model_info.get("default_reasoning_effort")
if value is not None:
return value
bare_model_key = _get_model_cost_key(resolved_model)
if bare_model_key is None:
return None
bare_value = (litellm.model_cost.get(bare_model_key) or {}).get("default_reasoning_effort")
return bare_value if isinstance(bare_value, str) else None
except Exception as e: # noqa: BLE001 # _get_model_info_helper raises bare Exception for unmapped models
verbose_logger.debug(
f"Model not found or error in checking default_reasoning_effort. "
f"You passed model={model}, custom_llm_provider={custom_llm_provider}. "
f"Error: {str(e)}"
)
return None
def supports_audio_input(model: str, custom_llm_provider: Optional[str] = None) -> bool:
"""Check if a given model supports audio input in a chat completion call"""
return _supports_factory(model=model, custom_llm_provider=custom_llm_provider, key="supports_audio_input")
@ -5520,6 +5543,7 @@ def _get_model_info_helper(
supports_low_reasoning_effort=_model_info.get("supports_low_reasoning_effort", None),
supports_xhigh_reasoning_effort=_model_info.get("supports_xhigh_reasoning_effort", None),
supports_max_reasoning_effort=_model_info.get("supports_max_reasoning_effort", None),
default_reasoning_effort=_model_info.get("default_reasoning_effort", None),
bedrock_output_config_effort_ceiling=_model_info.get("bedrock_output_config_effort_ceiling", None),
bedrock_converse_supports_strict_tools=_model_info.get("bedrock_converse_supports_strict_tools", None),
supports_computer_use=_model_info.get("supports_computer_use", None),

View file

@ -3575,6 +3575,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.38e-06,
"litellm_provider": "azure",
@ -3877,6 +3878,7 @@
"supports_vision": true
},
"azure/global/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"input_cost_per_token": 1.25e-06,
"litellm_provider": "azure",
@ -4913,6 +4915,7 @@
"supports_audio_input": true
},
"azure/gpt-5.1-2025-11-13": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -5368,6 +5371,7 @@
"supports_vision": true
},
"azure/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"input_cost_per_token": 1.25e-06,
"litellm_provider": "azure",
@ -5526,6 +5530,7 @@
"supports_vision": true
},
"azure/gpt-5.2": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"input_cost_per_token": 1.75e-06,
"litellm_provider": "azure",
@ -5559,6 +5564,7 @@
"supports_vision": true
},
"azure/gpt-5.2-2025-12-11": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -5819,6 +5825,7 @@
"supports_web_search": true
},
"azure/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_priority": 5e-07,
@ -5860,6 +5867,7 @@
"supports_vision": true
},
"azure/us/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -5895,6 +5903,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -5930,6 +5939,7 @@
"supports_vision": true
},
"azure/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_priority": 5e-07,
@ -5971,6 +5981,7 @@
"supports_vision": true
},
"azure/us/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -6006,6 +6017,7 @@
"supports_vision": true
},
"azure/eu/gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.8e-07,
"cache_read_input_token_cost_priority": 5.5e-07,
"input_cost_per_token": 2.75e-06,
@ -6627,6 +6639,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_priority": 1e-06,
@ -6672,6 +6685,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/us/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6714,6 +6728,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/eu/gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6756,6 +6771,7 @@
"supports_minimal_reasoning_effort": false
},
"azure/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_priority": 1e-06,
@ -6798,6 +6814,7 @@
"supports_web_search": true
},
"azure/us/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6837,6 +6854,7 @@
"supports_web_search": true
},
"azure/eu/gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1.1e-06,
"cache_read_input_token_cost_priority": 1.38e-06,
@ -6876,6 +6894,7 @@
"supports_web_search": true
},
"azure/gpt-5.5-pro": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -6915,6 +6934,7 @@
"supports_low_reasoning_effort": false
},
"azure/gpt-5.5-pro-2026-04-23": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -8078,6 +8098,7 @@
"supports_vision": true
},
"azure/us/gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.38e-06,
"litellm_provider": "azure",
@ -23098,6 +23119,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.1": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -23137,6 +23159,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.1-2025-11-13": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.25e-07,
"cache_read_input_token_cost_priority": 2.5e-07,
"input_cost_per_token": 1.25e-06,
@ -23215,6 +23238,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.2": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -23255,6 +23279,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.2-2025-12-11": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 1.75e-07,
"cache_read_input_token_cost_priority": 3.5e-07,
"input_cost_per_token": 1.75e-06,
@ -23651,6 +23676,7 @@
"supports_xhigh_reasoning_effort": true
},
"gpt-5.5": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
@ -23700,6 +23726,7 @@
"supports_minimal_reasoning_effort": false
},
"gpt-5.5-2026-04-23": {
"default_reasoning_effort": "medium",
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
@ -23749,6 +23776,7 @@
"supports_minimal_reasoning_effort": false
},
"gpt-5.5-pro": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -23794,6 +23822,7 @@
"supports_low_reasoning_effort": false
},
"gpt-5.5-pro-2026-04-23": {
"default_reasoning_effort": "high",
"cache_read_input_token_cost": 3e-06,
"cache_read_input_token_cost_above_272k_tokens": 6e-06,
"input_cost_per_token": 3e-05,
@ -23839,6 +23868,7 @@
"supports_low_reasoning_effort": false
},
"gpt-5.4": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_flex": 1.3e-07,
@ -23887,6 +23917,7 @@
"supports_minimal_reasoning_effort": true
},
"gpt-5.4-2026-03-05": {
"default_reasoning_effort": "none",
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_above_272k_tokens": 5e-07,
"cache_read_input_token_cost_flex": 1.3e-07,

View file

@ -1,6 +1,7 @@
import pytest
import litellm
from litellm.litellm_core_utils.get_model_cost_map import get_model_cost_map
from litellm.llms.azure.chat.gpt_5_transformation import AzureOpenAIGPT5Config
@ -9,6 +10,13 @@ def config() -> AzureOpenAIGPT5Config:
return AzureOpenAIGPT5Config()
@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_azure_gpt5_supports_reasoning_effort(config: AzureOpenAIGPT5Config):
assert "reasoning_effort" in config.get_supported_openai_params(model="gpt-5")
assert "reasoning_effort" in config.get_supported_openai_params(
@ -299,3 +307,72 @@ def test_azure_gpt5_1_does_not_support_logprobs(config: AzureOpenAIGPT5Config):
supported_params = config.get_supported_openai_params(model="gpt-5.1")
assert "logprobs" not in supported_params
assert "top_logprobs" not in supported_params
def test_azure_gpt5_5_temperature_dropped_without_reasoning_effort(
config: AzureOpenAIGPT5Config,
):
params = config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="azure/gpt-5.5",
drop_params=True,
api_version="2025-01-01-preview",
)
assert "temperature" not in params
def test_azure_gpt5_5_temperature_error_without_reasoning_effort(
config: AzureOpenAIGPT5Config,
):
with pytest.raises(
litellm.utils.UnsupportedParamsError,
match="reasoning_effort resolves to 'medium'",
):
config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="azure/gpt-5.5",
drop_params=False,
api_version="2025-01-01-preview",
)
def test_azure_gpt5_5_series_temperature_dropped_without_reasoning_effort(
config: AzureOpenAIGPT5Config,
):
params = config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="gpt5_series/gpt-5.5",
drop_params=True,
api_version="2025-01-01-preview",
)
assert "temperature" not in params
def test_azure_gpt5_5_bare_deployment_temperature_error_without_reasoning_effort(
config: AzureOpenAIGPT5Config,
):
with pytest.raises(litellm.utils.UnsupportedParamsError):
config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="gpt-5.5",
drop_params=False,
api_version="2025-01-01-preview",
)
def test_azure_gpt5_5_temperature_with_explicit_reasoning_effort_none(
config: AzureOpenAIGPT5Config,
):
params = config.map_openai_params(
non_default_params={"temperature": 0.1, "reasoning_effort": "none"},
optional_params={},
model="azure/gpt-5.5",
drop_params=False,
api_version="2025-01-01-preview",
)
assert params["temperature"] == 0.1
assert params["reasoning_effort"] == "none"

View file

@ -137,7 +137,7 @@ def test_gpt5_codex_temperature_error(config: OpenAIConfig):
"""Test that GPT-5-Codex raises error for unsupported temperature when drop_params=False."""
with pytest.raises(
litellm.utils.UnsupportedParamsError,
match="gpt-5 models \\(including gpt-5-codex\\)",
match="gpt-5-codex doesn't support temperature=0.7",
):
config.map_openai_params(
non_default_params={"temperature": 0.7},
@ -1309,3 +1309,120 @@ def test_responses_gpt54_allow_temperature_effort_none(
drop_params=False,
)
assert params["temperature"] == 0.7
def test_gpt5_5_temperature_dropped_without_reasoning_effort(config: OpenAIConfig):
params = config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="gpt-5.5",
drop_params=True,
)
assert "temperature" not in params
def test_gpt5_5_temperature_error_without_reasoning_effort(config: OpenAIConfig):
with pytest.raises(
litellm.utils.UnsupportedParamsError,
match="reasoning_effort resolves to 'medium'",
):
config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="gpt-5.5",
drop_params=False,
)
def test_gpt5_5_dated_temperature_error_without_reasoning_effort(config: OpenAIConfig):
with pytest.raises(litellm.utils.UnsupportedParamsError):
config.map_openai_params(
non_default_params={"temperature": 0.1},
optional_params={},
model="gpt-5.5-2026-04-23",
drop_params=False,
)
def test_gpt5_5_temperature_with_explicit_reasoning_effort_none(config: OpenAIConfig):
params = config.map_openai_params(
non_default_params={"temperature": 0.1, "reasoning_effort": "none"},
optional_params={},
model="gpt-5.5",
drop_params=False,
)
assert params["temperature"] == 0.1
assert params["reasoning_effort"] == "none"
def test_gpt5_5_temperature_one_without_reasoning_effort(config: OpenAIConfig):
params = config.map_openai_params(
non_default_params={"temperature": 1.0},
optional_params={},
model="gpt-5.5",
drop_params=False,
)
assert params["temperature"] == 1.0
def test_gpt5_5_top_p_dropped_without_reasoning_effort(config: OpenAIConfig):
params = config.map_openai_params(
non_default_params={"top_p": 0.5},
optional_params={},
model="gpt-5.5",
drop_params=True,
)
assert "top_p" not in params
def test_gpt5_6_temperature_kept_when_default_effort_absent(config: OpenAIConfig):
params = config.map_openai_params(
non_default_params={"temperature": 0.2},
optional_params={},
model="gpt-5.6",
drop_params=False,
)
assert params["temperature"] == 0.2
def test_responses_gpt5_5_temperature_dropped_without_reasoning(
responses_config: OpenAIResponsesAPIConfig,
):
params = responses_config.map_openai_params(
response_api_optional_params=ResponsesAPIOptionalRequestParams(
temperature=0.1,
),
model="gpt-5.5",
drop_params=True,
)
assert "temperature" not in params
def test_responses_gpt5_5_temperature_error_without_reasoning(
responses_config: OpenAIResponsesAPIConfig,
):
with pytest.raises(
litellm.UnsupportedParamsError,
match="reasoning_effort resolves to 'medium'",
):
responses_config.map_openai_params(
response_api_optional_params=ResponsesAPIOptionalRequestParams(
temperature=0.1,
),
model="gpt-5.5",
drop_params=False,
)
def test_responses_gpt5_5_temperature_allowed_with_effort_none(
responses_config: OpenAIResponsesAPIConfig,
):
params = responses_config.map_openai_params(
response_api_optional_params=ResponsesAPIOptionalRequestParams(
temperature=0.1,
reasoning={"effort": "none"},
),
model="gpt-5.5",
drop_params=False,
)
assert params["temperature"] == 0.1

View file

@ -861,6 +861,10 @@ def test_aaamodel_prices_and_context_window_json_is_valid():
"supports_none_reasoning_effort": {"type": "boolean"},
"supports_xhigh_reasoning_effort": {"type": "boolean"},
"supports_max_reasoning_effort": {"type": "boolean"},
"default_reasoning_effort": {
"type": "string",
"enum": ["none", "minimal", "low", "medium", "high", "xhigh"],
},
"supports_adaptive_thinking": {"type": "boolean"},
"supports_mid_conversation_system": {"type": "boolean"},
"supports_sampling_params": {"type": "boolean"},