From 6105a5841b2475c0bdd1f01311ca6e1ab252c99c Mon Sep 17 00:00:00 2001 From: Mikhail <6589665+mshavliuk@users.noreply.github.com> Date: Sat, 21 Jun 2025 02:21:50 +0300 Subject: [PATCH] core: fix `get_buffer_string` output for structured message content (#31600) --- libs/core/langchain_core/messages/utils.py | 2 +- .../tests/unit_tests/messages/test_utils.py | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index adad9c9b6ac..be91d95d597 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -129,7 +129,7 @@ def get_buffer_string( else: msg = f"Got unsupported message type: {m}" raise ValueError(msg) # noqa: TRY004 - message = f"{role}: {m.content}" + message = f"{role}: {m.text()}" if isinstance(m, AIMessage) and "function_call" in m.additional_kwargs: message += f"{m.additional_kwargs['function_call']}" string_messages.append(message) diff --git a/libs/core/tests/unit_tests/messages/test_utils.py b/libs/core/tests/unit_tests/messages/test_utils.py index f7201ca48a9..a02d58b0991 100644 --- a/libs/core/tests/unit_tests/messages/test_utils.py +++ b/libs/core/tests/unit_tests/messages/test_utils.py @@ -21,6 +21,7 @@ from langchain_core.messages.utils import ( convert_to_openai_messages, count_tokens_approximately, filter_messages, + get_buffer_string, merge_message_runs, trim_messages, ) @@ -1395,3 +1396,64 @@ def test_count_tokens_approximately_mixed_content_types() -> None: # Ensure that count is consistent if we do one message at a time assert sum(count_tokens_approximately([m]) for m in messages) == token_count + + +def test_get_buffer_string_with_structured_content() -> None: + """Test get_buffer_string with structured content in messages.""" + messages = [ + HumanMessage(content=[{"type": "text", "text": "Hello, world!"}]), + AIMessage(content=[{"type": "text", "text": "Hi there!"}]), + SystemMessage(content=[{"type": "text", "text": "System message"}]), + ] + expected = "Human: Hello, world!\nAI: Hi there!\nSystem: System message" + actual = get_buffer_string(messages) + assert actual == expected + + +def test_get_buffer_string_with_mixed_content() -> None: + """Test get_buffer_string with mixed content types in messages.""" + messages = [ + HumanMessage(content="Simple text"), + AIMessage(content=[{"type": "text", "text": "Structured text"}]), + SystemMessage(content=[{"type": "text", "text": "Another structured text"}]), + ] + expected = ( + "Human: Simple text\nAI: Structured text\nSystem: Another structured text" + ) + actual = get_buffer_string(messages) + assert actual == expected + + +def test_get_buffer_string_with_function_call() -> None: + """Test get_buffer_string with function call in additional_kwargs.""" + messages = [ + HumanMessage(content="Hello"), + AIMessage( + content="Hi", + additional_kwargs={ + "function_call": { + "name": "test_function", + "arguments": '{"arg": "value"}', + } + }, + ), + ] + # TODO: consider changing this + expected = ( + "Human: Hello\n" + "AI: Hi{'name': 'test_function', 'arguments': '{\"arg\": \"value\"}'}" + ) + actual = get_buffer_string(messages) + assert actual == expected + + +def test_get_buffer_string_with_empty_content() -> None: + """Test get_buffer_string with empty content in messages.""" + messages = [ + HumanMessage(content=[]), + AIMessage(content=""), + SystemMessage(content=[]), + ] + expected = "Human: \nAI: \nSystem: " + actual = get_buffer_string(messages) + assert actual == expected