Fix: Add support for reasoning check via model map

This commit is contained in:
Sameer Kankute 2026-03-03 13:24:37 +05:30
parent 86d5b4c632
commit 8cf6798385
6 changed files with 77307 additions and 77015 deletions

View file

@ -65,9 +65,9 @@ class AzureOpenAIGPT5Config(AzureOpenAIConfig, OpenAIGPT5Config):
# gpt-5.1 supports reasoning_effort='none', but other gpt-5 models don't
# See: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/reasoning
is_gpt_5_1 = self.is_model_gpt_5_1_model(model)
supports_none = self._supports_reasoning_effort_level(model, "none")
if reasoning_effort_value == "none" and not is_gpt_5_1:
if reasoning_effort_value == "none" and not supports_none:
if litellm.drop_params is True or (
drop_params is not None and drop_params is True
):
@ -97,8 +97,8 @@ class AzureOpenAIGPT5Config(AzureOpenAIConfig, OpenAIGPT5Config):
drop_params=drop_params,
)
# Only drop reasoning_effort='none' for non-gpt-5.1 models
if result.get("reasoning_effort") == "none" and not is_gpt_5_1:
# Only drop reasoning_effort='none' for models that don't support it
if result.get("reasoning_effort") == "none" and not supports_none:
result.pop("reasoning_effort")
return result

View file

@ -3,6 +3,7 @@
from typing import Optional
import litellm
from litellm.utils import _supports_factory
from .gpt_transformation import OpenAIGPTConfig
@ -40,42 +41,26 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
"""Check if the model is specifically a GPT-5 Codex variant."""
return "gpt-5-codex" in model
@classmethod
def is_model_gpt_5_1_codex_max_model(cls, model: str) -> bool:
"""Check if the model is the gpt-5.1-codex-max variant."""
model_name = model.split("/")[-1] # handle provider prefixes
return model_name == "gpt-5.1-codex-max"
@classmethod
def is_model_gpt_5_1_model(cls, model: str) -> bool:
"""Check if the model is a gpt-5.1 or gpt-5.2 chat variant.
gpt-5.1/5.2 support temperature when reasoning_effort="none",
unlike base gpt-5 which only supports temperature=1. Excludes
pro variants which keep stricter knobs and gpt-5.2-chat variants
which only support temperature=1.
"""
model_name = model.split("/")[-1]
is_gpt_5_1 = model_name.startswith("gpt-5.1")
is_gpt_5_2 = (
model_name.startswith("gpt-5.2")
and "pro" not in model_name
and not model_name.startswith("gpt-5.2-chat")
)
return is_gpt_5_1 or is_gpt_5_2
@classmethod
def is_model_gpt_5_2_pro_model(cls, model: str) -> bool:
"""Check if the model is the gpt-5.2-pro snapshot/alias."""
model_name = model.split("/")[-1]
return model_name.startswith("gpt-5.2-pro")
@classmethod
def is_model_gpt_5_2_model(cls, model: str) -> bool:
"""Check if the model is a gpt-5.2 variant (including pro)."""
model_name = model.split("/")[-1]
return model_name.startswith("gpt-5.2")
@classmethod
def _supports_reasoning_effort_level(cls, model: str, level: str) -> bool:
"""Check if the model supports a specific reasoning_effort level.
Looks up ``supports_{level}_reasoning_effort`` in the model map via
the shared ``_supports_factory`` helper.
Returns False for unknown models (safe fallback).
"""
return _supports_factory(
model=model,
custom_llm_provider=None,
key=f"supports_{level}_reasoning_effort",
)
def get_supported_openai_params(self, model: str) -> list:
if self.is_model_gpt_5_search_model(model):
return [
@ -114,7 +99,7 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
]
# gpt-5.1/5.2 support logprobs, top_p, top_logprobs when reasoning_effort="none"
if not self.is_model_gpt_5_1_model(model):
if not self._supports_reasoning_effort_level(model, "none"):
non_supported_params.extend(["logprobs", "top_p", "top_logprobs"])
return [
@ -147,10 +132,7 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
or optional_params.get("reasoning_effort")
)
if reasoning_effort is not None and reasoning_effort == "xhigh":
if not (
self.is_model_gpt_5_1_codex_max_model(model)
or self.is_model_gpt_5_2_model(model)
):
if not self._supports_reasoning_effort_level(model, "xhigh"):
if litellm.drop_params or drop_params:
non_default_params.pop("reasoning_effort", None)
else:
@ -171,7 +153,8 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
)
# gpt-5.1/5.2 support logprobs, top_p, top_logprobs only when reasoning_effort="none"
if self.is_model_gpt_5_1_model(model):
supports_none = self._supports_reasoning_effort_level(model, "none")
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 reasoning_effort not in (None, "none"):
@ -191,10 +174,8 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
if "temperature" in non_default_params:
temperature_value: Optional[float] = non_default_params.pop("temperature")
if temperature_value is not None:
is_gpt_5_1 = self.is_model_gpt_5_1_model(model)
# gpt-5.1 supports any temperature when reasoning_effort="none" (or not specified, as it defaults to "none")
if is_gpt_5_1 and (reasoning_effort == "none" or reasoning_effort is None):
# models supporting reasoning_effort="none" also support flexible temperature
if supports_none and (reasoning_effort == "none" or reasoning_effort is None):
optional_params["temperature"] = temperature_value
elif temperature_value == 1:
optional_params["temperature"] = temperature_value

File diff suppressed because it is too large Load diff

View file

@ -136,6 +136,8 @@ class ProviderSpecificModelInfo(TypedDict, total=False):
supports_web_search: Optional[bool]
supports_reasoning: Optional[bool]
supports_url_context: Optional[bool]
supports_none_reasoning_effort: Optional[bool]
supports_xhigh_reasoning_effort: Optional[bool]
class SearchContextCostPerQuery(TypedDict, total=False):

View file

@ -5718,6 +5718,12 @@ def _get_model_info_helper( # noqa: PLR0915
supports_web_search=_model_info.get("supports_web_search", None),
supports_url_context=_model_info.get("supports_url_context", None),
supports_reasoning=_model_info.get("supports_reasoning", None),
supports_none_reasoning_effort=_model_info.get(
"supports_none_reasoning_effort", None
),
supports_xhigh_reasoning_effort=_model_info.get(
"supports_xhigh_reasoning_effort", None
),
supports_computer_use=_model_info.get("supports_computer_use", None),
search_context_cost_per_query=_model_info.get(
"search_context_cost_per_query", None

File diff suppressed because it is too large Load diff