From 5ca2041ba19e96ad1a14fed01194de3cb57c9735 Mon Sep 17 00:00:00 2001 From: Abhishek Deshmukh Date: Sat, 4 Apr 2026 01:17:03 +0530 Subject: [PATCH] fix: include supports_xhigh/none/minimal_reasoning_effort in get_model_info get_model_info was not returning supports_xhigh_reasoning_effort, supports_none_reasoning_effort, or supports_minimal_reasoning_effort even though these fields exist in model_prices_and_context_window.json. The _get_model_info_helper function builds a ModelInfoBase object by explicitly passing each field, but these three reasoning-effort capability fields were missing from the constructor call. Also added supports_parallel_function_calling which was similarly omitted. Changes: - litellm/utils.py: add the four missing fields to ModelInfoBase(...) constructor in _get_model_info_helper - litellm/types/utils.py: add supports_minimal_reasoning_effort to ProviderSpecificModelInfo TypedDict (it was already in the JSON and used in gpt_5_transformation.py but not in the type definition) - tests/test_litellm/test_utils.py: add regression test for the bug (issue #25096) Fixes #25096 --- litellm/types/utils.py | 1 + litellm/utils.py | 12 +++++++++++ tests/test_litellm/test_utils.py | 35 ++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 3f6e6e5aa5a..caa63d8c2c5 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -140,6 +140,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False): supports_url_context: Optional[bool] supports_none_reasoning_effort: Optional[bool] supports_xhigh_reasoning_effort: Optional[bool] + supports_minimal_reasoning_effort: Optional[bool] class SearchContextCostPerQuery(TypedDict, total=False): diff --git a/litellm/utils.py b/litellm/utils.py index e2dac1c9f62..5a6e15aaea7 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -5861,6 +5861,18 @@ def _get_model_info_helper( # noqa: PLR0915 supports_url_context=_model_info.get("supports_url_context", None), supports_reasoning=_model_info.get("supports_reasoning", None), supports_computer_use=_model_info.get("supports_computer_use", None), + supports_parallel_function_calling=_model_info.get( + "supports_parallel_function_calling", 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_minimal_reasoning_effort=_model_info.get( + "supports_minimal_reasoning_effort", None + ), search_context_cost_per_query=_model_info.get( "search_context_cost_per_query", None ), diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index bdb38ab65f3..47b8b571d85 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -1166,6 +1166,41 @@ def test_get_model_info_shows_supports_computer_use(): ) # Expecting None due to the default in ModelInfoBase +def test_get_model_info_shows_supports_xhigh_reasoning_effort(): + """ + Tests that get_model_info correctly returns supports_xhigh_reasoning_effort. + + Regression test for https://github.com/BerriAI/litellm/issues/25096 + where get_model_info omitted reasoning-effort capability fields even + though they exist in model_cost. + """ + os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" + litellm.model_cost = litellm.get_model_cost_map(url="") + + model = "gpt-5.4" + info = litellm.get_model_info(model) + model_cost = litellm.model_cost[model] + + assert info.get("supports_xhigh_reasoning_effort") == model_cost.get( + "supports_xhigh_reasoning_effort" + ), ( + f"get_model_info should return supports_xhigh_reasoning_effort={model_cost.get('supports_xhigh_reasoning_effort')!r} " + f"for {model!r}, got {info.get('supports_xhigh_reasoning_effort')!r}" + ) + assert info.get("supports_none_reasoning_effort") == model_cost.get( + "supports_none_reasoning_effort" + ), ( + f"get_model_info should return supports_none_reasoning_effort={model_cost.get('supports_none_reasoning_effort')!r} " + f"for {model!r}, got {info.get('supports_none_reasoning_effort')!r}" + ) + assert info.get("supports_minimal_reasoning_effort") == model_cost.get( + "supports_minimal_reasoning_effort" + ), ( + f"get_model_info should return supports_minimal_reasoning_effort={model_cost.get('supports_minimal_reasoning_effort')!r} " + f"for {model!r}, got {info.get('supports_minimal_reasoning_effort')!r}" + ) + + @pytest.mark.parametrize( "model, custom_llm_provider", [