mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
fix(anthropic): accept a tool_calls turn without content in count validation
The chat translation merged in #47363 counts an assistant tool_calls turn, but validate_request still rejects that turn when it carries no content key. OpenAI leaves content optional there, and an SDK message dumped with exclude_none drops the key entirely, so a caller going through the config or the handler directly gets a ValueError on a turn every other layer now accepts Treat tool_calls as the content for that check. A turn with neither is still refused Relates to #26324
This commit is contained in:
parent
d18efdfe13
commit
fac1192aa5
2 changed files with 35 additions and 1 deletions
|
|
@ -488,5 +488,5 @@ class AnthropicCountTokensConfig:
|
|||
if "role" not in message:
|
||||
raise ValueError(f"Message {i} must have a 'role' field")
|
||||
|
||||
if "content" not in message:
|
||||
if "content" not in message and "tool_calls" not in message:
|
||||
raise ValueError(f"Message {i} must have a 'content' field")
|
||||
|
|
|
|||
|
|
@ -1019,3 +1019,37 @@ async def test_counter_leaves_out_context_management_without_edits(context_manag
|
|||
ANTHROPIC_BETA_HEADER_VALUES.COMPACT_2026_01_12.value,
|
||||
ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_MANAGEMENT_2025_06_27.value,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("config_type", (AnthropicCountTokensConfig, AzureAIAnthropicCountTokensConfig))
|
||||
def test_validate_request_accepts_a_tool_call_turn_without_content(
|
||||
config_type: type[AnthropicCountTokensConfig],
|
||||
) -> None:
|
||||
"""OpenAI leaves ``content`` optional on an assistant ``tool_calls`` turn, and an SDK dump that drops
|
||||
None values leaves the key out, so the shape the chat translation already counts is not rejected here."""
|
||||
validated: Final = config_type().validate_request(
|
||||
model="claude-opus-5-5",
|
||||
messages=[
|
||||
{"role": "user", "content": "Weather in SF?"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"tool_calls": [
|
||||
{"id": "call-1", "type": "function", "function": {"name": "get_weather", "arguments": "{}"}}
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
assert validated is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("config_type", (AnthropicCountTokensConfig, AzureAIAnthropicCountTokensConfig))
|
||||
def test_validate_request_still_requires_content_on_a_plain_turn(
|
||||
config_type: type[AnthropicCountTokensConfig],
|
||||
) -> None:
|
||||
"""A turn that carries neither content nor tool calls has nothing to count and is still refused."""
|
||||
with pytest.raises(ValueError, match="Message 1 must have a 'content' field"):
|
||||
config_type().validate_request(
|
||||
model="claude-opus-5-5",
|
||||
messages=[{"role": "user", "content": "Weather in SF?"}, {"role": "assistant"}],
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue