From 82cf1bee1721c8cc90b303ab45d2c1e06f0bb2f5 Mon Sep 17 00:00:00 2001 From: Anjan <743179+t-anjan@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:24:14 +0530 Subject: [PATCH 1/3] Fix structured value parsing for split text chunks --- .../packages/core/agent_framework/_types.py | 20 +++++++++++++++-- python/packages/core/tests/core/test_types.py | 22 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/python/packages/core/agent_framework/_types.py b/python/packages/core/agent_framework/_types.py index b947d495822..93d263514f2 100644 --- a/python/packages/core/agent_framework/_types.py +++ b/python/packages/core/agent_framework/_types.py @@ -2135,6 +2135,20 @@ def _parse_structured_response_value(text: str, response_format: Any | None) -> return None +def _message_text_for_structured_response(message: Message) -> str: + return "".join(content.text for content in message.contents if content.type == "text") # type: ignore[misc] + + +def _messages_text_for_structured_response( + messages: Sequence[Message], + *, + separator: str, + strip: bool = False, +) -> str: + text = separator.join(_message_text_for_structured_response(message) for message in messages) + return text.strip() if strip else text + + class ChatResponse(SerializationMixin, Generic[ResponseModelT]): """Represents the response to a chat request. @@ -2407,7 +2421,8 @@ def value(self) -> ResponseModelT | None: if self._value_parsed: return self._value if self._response_format is not None: - self._value = cast(ResponseModelT, _parse_structured_response_value(self.text, self._response_format)) + text = _messages_text_for_structured_response(self.messages, separator="\n", strip=True) + self._value = cast(ResponseModelT, _parse_structured_response_value(text, self._response_format)) self._value_parsed = True return self._value @@ -2671,7 +2686,8 @@ def value(self) -> ResponseModelT | None: if self._value_parsed: return self._value if self._response_format is not None: - self._value = cast(ResponseModelT, _parse_structured_response_value(self.text, self._response_format)) + text = _messages_text_for_structured_response(self.messages, separator="") + self._value = cast(ResponseModelT, _parse_structured_response_value(text, self._response_format)) self._value_parsed = True return self._value diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index edf19b3ff88..e4427e9c2d5 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -834,6 +834,28 @@ 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_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_parse_structured_response_value_empty_text_with_pydantic_model() -> None: """Empty text should return None instead of raising when response_format is a Pydantic model.""" result = _parse_structured_response_value("", OutputModel) From d3a91f443965c860e9886da6cdbe322832a85b59 Mon Sep 17 00:00:00 2001 From: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Date: Wed, 8 Jul 2026 18:44:11 +0900 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- python/packages/core/agent_framework/_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/packages/core/agent_framework/_types.py b/python/packages/core/agent_framework/_types.py index 93d263514f2..f5478fc012e 100644 --- a/python/packages/core/agent_framework/_types.py +++ b/python/packages/core/agent_framework/_types.py @@ -2136,7 +2136,7 @@ def _parse_structured_response_value(text: str, response_format: Any | None) -> def _message_text_for_structured_response(message: Message) -> str: - return "".join(content.text for content in message.contents if content.type == "text") # type: ignore[misc] + return "".join((content.text or "") for content in message.contents if content.type == "text") def _messages_text_for_structured_response( From a5f64d66fe675c666330cb49018fcf2e6241ab9a Mon Sep 17 00:00:00 2001 From: Anjan <743179+t-anjan@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:24:14 +0530 Subject: [PATCH 3/3] Fix structured value parsing for split text chunks --- python/packages/core/tests/core/test_types.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index e4427e9c2d5..c0bb918a355 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -856,6 +856,14 @@ def test_agent_response_value_parses_split_structured_text_without_changing_mess 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_parse_structured_response_value_empty_text_with_pydantic_model() -> None: """Empty text should return None instead of raising when response_format is a Pydantic model.""" result = _parse_structured_response_value("", OutputModel)