fix: Handle HTTP/HTTPS URLs for media files in LiteLLM content conversion

For providers that typically require file IDs (like OpenAI and Azure), if a file URI is an HTTP/HTTPS URL and the MIME type is image, video, or audio, convert it to the corresponding URL-based content type (e.g., "image_url") instead of using the generic "file" type

Close #4112

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 863311703
This commit is contained in:
George Weale
2026-01-30 11:02:29 -08:00
committed by Copybara-Service
parent 2ac468ea7e
commit 47221cd5c1
2 changed files with 160 additions and 32 deletions
+96
View File
@@ -2330,6 +2330,55 @@ async def test_get_content_file_uri_file_id_required_falls_back_to_text(
]
@pytest.mark.asyncio
@pytest.mark.parametrize(
"provider,model",
[
("openai", "openai/gpt-4o"),
("azure", "azure/gpt-4"),
],
)
@pytest.mark.parametrize(
"file_uri,mime_type,expected_type",
[
pytest.param(
"https://example.com/image.png",
"image/png",
"image_url",
id="image",
),
pytest.param(
"https://example.com/video.mp4",
"video/mp4",
"video_url",
id="video",
),
pytest.param(
"https://example.com/audio.mp3",
"audio/mpeg",
"audio_url",
id="audio",
),
],
)
async def test_get_content_file_uri_media_url_file_id_required_uses_url_type(
provider, model, file_uri, mime_type, expected_type
):
parts = [
types.Part(
file_data=types.FileData(
file_uri=file_uri,
mime_type=mime_type,
)
)
]
content = await _get_content(parts, provider=provider, model=model)
assert content == [{
"type": expected_type,
expected_type: {"url": file_uri},
}]
@pytest.mark.asyncio
@pytest.mark.parametrize(
"provider,model",
@@ -2353,6 +2402,53 @@ async def test_get_content_file_uri_file_id_required_preserves_file_id(
assert content == [{"type": "file", "file": {"file_id": "file-abc123"}}]
@pytest.mark.asyncio
@pytest.mark.parametrize(
"provider,model",
[
("openai", "openai/gpt-4o"),
("azure", "azure/gpt-4"),
],
)
async def test_get_content_file_uri_http_pdf_file_id_required_falls_back_to_text(
provider, model
):
file_uri = "https://example.com/document.pdf"
parts = [
types.Part(
file_data=types.FileData(
file_uri=file_uri,
mime_type="application/pdf",
display_name="document.pdf",
)
)
]
content = await _get_content(parts, provider=provider, model=model)
assert content == [
{"type": "text", "text": '[File reference: "document.pdf"]'}
]
@pytest.mark.asyncio
async def test_get_content_file_uri_http_pdf_non_file_id_provider_uses_file():
file_uri = "https://example.com/document.pdf"
parts = [
types.Part(
file_data=types.FileData(
file_uri=file_uri,
mime_type="application/pdf",
)
)
]
content = await _get_content(
parts, provider="vertex_ai", model="vertex_ai/gemini-2.5-flash"
)
assert content == [{
"type": "file",
"file": {"file_id": file_uri, "format": "application/pdf"},
}]
@pytest.mark.asyncio
async def test_get_content_file_uri_anthropic_falls_back_to_text():
parts = [