Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion libs/core/langchain_core/messages/block_translators/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ def convert_to_openai_data_block(
if block.get("source_type") == "base64" or "base64" in block:
# Handle v0 format (Base64CB): {"source_type": "base64", "data": "...", ...}
# Handle v1 format (IDCB): {"base64": "...", ...}
if (
api == "chat/completions"
and block.get("mime_type") != "application/pdf"
):
error_msg = (
"OpenAI Chat Completions only supports application/pdf for "
"file data blocks. Use Responses API for other file MIME types."
)
raise ValueError(error_msg)
base64_data = block["data"] if "source_type" in block else block["base64"]
file = {"file_data": f"data:{block['mime_type']};base64,{base64_data}"}
if filename := block.get("filename"):
Expand Down Expand Up @@ -548,7 +557,7 @@ def _extract_extras(
filename = block["file"].get("filename")
return types.create_file_block(
base64=parsed["data"],
mime_type="application/pdf",
mime_type=parsed["mime_type"],
filename=filename,
**all_extras,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,16 @@ def test_convert_to_openai_data_block() -> None:
result = convert_to_openai_data_block(block)
assert result == expected

# File / base64 with non-PDF MIME (chat/completions)
block = {
"type": "file",
"base64": "<base64 string>",
"mime_type": "text/csv",
"filename": "test.csv",
}
with pytest.raises(ValueError, match="only supports application/pdf"):
convert_to_openai_data_block(block)

# Image / base64
block = {
"type": "image",
Expand Down Expand Up @@ -603,3 +613,39 @@ def test_convert_to_openai_data_block() -> None:
expected = {"type": "input_file", "file_id": "file-abc123"}
result = convert_to_openai_data_block(block, api="responses")
assert result == expected


def test_convert_to_v1_file_block_preserves_non_pdf_mime_type() -> None:
message = HumanMessage(
content=[
{
"type": "file",
"file": {
"filename": "sheet.csv",
"file_data": "data:text/csv;base64,aGVsbG8=",
},
},
{
"type": "file",
"file": {
"file_data": "data:text/plain;base64,aGVsbG8=",
},
},
]
)

expected: list[types.ContentBlock] = [
{
"type": "file",
"base64": "aGVsbG8=",
"mime_type": "text/csv",
"extras": {"filename": "sheet.csv"},
},
{
"type": "file",
"base64": "aGVsbG8=",
"mime_type": "text/plain",
},
]

assert _content_blocks_equal_ignore_id(message.content_blocks, expected)
Loading