From afe8abc768958efc329755de322fff450955eb36 Mon Sep 17 00:00:00 2001 From: Krish Dholakia Date: Fri, 13 Jun 2025 21:22:03 -0700 Subject: [PATCH] Add anthropic 'none' tool choice param support (#11695) * docs(index.md): add stable pip package * fix(anthropic/chat/transformation.py): add 'none' tool choice mapping Allows disabling anthropic tool calling Maintain parity * fix(transformation.py): if tool_choice="none" ignore 'disable_parallel_Tool_use' unsupported param from anthropic - makes sense as the 'none' implies no tool calls are being made --- litellm/llms/anthropic/chat/transformation.py | 6 +++++- litellm/types/llms/anthropic.py | 2 +- .../chat/test_anthropic_chat_transformation.py | 10 ++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index ec3621f3465..44ca229be77 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -157,6 +157,8 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): ) elif tool_choice == "required": _tool_choice = AnthropicMessagesToolChoice(type="any") + elif tool_choice == "none": + _tool_choice = AnthropicMessagesToolChoice(type="none") elif isinstance(tool_choice, dict): _tool_name = tool_choice.get("function", {}).get("name") _tool_choice = AnthropicMessagesToolChoice(type="tool") @@ -166,7 +168,9 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): if parallel_tool_use is not None: # Anthropic uses 'disable_parallel_tool_use' flag to determine if parallel tool use is allowed # this is the inverse of the openai flag. - if _tool_choice is not None: + if tool_choice == "none": + pass + elif _tool_choice is not None: _tool_choice["disable_parallel_tool_use"] = not parallel_tool_use else: # use anthropic defaults and make sure to send the disable_parallel_tool_use flag _tool_choice = AnthropicMessagesToolChoice( diff --git a/litellm/types/llms/anthropic.py b/litellm/types/llms/anthropic.py index c503240928f..457e3b658ba 100644 --- a/litellm/types/llms/anthropic.py +++ b/litellm/types/llms/anthropic.py @@ -7,7 +7,7 @@ from .openai import ChatCompletionCachedContent, ChatCompletionThinkingBlock class AnthropicMessagesToolChoice(TypedDict, total=False): - type: Required[Literal["auto", "any", "tool"]] + type: Required[Literal["auto", "any", "tool", "none"]] name: str disable_parallel_tool_use: bool # default is false diff --git a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py index eaa118f33a3..58b1243d3ae 100644 --- a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -209,6 +209,15 @@ def test_add_code_execution_tool(): assert tools[0]["type"] == "code_execution_20250522" +def test_map_tool_choice(): + config = AnthropicConfig() + + tool_choice = "none" + result = config._map_tool_choice(tool_choice=tool_choice, parallel_tool_use=True) + assert result is not None + assert result["type"] == "none" + print(result) + def test_transform_response_with_prefix_prompt(): import httpx @@ -252,3 +261,4 @@ def test_transform_response_with_prefix_prompt(): result.choices[0].message.content == "You are a helpful assistant. The grass is green." ) +