mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-05 16:24:59 +00:00
Fix reasoning summary alias stripping
This commit is contained in:
@@ -212,6 +212,12 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
|
||||
model: str,
|
||||
drop_params: bool,
|
||||
) -> dict:
|
||||
# AI SDK / Responses-style aliases; never valid on Chat Completions when not
|
||||
# bridged to Responses API (see main.responses_api_bridge_check).
|
||||
self._strip_reasoning_summary_aliases_for_chat_completions(
|
||||
non_default_params, optional_params
|
||||
)
|
||||
|
||||
if self.is_model_gpt_5_search_model(model):
|
||||
if "max_tokens" in non_default_params:
|
||||
optional_params["max_completion_tokens"] = non_default_params.pop(
|
||||
@@ -224,12 +230,6 @@ class OpenAIGPT5Config(OpenAIGPTConfig):
|
||||
drop_params=drop_params,
|
||||
)
|
||||
|
||||
# AI SDK / Responses-style aliases; never valid on Chat Completions when not
|
||||
# bridged to Responses API (see main.responses_api_bridge_check).
|
||||
self._strip_reasoning_summary_aliases_for_chat_completions(
|
||||
non_default_params, optional_params
|
||||
)
|
||||
|
||||
# Get raw reasoning_effort and effective effort level for all guards.
|
||||
# Use effective_effort (extracted string) for xhigh validation, "none" checks, and
|
||||
# tool/sampling guards — dict inputs like {"effort": "none", "summary": "detailed"}
|
||||
|
||||
+14
-11
@@ -9494,14 +9494,17 @@ def get_non_default_completion_params(kwargs: dict) -> dict:
|
||||
|
||||
def peek_reasoning_summary_aliases(optional_params: dict) -> Optional[Any]:
|
||||
"""Read AI-SDK-style reasoning summary from optional_params or nested extra_body."""
|
||||
rs = optional_params.get("reasoningSummary") or optional_params.get(
|
||||
"reasoning_summary"
|
||||
)
|
||||
rs = optional_params.get("reasoningSummary")
|
||||
if rs is None:
|
||||
rs = optional_params.get("reasoning_summary")
|
||||
if rs is not None:
|
||||
return rs
|
||||
extra_body = optional_params.get("extra_body")
|
||||
if isinstance(extra_body, dict):
|
||||
return extra_body.get("reasoningSummary") or extra_body.get("reasoning_summary")
|
||||
rs = extra_body.get("reasoningSummary")
|
||||
if rs is None:
|
||||
rs = extra_body.get("reasoning_summary")
|
||||
return rs
|
||||
return None
|
||||
|
||||
|
||||
@@ -9511,18 +9514,18 @@ def strip_reasoning_summary_aliases_from_optional_params(
|
||||
"""Copy optional_params; remove reasoningSummary aliases from top-level and extra_body."""
|
||||
op = dict(optional_params)
|
||||
rs_val = op.pop("reasoningSummary", None)
|
||||
snake_rs_val = op.pop("reasoning_summary", None)
|
||||
if rs_val is None:
|
||||
rs_val = op.pop("reasoning_summary", None)
|
||||
rs_val = snake_rs_val
|
||||
eb = op.get("extra_body")
|
||||
if isinstance(eb, dict):
|
||||
eb = dict(eb)
|
||||
eb_rs_val = eb.pop("reasoningSummary", None)
|
||||
eb_snake_rs_val = eb.pop("reasoning_summary", None)
|
||||
if rs_val is None:
|
||||
rs_val = eb.pop("reasoningSummary", None) or eb.pop(
|
||||
"reasoning_summary", None
|
||||
)
|
||||
else:
|
||||
eb.pop("reasoningSummary", None)
|
||||
eb.pop("reasoning_summary", None)
|
||||
rs_val = eb_rs_val
|
||||
if rs_val is None:
|
||||
rs_val = eb_snake_rs_val
|
||||
if eb:
|
||||
op["extra_body"] = eb
|
||||
else:
|
||||
|
||||
@@ -4,7 +4,11 @@ import litellm
|
||||
from litellm.litellm_core_utils.get_model_cost_map import get_model_cost_map
|
||||
from litellm.llms.openai.chat.gpt_5_transformation import OpenAIGPT5Config
|
||||
from litellm.llms.openai.openai import OpenAIConfig
|
||||
from litellm.utils import _is_explicitly_disabled_factory
|
||||
from litellm.utils import (
|
||||
_is_explicitly_disabled_factory,
|
||||
peek_reasoning_summary_aliases,
|
||||
strip_reasoning_summary_aliases_from_optional_params,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@@ -1007,6 +1011,74 @@ def test_gpt5_search_drops_unsupported_params(config: OpenAIConfig):
|
||||
assert "tools" not in params
|
||||
|
||||
|
||||
def test_gpt5_search_strips_reasoning_summary_aliases(gpt5_config: OpenAIGPT5Config):
|
||||
"""Search models still strip Responses-only reasoning summary aliases."""
|
||||
non_default_params = {
|
||||
"reasoningSummary": "auto",
|
||||
"reasoning_summary": "ignored",
|
||||
}
|
||||
optional_params = {
|
||||
"extra_body": {
|
||||
"reasoningSummary": "auto",
|
||||
"reasoning_summary": "ignored",
|
||||
"metadata": "ok",
|
||||
}
|
||||
}
|
||||
|
||||
params = gpt5_config.map_openai_params(
|
||||
non_default_params=non_default_params,
|
||||
optional_params=optional_params,
|
||||
model="gpt-5-search-api",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
assert "reasoningSummary" not in non_default_params
|
||||
assert "reasoning_summary" not in non_default_params
|
||||
assert "reasoningSummary" not in params
|
||||
assert "reasoning_summary" not in params
|
||||
assert params["extra_body"] == {"metadata": "ok"}
|
||||
|
||||
|
||||
def test_reasoning_summary_alias_helpers_preserve_falsy_and_strip_all_aliases():
|
||||
optional_params = {"reasoningSummary": False, "reasoning_summary": "ignored"}
|
||||
|
||||
assert peek_reasoning_summary_aliases(optional_params) is False
|
||||
stripped, rs_val = strip_reasoning_summary_aliases_from_optional_params(
|
||||
optional_params
|
||||
)
|
||||
|
||||
assert rs_val is False
|
||||
assert stripped == {}
|
||||
|
||||
optional_params = {
|
||||
"extra_body": {"reasoningSummary": False, "reasoning_summary": "ignored"}
|
||||
}
|
||||
|
||||
assert peek_reasoning_summary_aliases(optional_params) is False
|
||||
stripped, rs_val = strip_reasoning_summary_aliases_from_optional_params(
|
||||
optional_params
|
||||
)
|
||||
|
||||
assert rs_val is False
|
||||
assert stripped == {}
|
||||
|
||||
optional_params = {
|
||||
"extra_body": {
|
||||
"reasoningSummary": "auto",
|
||||
"reasoning_summary": "ignored",
|
||||
"metadata": "ok",
|
||||
}
|
||||
}
|
||||
|
||||
assert peek_reasoning_summary_aliases(optional_params) == "auto"
|
||||
stripped, rs_val = strip_reasoning_summary_aliases_from_optional_params(
|
||||
optional_params
|
||||
)
|
||||
|
||||
assert rs_val == "auto"
|
||||
assert stripped == {"extra_body": {"metadata": "ok"}}
|
||||
|
||||
|
||||
# GPT-5 unsupported params audit (validated via direct API calls)
|
||||
def test_gpt5_rejects_params_unsupported_by_openai(config: OpenAIConfig):
|
||||
"""Params that OpenAI rejects for all GPT-5 reasoning models."""
|
||||
|
||||
Reference in New Issue
Block a user