diff --git a/litellm/utils.py b/litellm/utils.py index ca878721197..d71a6917173 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -2538,6 +2538,12 @@ def _supports_factory(model: str, custom_llm_provider: Optional[str], key: str) model=model, custom_llm_provider=custom_llm_provider ) + # Strip responses/ prefix so capability lookups resolve to the + # base model entry in the cost map (e.g. "gpt-5.4" not + # "responses/gpt-5.4"). See #23423. + if model.startswith("responses/"): + model = model[len("responses/"):] + model_info = _get_model_info_helper( model=model, custom_llm_provider=custom_llm_provider ) diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index 64488e2fb6a..826ae1917cd 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -998,6 +998,10 @@ def test_supports_tool_choice_simple_tests(): assert litellm.utils.supports_tool_choice(model="perplexity/sonar") is False + # Responses API prefix must resolve to base model. See #23423. + assert litellm.utils.supports_tool_choice(model="openai/responses/gpt-5.4") is True + assert litellm.utils.supports_tool_choice(model="responses/gpt-5.4", custom_llm_provider="openai") is True + def test_check_provider_match(): """