diff --git a/python/packages/core/agent_framework/_types.py b/python/packages/core/agent_framework/_types.py index a91f320384..edcf981d4d 100644 --- a/python/packages/core/agent_framework/_types.py +++ b/python/packages/core/agent_framework/_types.py @@ -2191,7 +2191,7 @@ def _last_non_empty_assistant_message_text(messages: Sequence[Message]) -> str: for message in reversed(messages): if message.role != "assistant": continue - text = message.text + text = "".join((content.text or "") for content in message.contents if content.type == "text") if text.strip(): return text return "" diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index bb67f936fe..90372f8672 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -884,6 +884,17 @@ def test_chat_response_with_mapping_response_format() -> None: assert response.value["response"] == "Hello" +def test_chat_response_value_parses_split_structured_text_without_changing_message_text() -> None: + """ChatResponse.value should not use Message.text spacing between structured output chunks.""" + message = Message(role="assistant", contents=[Content.from_text('{ "respon'), Content.from_text('se": "Hello" }')]) + response = ChatResponse(messages=message, response_format=OutputModel) + + assert message.text == '{ "respon se": "Hello" }' + assert response.text == '{ "respon se": "Hello" }' + assert response.value is not None + assert response.value.response == "Hello" + + def test_chat_response_value_parses_final_message_with_response_format() -> None: """ChatResponse.value should ignore intermediate messages when parsing structured output.""" response = ChatResponse( @@ -899,6 +910,17 @@ def test_chat_response_value_parses_final_message_with_response_format() -> None assert response.value.response == "Hello" +def test_agent_response_value_parses_split_structured_text_without_changing_message_text() -> None: + """AgentResponse.value should not use Message.text spacing between structured output chunks.""" + message = Message(role="assistant", contents=[Content.from_text('{"response": "Hel'), Content.from_text('lo"}')]) + response = AgentResponse(messages=message, response_format=OutputModel) + + assert message.text == '{"response": "Hel lo"}' + assert response.text == '{"response": "Hel lo"}' + assert response.value is not None + assert response.value.response == "Hello" + + def test_agent_response_value_parses_final_message_with_response_format() -> None: """AgentResponse.value should ignore intermediate messages when parsing structured output.""" response = AgentResponse( @@ -914,6 +936,14 @@ def test_agent_response_value_parses_final_message_with_response_format() -> Non assert response.value.response == "Hello" +def test_chat_response_value_handles_text_content_without_text() -> None: + """ChatResponse.value should ignore text content with no text value.""" + message = Message(role="assistant", contents=[Content.from_dict({"type": "text"})]) + response = ChatResponse(messages=message, response_format=OutputModel) + + assert response.value is None + + def test_agent_response_mapping_value_parses_final_message() -> None: """AgentResponse.value should parse the final message for JSON schema mappings.""" response = AgentResponse(