diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index 795fb36961e..84b89a52ea4 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -2393,6 +2393,28 @@ def anthropic_messages_pt( "url": image_url_value["url"], "format": image_url_value.get("format"), } + url_str = ( + image_url_value.get("url") if isinstance(image_url_value, dict) else image_url_value + ) + if isinstance(url_str, str) and _is_anthropic_document_data_uri(url_str): # pyright: ignore[reportUnnecessaryIsInstance] # malformed payloads can carry a non-str url + image_chunk = convert_to_anthropic_image_obj( + openai_image_url=url_str, + format=None, + ) + _document_content_element = AnthropicMessagesDocumentParam( + type="document", + source=AnthropicContentParamSource( + type="base64", + media_type=image_chunk["media_type"], + data=image_chunk["data"], + ), + ) + add_cache_control_to_content( + anthropic_content_element=_document_content_element, + original_content_element=m, # pyright: ignore[reportArgumentType] # cache_control lives on the block + ) + user_content.append(_document_content_element) + continue # Bedrock invoke models have format: invoke/... # Vertex AI Anthropic also doesn't support URL sources for images is_bedrock_invoke = model.lower().startswith("invoke/") diff --git a/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py b/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py index 72d26f31c60..5ed81232c45 100644 --- a/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py +++ b/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py @@ -2164,6 +2164,34 @@ def test_anthropic_messages_pt_file_block_without_cache_control(): assert "cache_control" not in file_block +def test_anthropic_messages_pt_maps_pdf_data_uri_to_document_block(): + messages = [ + { + "role": "user", + "content": [ + { + "type": "image_url", + "image_url": {"url": "data:application/pdf;base64,AAAA"}, + } + ], + } + ] + + result = anthropic_messages_pt( + messages=messages, + model="claude-sonnet-4-5", + llm_provider="anthropic", + ) + + document = result[0]["content"][0] + assert document["type"] == "document" + assert document["source"] == { + "type": "base64", + "media_type": "application/pdf", + "data": "AAAA", + } + + # ── _convert_to_bedrock_tool_call_invoke tests ──