mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-03 07:23:33 +00:00
fix(anthropic-messages): map tool_choice.disable_parallel_tool_use to parallel_tool_calls=false on the chat and responses adapters
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
f6d2f2098c
commit
2b77493e32
4 changed files with 51 additions and 6 deletions
|
|
@ -1101,9 +1101,10 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
tool_choice: Final = anthropic_message_request["tool_choice"]
|
||||
if not tool_choice:
|
||||
return
|
||||
new_kwargs["tool_choice"] = self.translate_anthropic_tool_choice_to_openai(
|
||||
tool_choice=cast(AnthropicMessagesToolChoice, tool_choice)
|
||||
)
|
||||
anthropic_tool_choice: Final = cast(AnthropicMessagesToolChoice, tool_choice)
|
||||
new_kwargs["tool_choice"] = self.translate_anthropic_tool_choice_to_openai(tool_choice=anthropic_tool_choice)
|
||||
if anthropic_tool_choice.get("disable_parallel_tool_use") is True:
|
||||
new_kwargs["parallel_tool_calls"] = False # rebind-ok: out-param store like tool_choice above
|
||||
|
||||
def _translate_stop_sequences_to_openai(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -656,9 +656,10 @@ class LiteLLMAnthropicToResponsesAPIAdapter:
|
|||
# tool_choice
|
||||
tool_choice: Final = anthropic_request.get("tool_choice")
|
||||
if tool_choice:
|
||||
responses_kwargs["tool_choice"] = self.translate_tool_choice_to_responses_api(
|
||||
cast(AnthropicMessagesToolChoice, tool_choice)
|
||||
)
|
||||
anthropic_tool_choice: Final = cast(AnthropicMessagesToolChoice, tool_choice)
|
||||
responses_kwargs["tool_choice"] = self.translate_tool_choice_to_responses_api(anthropic_tool_choice)
|
||||
if anthropic_tool_choice.get("disable_parallel_tool_use") is True:
|
||||
responses_kwargs["parallel_tool_calls"] = False
|
||||
|
||||
# thinking -> reasoning
|
||||
thinking: Final = anthropic_request.get("thinking")
|
||||
|
|
|
|||
|
|
@ -5527,3 +5527,30 @@ async def test_chat_bridge_tool_result_text_block_without_text_reaches_the_model
|
|||
],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("tool_choice", "expected_parallel_tool_calls"),
|
||||
[
|
||||
({"type": "auto", "disable_parallel_tool_use": True}, False),
|
||||
({"type": "any", "disable_parallel_tool_use": True}, False),
|
||||
({"type": "auto", "disable_parallel_tool_use": False}, None),
|
||||
({"type": "auto"}, None),
|
||||
],
|
||||
)
|
||||
def test_translate_anthropic_to_openai_disable_parallel_tool_use_sets_parallel_tool_calls(
|
||||
tool_choice: dict[str, object], expected_parallel_tool_calls: bool | None
|
||||
) -> None:
|
||||
from litellm.types.llms.anthropic import AnthropicMessagesRequest
|
||||
|
||||
request: Final = AnthropicMessagesRequest(
|
||||
model="gpt-5.4",
|
||||
max_tokens=64,
|
||||
messages=[{"role": "user", "content": "What is the weather in Paris?"}],
|
||||
tools=[{"name": "lookup_weather", "input_schema": {"type": "object", "properties": {}}}],
|
||||
tool_choice=tool_choice,
|
||||
)
|
||||
|
||||
translated, _ = LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(request)
|
||||
|
||||
assert translated.get("parallel_tool_calls") == expected_parallel_tool_calls
|
||||
|
|
|
|||
|
|
@ -1178,6 +1178,22 @@ class TestTranslateRequestBroaderCoverage:
|
|||
kwargs = _ADAPTER.translate_request(req)
|
||||
assert kwargs["tool_choice"] == {"type": "function", "name": "do_thing"}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("tool_choice", "expected_parallel_tool_calls"),
|
||||
[
|
||||
({"type": "auto", "disable_parallel_tool_use": True}, False),
|
||||
({"type": "any", "disable_parallel_tool_use": True}, False),
|
||||
({"type": "auto", "disable_parallel_tool_use": False}, None),
|
||||
({"type": "auto"}, None),
|
||||
],
|
||||
)
|
||||
def test_disable_parallel_tool_use_sets_parallel_tool_calls(
|
||||
self, tool_choice: dict[str, object], expected_parallel_tool_calls: bool | None
|
||||
):
|
||||
req = _make_request(tools=[{"name": "do_thing"}], tool_choice=tool_choice)
|
||||
kwargs = _ADAPTER.translate_request(req)
|
||||
assert kwargs.get("parallel_tool_calls") == expected_parallel_tool_calls
|
||||
|
||||
def test_thinking_translated_to_reasoning(self):
|
||||
req = _make_request(thinking={"type": "enabled", "budget_tokens": 12000})
|
||||
kwargs = _ADAPTER.translate_request(req)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue