fix(responses): preserve explicit media formats on lts

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
mateo 2026-11-12 13:54:26 +00:00
parent 6a6d974c68
commit ac7ad3ff7b
2 changed files with 68 additions and 0 deletions

View file

@ -2259,6 +2259,9 @@ class LiteLLMCompletionResponsesConfig:
file_dict["file_data"] = item["file_data"]
if item.get("filename"):
file_dict["filename"] = item["filename"]
media_format: Final = item.get("format")
if media_format is not None:
file_dict["format"] = media_format
bucket_owner: Final = item.get("bucket_owner")
if bucket_owner is not None and _is_s3_url(file_id or item.get("file_data")):
file_dict["bucket_owner"] = bucket_owner
@ -2283,6 +2286,9 @@ class LiteLLMCompletionResponsesConfig:
if bucket_owner is not None and _is_s3_url(url)
else ChatCompletionImageUrlObject(url=url, detail=detail)
)
media_format: Final = item.get("format")
if media_format is not None:
image_url_obj["format"] = media_format
return ChatCompletionImageObject(type="image_url", image_url=image_url_obj)

View file

@ -44,6 +44,68 @@ from litellm.types.utils import (
class TestLiteLLMCompletionResponsesConfig:
@pytest.mark.parametrize("part_type", ["input_image", "input_file"])
@pytest.mark.parametrize(
("key", "media_format", "expected_format"),
[("key", "image/png", "png"), ("key.jpeg", "image/png", "png"), ("key.png", None, "png")],
)
def test_explicit_responses_media_format_reaches_the_converse_s3_image(
self, part_type: str, key: str, media_format: str | None, expected_format: str
) -> None:
uri: Final = f"s3://bucket/{key}"
messages: Final = LiteLLMCompletionResponsesConfig.transform_responses_api_input_to_messages(
input=[
{
"role": "user",
"content": [
{
"type": part_type,
"image_url" if part_type == "input_image" else "file_id": uri,
**({"format": media_format} if media_format is not None else {}),
}
],
}
],
responses_api_request={},
)
request: Final = litellm.AmazonConverseConfig()._transform_request(
model="us.amazon.nova-2-lite-v1:0",
messages=messages,
optional_params={},
litellm_params={},
headers={},
)
assert request["messages"] == [
{
"role": "user",
"content": [{"image": {"format": expected_format, "source": {"s3Location": {"uri": uri}}}}],
}
]
@pytest.mark.parametrize("part_type", ["input_image", "input_file"])
def test_extensionless_responses_s3_media_without_format_is_a_bad_request(self, part_type: str) -> None:
messages: Final = LiteLLMCompletionResponsesConfig.transform_responses_api_input_to_messages(
input=[
{
"role": "user",
"content": [
{"type": part_type, "image_url" if part_type == "input_image" else "file_id": "s3://bucket/key"}
],
}
],
responses_api_request={},
)
with pytest.raises(litellm.BadRequestError, match="Cannot tell the media type"):
litellm.AmazonConverseConfig()._transform_request(
model="us.amazon.nova-2-lite-v1:0",
messages=messages,
optional_params={},
litellm_params={},
headers={},
)
def test_transform_input_file_item_to_file_item_with_file_id(self):
"""Test transformation of input_file item with file_id to Chat Completion file format"""
# Setup