fix: Remove redundant format field from LiteLLM content objects

LiteLLM providers can extract the MIME type from the data URI. Removing the separate `format` field avoids redundancy and potential issues with backends that may reject requests containing this field.

Close #2017

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 828014286
This commit is contained in:
George Weale
2025-11-04 09:44:38 -08:00
committed by Copybara-Service
parent 38ea749c9c
commit 489c39db01
2 changed files with 13 additions and 20 deletions
+6 -13
View File
@@ -314,33 +314,28 @@ def _get_content(
):
base64_string = base64.b64encode(part.inline_data.data).decode("utf-8")
data_uri = f"data:{part.inline_data.mime_type};base64,{base64_string}"
# LiteLLM providers extract the MIME type from the data URI; avoid
# passing a separate `format` field that some backends reject.
if part.inline_data.mime_type.startswith("image"):
# Use full MIME type (e.g., "image/png") for providers that validate it
format_type = part.inline_data.mime_type
content_objects.append({
"type": "image_url",
"image_url": {"url": data_uri, "format": format_type},
"image_url": {"url": data_uri},
})
elif part.inline_data.mime_type.startswith("video"):
# Use full MIME type (e.g., "video/mp4") for providers that validate it
format_type = part.inline_data.mime_type
content_objects.append({
"type": "video_url",
"video_url": {"url": data_uri, "format": format_type},
"video_url": {"url": data_uri},
})
elif part.inline_data.mime_type.startswith("audio"):
# Use full MIME type (e.g., "audio/mpeg") for providers that validate it
format_type = part.inline_data.mime_type
content_objects.append({
"type": "audio_url",
"audio_url": {"url": data_uri, "format": format_type},
"audio_url": {"url": data_uri},
})
elif part.inline_data.mime_type == "application/pdf":
format_type = part.inline_data.mime_type
content_objects.append({
"type": "file",
"file": {"file_data": data_uri, "format": format_type},
"file": {"file_data": data_uri},
})
else:
raise ValueError("LiteLlm(BaseLlm) does not support this content part.")
@@ -348,8 +343,6 @@ def _get_content(
file_object: ChatCompletionFileUrlObject = {
"file_id": part.file_data.file_uri,
}
if part.file_data.mime_type:
file_object["format"] = part.file_data.mime_type
content_objects.append({
"type": "file",
"file": file_object,
+7 -7
View File
@@ -1107,7 +1107,7 @@ def test_content_to_message_param_user_message_with_file_uri():
assert message["content"][0]["text"] == "Summarize this file."
assert message["content"][1]["type"] == "file"
assert message["content"][1]["file"]["file_id"] == "gs://bucket/document.pdf"
assert message["content"][1]["file"]["format"] == "application/pdf"
assert "format" not in message["content"][1]["file"]
def test_content_to_message_param_user_message_file_uri_only():
@@ -1126,7 +1126,7 @@ def test_content_to_message_param_user_message_file_uri_only():
assert isinstance(message["content"], list)
assert message["content"][0]["type"] == "file"
assert message["content"][0]["file"]["file_id"] == "gs://bucket/only.pdf"
assert message["content"][0]["file"]["format"] == "application/pdf"
assert "format" not in message["content"][0]["file"]
def test_content_to_message_param_multi_part_function_response():
@@ -1278,7 +1278,7 @@ def test_get_content_image():
content[0]["image_url"]["url"]
== "data:image/png;base64,dGVzdF9pbWFnZV9kYXRh"
)
assert content[0]["image_url"]["format"] == "image/png"
assert "format" not in content[0]["image_url"]
def test_get_content_video():
@@ -1291,7 +1291,7 @@ def test_get_content_video():
content[0]["video_url"]["url"]
== "data:video/mp4;base64,dGVzdF92aWRlb19kYXRh"
)
assert content[0]["video_url"]["format"] == "video/mp4"
assert "format" not in content[0]["video_url"]
def test_get_content_pdf():
@@ -1304,7 +1304,7 @@ def test_get_content_pdf():
content[0]["file"]["file_data"]
== "data:application/pdf;base64,dGVzdF9wZGZfZGF0YQ=="
)
assert content[0]["file"]["format"] == "application/pdf"
assert "format" not in content[0]["file"]
def test_get_content_file_uri():
@@ -1317,7 +1317,7 @@ def test_get_content_file_uri():
content = _get_content(parts)
assert content[0]["type"] == "file"
assert content[0]["file"]["file_id"] == "gs://bucket/document.pdf"
assert content[0]["file"]["format"] == "application/pdf"
assert "format" not in content[0]["file"]
def test_get_content_audio():
@@ -1330,7 +1330,7 @@ def test_get_content_audio():
content[0]["audio_url"]["url"]
== "data:audio/mpeg;base64,dGVzdF9hdWRpb19kYXRh"
)
assert content[0]["audio_url"]["format"] == "audio/mpeg"
assert "format" not in content[0]["audio_url"]
def test_to_litellm_role():