From 66d1ed6099d6b5615eddbb79676edfafb357ff0f Mon Sep 17 00:00:00 2001 From: Jacob Lee Date: Wed, 7 May 2025 07:57:37 -0700 Subject: [PATCH] fix(core): Permit OpenAI style blocks to be passed into convert_to_openai_messages (#31140) Should effectively be a noop, just shouldn't throw CC @madams0013 --------- Co-authored-by: ccurme --- libs/core/langchain_core/messages/utils.py | 18 ++++++++++++++++++ .../tests/unit_tests/messages/test_utils.py | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index d3e27c502a4..5b51f63c09d 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -1139,6 +1139,24 @@ def convert_to_openai_messages( f"content block:\n\n{block}" ) raise ValueError(err) + # OpenAI file format + elif ( + block.get("type") == "file" + and isinstance(block.get("file"), dict) + and isinstance(block.get("file", {}).get("file_data"), str) + ): + if block.get("file", {}).get("filename") is None: + logger.info("Generating a fallback filename.") + block["file"]["filename"] = "LC_AUTOGENERATED" + content.append(block) + # OpenAI audio format + elif ( + block.get("type") == "input_audio" + and isinstance(block.get("input_audio"), dict) + and isinstance(block.get("input_audio", {}).get("data"), str) + and isinstance(block.get("input_audio", {}).get("format"), str) + ): + content.append(block) elif block.get("type") == "tool_use": if missing := [ k for k in ("id", "name", "input") if k not in block diff --git a/libs/core/tests/unit_tests/messages/test_utils.py b/libs/core/tests/unit_tests/messages/test_utils.py index db75921e1a3..218f94dc2e8 100644 --- a/libs/core/tests/unit_tests/messages/test_utils.py +++ b/libs/core/tests/unit_tests/messages/test_utils.py @@ -1209,6 +1209,13 @@ def test_convert_to_openai_messages_multimodal() -> None: "mime_type": "application/pdf", "filename": "test.pdf", }, + { + "type": "file", + "file": { + "filename": "draconomicon.pdf", + "file_data": "data:application/pdf;base64,", + }, + }, { "type": "file", "source_type": "id", @@ -1220,13 +1227,20 @@ def test_convert_to_openai_messages_multimodal() -> None: "data": "", "mime_type": "audio/wav", }, + { + "type": "input_audio", + "input_audio": { + "data": "", + "format": "wav", + }, + }, ] ) ] result = convert_to_openai_messages(messages, text_format="block") assert len(result) == 1 message = result[0] - assert len(message["content"]) == 6 + assert len(message["content"]) == 8 # Test adding filename messages = [