fix: map Chat Completion file type to Responses API input_file#23618
Conversation
When bridging /chat/completions to the Responses API, content items with
type 'file' were falling through to the default handler and being
stringified as input_text. This caused the model to receive the Python
dict representation as plain text instead of the actual file content.
Add explicit handling for type 'file' that correctly maps:
{"type": "file", "file": {"file_data": "...", "filename": "..."}}
to:
{"type": "input_file", "file_data": "...", "filename": "..."}
Fixes BerriAI#23588
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
Greptile SummaryThis PR fixes a bug where Chat Completion messages containing Key changes:
Notable pre-existing gaps (flagged in earlier review threads, not introduced by this PR):
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| litellm/completion_extras/litellm_responses_transformation/transformation.py | Adds explicit elif item_type == "file" branch in _convert_content_to_responses_format to map Chat Completion file items to Responses API input_file format, correctly flattening the nested file dict. Also contains cosmetic formatting-only changes to other parts of the file. |
| tests/test_litellm/completion_extras/litellm_responses_transformation/test_completion_extras_litellm_responses_transformation_transformation.py | Adds two mock-only unit tests verifying the new file → input_file conversion: one for the file_data+filename variant and one for the file_id variant. No real network calls; tests are correctly placed in the mock-only test folder. |
Sequence Diagram
sequenceDiagram
participant Caller as Caller (/chat/completions)
participant FwdTransform as LiteLLMResponsesTransformationHandler<br/>_convert_content_to_responses_format
participant ResponsesAPI as Responses API
participant RevTransform as LiteLLMCompletionResponsesConfig<br/>_transform_input_file_item_to_file_item
Caller->>FwdTransform: {type: "file", file: {file_data: "...", filename: "test.pdf"}}
Note over FwdTransform: NEW: elif item_type == "file"<br/>Extract file_id/file_data/filename from nested file dict
FwdTransform->>ResponsesAPI: {type: "input_file", file_data: "...", filename: "test.pdf"}
ResponsesAPI-->>RevTransform: {type: "input_file", file_data: "...", filename: "test.pdf"}
Note over RevTransform: keys = ["file_id", "file_data"]<br/>⚠ "filename" is NOT in keys list (pre-existing gap)
RevTransform-->>Caller: {type: "file", file: {file_data: "..."}}
Note over Caller: ⚠ filename is silently dropped on round-trip
Last reviewed commit: 98890e7
501ddb4
into
BerriAI:litellm_oss_staging_03_17_2026
Summary
Fixes #23588
When bridging
/chat/completionsto the Responses API, content items withtype: "file"were falling through to the default handler in_convert_content_to_responses_formatand being stringified asinput_text. This caused the model to receive the Python dict representation as plain text instead of the actual file bytes.Root cause: In
litellm/completion_extras/litellm_responses_transformation/transformation.py, the_convert_content_to_responses_formatmethod handles"text","image_url", and"image"content types explicitly, but"file"was not handled — it fell through to theelsebranch which callsstr(item)and wraps it asinput_text.Fix: Add an explicit
elif item_type == "file"branch that maps:to:
This is the inverse of the existing
_transform_input_file_item_to_file_itemin the responses-to-completion direction, which already correctly mapsinput_file→file.Test plan
test_convert_chat_completion_file_type_to_input_file— verifiesfile_dataandfilenameare correctly extractedtest_convert_chat_completion_file_type_with_file_id— verifiesfile_idvariant works🤖 Generated with Claude Code