Python: parse structured response value from final message#6383
Python: parse structured response value from final message#6383liuzemei wants to merge 1 commit into
Conversation
Signed-off-by: liuzemei <35027683+liuzemei@users.noreply.github.com>
|
@liuzemei please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR updates structured-output parsing for ChatResponse.value and AgentResponse.value to parse only the final non-empty message (ignoring earlier messages), and adds regression tests for multi-message responses.
Changes:
- Add
_last_non_empty_message_text()helper to select the final non-empty message text. - Update
ChatResponse.value/AgentResponse.valueto parse structured output from the final message only. - Add tests asserting intermediate messages are ignored when parsing structured output.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/core/agent_framework/_types.py | Parse structured output from the last non-empty message instead of concatenated response text. |
| python/packages/core/tests/core/test_types.py | Add tests validating structured parsing ignores intermediate messages for both response types. |
| def _last_non_empty_message_text(messages: Sequence[Message]) -> str: | ||
| for message in reversed(messages): | ||
| text = message.text | ||
| if text.strip(): | ||
| return text | ||
| return "" |
| self._value = cast( | ||
| ResponseModelT, | ||
| _parse_structured_response_value(_last_non_empty_message_text(self.messages), self._response_format), | ||
| ) |
| def test_agent_response_value_parses_final_message_with_response_format() -> None: | ||
| """AgentResponse.value should ignore intermediate messages when parsing structured output.""" | ||
| response = AgentResponse( | ||
| messages=[ | ||
| Message(role="assistant", contents=['{"skill_name": "building-permit-compliance"}']), | ||
| Message(role="assistant", contents=['{"response": "Hello"}']), | ||
| ], | ||
| response_format=OutputModel, | ||
| ) |
Motivation and Context
Fixes #6366.
When an agent response contains intermediate messages and a final structured JSON payload,
AgentResponse.valuecurrently parsesself.text, which concatenates all message text. That can join intermediate tool/context JSON with the final response JSON and causeValidationError/JSONDecodeErrorfrom trailing characters.Description
ChatResponse.valueandAgentResponse.valuefrom the last non-empty message text instead of the public concatenated.textvalue..textbehavior unchanged for callers that want the full concatenated response text.Testing