Fix reasoningSummary for gpt-5 series as well

This commit is contained in:
Sameer Kankute
2026-05-11 11:15:05 +05:30
parent 0ac923c6b6
commit 22e9fd12df
2 changed files with 92 additions and 8 deletions
+20 -8
View File
@@ -991,17 +991,29 @@ def responses_api_bridge_check(
mode = "responses"
model_info["mode"] = mode
# OpenAI/Azure gpt-5.4+ chat-completions calls that need Responses-only fields
# (e.g. reasoning summary) must be bridged. SDKs send ``reasoningSummary`` /
# ``reasoning_summary`` alongside ``reasoning_effort``; Chat Completions rejects
# those keys, so route when tools+reasoning_effort (original case) or when a
# reasoning summary is requested without tools.
# OpenAI/Azure GPT-5 chat-completions that need Responses-only fields (e.g.
# ``reasoningSummary`` in ``extra_body``) must be bridged; Chat Completions rejects
# those keys.
#
# - gpt-5.4+: tools + reasoning_effort (original) or any reasoning-summary alias.
# - Older GPT-5 names (e.g. ``gpt-5``, ``gpt-5.1``): bridge only when a reasoning
# summary alias is present with ``reasoning_effort`` (tools alone stay on chat).
if (
custom_llm_provider in ("openai", "azure")
and OpenAIGPT5Config.is_model_gpt_5_4_plus_model(model)
and reasoning_effort is not None
and (tools or reasoning_summary is not None)
and model_info.get("mode") != "responses"
and OpenAIGPT5Config.is_model_gpt_5_model(model)
and not OpenAIGPT5Config.is_model_gpt_5_search_model(model)
and reasoning_effort is not None
and (
(
OpenAIGPT5Config.is_model_gpt_5_4_plus_model(model)
and (tools or reasoning_summary is not None)
)
or (
not OpenAIGPT5Config.is_model_gpt_5_4_plus_model(model)
and reasoning_summary is not None
)
)
):
model_info["mode"] = "responses"
model = model.replace("responses/", "")
+72
View File
@@ -775,6 +775,42 @@ def test_responses_api_bridge_check_gpt_5_4_reasoning_summary_without_tools_rout
assert model_info.get("mode") == "responses"
def test_responses_api_bridge_check_gpt_5_reasoning_summary_routes_to_responses():
"""Bare ``gpt-5`` with reasoning_effort + reasoningSummary should bridge (not 5.4+)."""
from litellm.main import responses_api_bridge_check
with patch("litellm.main._get_model_info_helper") as mock_get_model_info:
mock_get_model_info.return_value = {"max_tokens": 128000}
model_info, model = responses_api_bridge_check(
model="gpt-5",
custom_llm_provider="openai",
tools=None,
reasoning_effort="medium",
reasoning_summary="auto",
)
assert model == "gpt-5"
assert model_info.get("mode") == "responses"
def test_responses_api_bridge_check_gpt_5_tools_without_summary_stays_chat():
"""gpt-5 with tools + reasoning_effort but no summary should stay on chat."""
from litellm.main import responses_api_bridge_check
with patch("litellm.main._get_model_info_helper") as mock_get_model_info:
mock_get_model_info.return_value = {"max_tokens": 128000}
model_info, model = responses_api_bridge_check(
model="gpt-5",
custom_llm_provider="openai",
tools=[{"type": "function", "function": {"name": "get_capital"}}],
reasoning_effort="medium",
reasoning_summary=None,
)
assert model == "gpt-5"
assert model_info.get("mode") != "responses"
@patch("litellm.completion_extras.responses_api_bridge.completion")
def test_gpt_5_4_responses_bridge_preserves_reasoning_summary_dict(
mock_responses_completion,
@@ -839,6 +875,42 @@ def test_gpt_5_4_responses_bridge_merges_reasoning_summary_kwarg_without_tools(
assert "reasoning_summary" not in optional_params
@patch("litellm.completion_extras.responses_api_bridge.completion")
def test_gpt_5_responses_bridge_tools_and_reasoning_summary(
mock_responses_completion,
):
"""Bare gpt-5 with tools + reasoningSummary should bridge (OpenCode-style)."""
mock_responses_completion.return_value = MagicMock()
import litellm
litellm.completion(
model="gpt-5",
messages=[{"role": "user", "content": "ok"}],
tools=[
{
"type": "function",
"function": {
"name": "apply_patch",
"parameters": {"type": "object", "properties": {}},
},
}
],
tool_choice="auto",
reasoning_effort="medium",
reasoningSummary="auto",
stream=True,
api_key="fake-key",
)
assert mock_responses_completion.called is True
optional_params = mock_responses_completion.call_args.kwargs["optional_params"]
assert optional_params.get("reasoning_effort") == {
"effort": "medium",
"summary": "auto",
}
def test_responses_api_bridge_check_handles_exception():
"""Test that responses_api_bridge_check handles exceptions and still processes responses/ models."""
from litellm.main import responses_api_bridge_check