From d9929379003a2b5ea2d6c584fb9c1088a7e6aab7 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Sat, 5 Sep 2026 03:17:11 -0700 Subject: [PATCH] fix(responses): read reasoning support from the cost map instead of model-name rules --- .../llms/openai/responses/transformation.py | 7 ------- ...odel_prices_and_context_window_backup.json | 4 ++++ model_prices_and_context_window.json | 4 ++++ .../test_openai_responses_transformation.py | 2 ++ .../test_litellm/test_model_prices_schema.py | 21 +++++++++++++++++++ 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/litellm/llms/openai/responses/transformation.py b/litellm/llms/openai/responses/transformation.py index cdfbbb5be5c..123e9a1dda4 100644 --- a/litellm/llms/openai/responses/transformation.py +++ b/litellm/llms/openai/responses/transformation.py @@ -117,14 +117,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): return OpenAIGPT5Config.effort_resolves_to_none(model, effort) - @staticmethod - def _is_o_series_name(model: str) -> bool: - base: Final = model.split("/")[-1] - return len(base) > 1 and base[0] == "o" and base[1].isdigit() - def _supports_reasoning_param(self, model: str) -> bool: - if self._is_gpt_5_model(model=model) or self._is_o_series_name(model=model): - return True base: Final = model.split("/")[-1] if base not in litellm.open_ai_chat_completion_models: return True diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 2459ed940e0..99e728a30bc 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -37115,6 +37115,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37155,6 +37156,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37366,6 +37368,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37406,6 +37409,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 2459ed940e0..99e728a30bc 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -37115,6 +37115,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37155,6 +37156,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37366,6 +37368,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -37406,6 +37409,7 @@ "supports_parallel_function_calling": true, "supports_pdf_input": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, diff --git a/tests/test_litellm/llms/openai/responses/test_openai_responses_transformation.py b/tests/test_litellm/llms/openai/responses/test_openai_responses_transformation.py index bf382d4d8ce..cc884fd7dc1 100644 --- a/tests/test_litellm/llms/openai/responses/test_openai_responses_transformation.py +++ b/tests/test_litellm/llms/openai/responses/test_openai_responses_transformation.py @@ -2034,9 +2034,11 @@ class TestReasoningFollowsModelSupport: ("gpt-4o", False), ("gpt-4.1", False), ("gpt-4o-mini", False), + ("gpt-5-search-api", False), ("gpt-5.6", True), ("o3", True), ("o3-deep-research", True), + ("o4-mini-deep-research", True), ("codex-mini-latest", True), ("computer-use-preview", True), ], diff --git a/tests/test_litellm/test_model_prices_schema.py b/tests/test_litellm/test_model_prices_schema.py index 6114d1d8aba..79609032fbd 100644 --- a/tests/test_litellm/test_model_prices_schema.py +++ b/tests/test_litellm/test_model_prices_schema.py @@ -173,3 +173,24 @@ def test_dated_variants_carry_base_alias_service_tier_pricing(prices: dict): "sync the tier keys so service-tier requests against pinned snapshots are not " "billed at standard rates:\n" + "\n".join(drifted) ) + + +def is_openai_o_series(name: str) -> bool: + base = name.split("/")[-1] + return len(base) > 1 and base[0] == "o" and base[1].isdigit() + + +def test_openai_o_series_entries_carry_supports_reasoning(prices: dict): + unflagged = [ + name + for name, entry in prices.items() + if isinstance(entry, dict) + and entry.get("litellm_provider") == "openai" + and is_openai_o_series(name) + and entry.get("supports_reasoning") is not True + ] + assert unflagged == [], ( + "OpenAI o-series models are reasoning models, and the Responses API drops the " + "`reasoning` param for any mapped OpenAI model whose entry lacks supports_reasoning; " + "flag these entries:\n" + "\n".join(unflagged) + )