mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
Merge 6d80592607 into 635085ac14
This commit is contained in:
commit
acf653b8f8
2 changed files with 65 additions and 0 deletions
|
|
@ -636,6 +636,25 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
assistant_message["reasoning_content"] = reasoning_content
|
||||
new_messages.append(assistant_message)
|
||||
|
||||
has_conversational_input = any(m.get("role") != "system" for m in replayable_messages)
|
||||
has_translated_conversation = any(m.get("role") != "system" for m in new_messages)
|
||||
if has_conversational_input and not has_translated_conversation:
|
||||
unrecognized_block_types = sorted(
|
||||
{
|
||||
str(content.get("type"))
|
||||
for message in replayable_messages
|
||||
if message.get("role") != "system" and isinstance(message.get("content"), list)
|
||||
for content in message["content"]
|
||||
if isinstance(content, dict) and content.get("type") is not None
|
||||
}
|
||||
)
|
||||
type_list = ", ".join(json.dumps(block_type) for block_type in unrecognized_block_types) or "unknown"
|
||||
raise litellm.BadRequestError(
|
||||
message=f"Anthropic pass-through: every message's content blocks were of unrecognized types ({type_list}), so translation produced an empty conversation. Refusing to dispatch a request with no messages.",
|
||||
model=model or "",
|
||||
llm_provider="anthropic",
|
||||
)
|
||||
|
||||
return new_messages
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -5167,3 +5167,49 @@ def test_eager_input_streaming_tool_reaches_bedrock_converse_as_beta():
|
|||
|
||||
assert data["additionalModelRequestFields"]["anthropic_beta"] == ["fine-grained-tool-streaming-2025-05-14"]
|
||||
assert data["toolConfig"]["tools"][0]["toolSpec"]["inputSchema"]["json"] == EAGER_INPUT_SCHEMA
|
||||
|
||||
|
||||
def test_translate_anthropic_to_openai_rejects_all_unrecognized_content_blocks():
|
||||
request = {
|
||||
"model": "openai/gpt-4o",
|
||||
"max_tokens": 1024,
|
||||
"messages": [{"role": "user", "content": [{"type": "not_a_real_block", "text": "hello"}]}],
|
||||
}
|
||||
|
||||
with pytest.raises(litellm.BadRequestError, match="not_a_real_block"):
|
||||
LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(request)
|
||||
|
||||
control_chars = {
|
||||
**request,
|
||||
"messages": [{"role": "user", "content": [{"type": "forged\nERROR: injected"}]}],
|
||||
}
|
||||
with pytest.raises(litellm.BadRequestError) as exc_info:
|
||||
LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(control_chars)
|
||||
assert "forged\\nERROR: injected" in str(exc_info.value)
|
||||
assert "forged\nERROR: injected" not in str(exc_info.value)
|
||||
|
||||
with_system = {
|
||||
**request,
|
||||
"messages": [
|
||||
{"role": "system", "content": "keep this"},
|
||||
*request["messages"],
|
||||
],
|
||||
}
|
||||
with pytest.raises(litellm.BadRequestError):
|
||||
LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(with_system)
|
||||
|
||||
mixed = {
|
||||
"model": "openai/gpt-4o",
|
||||
"max_tokens": 1024,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "not_a_real_block", "text": "ignored"},
|
||||
{"type": "text", "text": "hello"},
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
openai_request, _ = LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(mixed)
|
||||
assert openai_request["messages"] == [{"role": "user", "content": [{"type": "text", "text": "hello"}]}]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue