From 0d115c8eecea4b2956e54e9da02e2fdddda8da02 Mon Sep 17 00:00:00 2001 From: Austin Varga <64624232+avarga1@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:39:58 -0600 Subject: [PATCH] fix(model_prices): add supports_tool_choice for GPT-5 variants across providers 23 GPT-5 model entries across chatgpt/, github_copilot/, gmi/openai/, perplexity/openai/, and replicate/openai/ had supports_function_calling=true but were missing supports_tool_choice, causing UnsupportedParamsError when tool_choice was passed (e.g. via ChatGPT or Copilot endpoints). Added supports_tool_choice=true for all affected entries where supports_function_calling is already true. Databricks GPT-5 entries are excluded as their function calling support is unconfirmed. Closes #25332 --- model_prices_and_context_window.json | 71 ++++++++++++++++++---------- tests/test_litellm/test_utils.py | 33 ++++++------- 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 90ff7d1103c..6661fdb2e91 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -16483,7 +16483,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/gpt-5-mini": { "litellm_provider": "github_copilot", @@ -16494,7 +16495,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/gpt-5.1": { "litellm_provider": "github_copilot", @@ -16509,7 +16511,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/gpt-5.1-codex-max": { "litellm_provider": "github_copilot", @@ -16523,7 +16526,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/gpt-5.2": { "litellm_provider": "github_copilot", @@ -16538,7 +16542,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/gpt-5.3-codex": { "litellm_provider": "github_copilot", @@ -16552,7 +16557,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "github_copilot/text-embedding-3-small": { "litellm_provider": "github_copilot", @@ -16585,7 +16591,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.4-pro": { "litellm_provider": "chatgpt", @@ -16599,7 +16606,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.3-codex": { "litellm_provider": "chatgpt", @@ -16613,7 +16621,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.3-codex-spark": { "litellm_provider": "chatgpt", @@ -16627,7 +16636,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.3-instant": { "litellm_provider": "chatgpt", @@ -16642,7 +16652,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.3-chat-latest": { "litellm_provider": "chatgpt", @@ -16657,7 +16668,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.2-codex": { "litellm_provider": "chatgpt", @@ -16671,7 +16683,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.2": { "litellm_provider": "chatgpt", @@ -16686,7 +16699,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.1-codex-max": { "litellm_provider": "chatgpt", @@ -16700,7 +16714,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "chatgpt/gpt-5.1-codex-mini": { "litellm_provider": "chatgpt", @@ -16714,7 +16729,8 @@ "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_response_schema": true, - "supports_vision": true + "supports_vision": true, + "supports_tool_choice": true }, "gigachat/GigaChat-2-Lite": { "input_cost_per_token": 0.0, @@ -16830,7 +16846,8 @@ "max_tokens": 32000, "mode": "chat", "output_cost_per_token": 1.4e-05, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "gmi/openai/gpt-5.1": { "input_cost_per_token": 1.25e-06, @@ -16840,7 +16857,8 @@ "max_tokens": 32000, "mode": "chat", "output_cost_per_token": 1e-05, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "gmi/openai/gpt-5": { "input_cost_per_token": 1.25e-06, @@ -16850,7 +16868,8 @@ "max_tokens": 32000, "mode": "chat", "output_cost_per_token": 1e-05, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "gmi/openai/gpt-4o": { "input_cost_per_token": 2.5e-06, @@ -26645,21 +26664,24 @@ "mode": "responses", "supports_web_search": true, "supports_reasoning": true, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "perplexity/openai/gpt-5.1": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "perplexity/openai/gpt-5-mini": { "litellm_provider": "perplexity", "mode": "responses", "supports_web_search": true, "supports_reasoning": false, - "supports_function_calling": true + "supports_function_calling": true, + "supports_tool_choice": true }, "perplexity/anthropic/claude-opus-4-6": { "litellm_provider": "perplexity", @@ -27255,7 +27277,8 @@ "litellm_provider": "replicate", "mode": "chat", "supports_function_calling": true, - "supports_system_messages": true + "supports_system_messages": true, + "supports_tool_choice": true }, "replicate/openai/gpt-5-mini": { "input_cost_per_token": 2.5e-07, @@ -38189,4 +38212,4 @@ "supports_native_structured_output": true, "supports_pdf_input": true } -} \ No newline at end of file +} diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index 50dc3c6c6ec..998b7e48dfe 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -1030,6 +1030,15 @@ def test_supports_tool_choice_simple_tests(): assert litellm.utils.supports_tool_choice(model="perplexity/sonar") is False + # GPT-5 variants across providers that support function calling should also support tool_choice + assert litellm.utils.supports_tool_choice(model="gpt-5.4-mini") is True + assert litellm.utils.supports_tool_choice(model="chatgpt/gpt-5.4") is True + assert litellm.utils.supports_tool_choice(model="github_copilot/gpt-5") is True + assert litellm.utils.supports_tool_choice(model="perplexity/openai/gpt-5.2") is True + assert ( + litellm.utils.supports_tool_choice(model="replicate/openai/gpt-5-nano") is True + ) + def test_check_provider_match(): """ @@ -1412,8 +1421,7 @@ class TestProxyFunctionCalling: assert result is True, "Resolvable model names work with fallback logic" # Documentation notes: - print( - """ + print(""" PROXY MODEL RESOLUTION BEHAVIOR: ✅ WORKS (with current fallback logic): @@ -1428,8 +1436,7 @@ class TestProxyFunctionCalling: 💡 SOLUTION: Use LiteLLM proxy server with proper model_list configuration that maps custom names to underlying models. - """ - ) + """) @pytest.mark.parametrize( "proxy_model_with_hints,expected_result", @@ -1791,8 +1798,7 @@ class TestProxyFunctionCalling: This test provides documentation on how the proxy server configuration would typically map custom model names to underlying models. """ - print( - """ + print(""" REAL-WORLD PROXY SERVER CONFIGURATION EXAMPLE: =============================================== @@ -1845,8 +1851,7 @@ class TestProxyFunctionCalling: - Consistent request/response format - Enhanced streaming support for function calls - """ - ) + """) # Verify that direct underlying models work as expected bedrock_models = [ @@ -2060,8 +2065,7 @@ class TestProxyFunctionCalling: This test provides documentation on how the proxy server configuration would typically map custom model names to underlying models. """ - print( - """ + print(""" REAL-WORLD PROXY SERVER CONFIGURATION EXAMPLE: =============================================== @@ -2114,8 +2118,7 @@ class TestProxyFunctionCalling: - Consistent request/response format - Enhanced streaming support for function calls - """ - ) + """) # Verify that direct underlying models work as expected bedrock_models = [ @@ -2329,8 +2332,7 @@ class TestProxyFunctionCalling: This test provides documentation on how the proxy server configuration would typically map custom model names to underlying models. """ - print( - """ + print(""" REAL-WORLD PROXY SERVER CONFIGURATION EXAMPLE: =============================================== @@ -2383,8 +2385,7 @@ class TestProxyFunctionCalling: - Consistent request/response format - Enhanced streaming support for function calls - """ - ) + """) # Verify that direct underlying models work as expected bedrock_models = [