-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Python: Fix AG-UI message handling and MCP tool double-call bug #3635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
moonbox3
wants to merge
7
commits into
microsoft:main
Choose a base branch
from
moonbox3:ag-ui-fixes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+734
−51
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Fixes several AG-UI streaming and snapshot edge-cases around tool calling, approvals, and MCP integration to align emitted events/messages with protocol and provider constraints.
Changes:
- Emit
TEXT_MESSAGE_ENDwhen a tool result arrives while a text message context is open. - Rebuild
MESSAGES_SNAPSHOTso tool calls and assistant text appear as separate assistant messages. - Improve robustness around malformed JSON tool arguments and track
confirm_changesin snapshots for UI rendering.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/ag-ui/agent_framework_ag_ui/_run.py | Updates streaming event emission, snapshot construction, confirm flow tracking, and adds post-processing for approval/tool history. |
| python/packages/ag-ui/agent_framework_ag_ui/_message_adapters.py | Adjusts tool-history sanitization to filter confirm_changes and fixes pending tool-call tracking behavior. |
| python/packages/ag-ui/tests/test_run.py | Adds regression tests for message end balancing and snapshots; introduces a malformed-JSON test case. |
| python/packages/ag-ui/tests/test_message_hygiene.py | Updates/extends hygiene tests around confirm_changes filtering and approval-result conversion. |
| python/packages/ag-ui/tests/test_message_adapters.py | Updates expectations/docs for approval-modified arguments behavior (LLM context vs snapshot payload). |
python/packages/ag-ui/agent_framework_ag_ui/_message_adapters.py
Outdated
Show resolved
Hide resolved
eavanvalkenburg
approved these changes
Feb 3, 2026
markwallace-microsoft
approved these changes
Feb 3, 2026
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation and Context
Summary
Description
Issue #3568: TextMessageEndEvent missing after tool results
When a tool-only response was detected, a
TextMessageStartEventwas emitted to create message context, butTextMessageEndEventwas not emitted aftertool results. Fixed by emitting the end event in
_emit_tool_result().Issue #3619: MessagesSnapshot merging tool_calls and content
The AG-UI protocol expects tool_calls and content to be in separate messages within
MessagesSnapshotEvent. The previous implementation merged them intoa single message. Fixed
_build_messages_snapshot()to emit separate messages.JSONDecodeError crash
Malformed JSON in tool arguments could crash the streaming response. Now we skip the confirmation flow with a warning log instead of crashing.
MCP tool double-call bug
Two root causes:
_replace_approval_contents_with_results()placed function_result content in user messages instead of tool messages. OpenAI requires tool results inrole="tool"messages._sanitize_tool_history()didn't remove call_ids from pending tracking after seeing their results, causing duplicate synthetic results.Fixed by:
_convert_approval_results_to_tool_messages()to extract function_result content from user messages into proper tool messagespending_tool_call_ids.discard(call_id)after processing tool resultsconfirm_changes not in MessagesSnapshotEvent
The
confirm_changestool call events were emitted but not tracked inflow.pending_tool_calls, so the frontend couldn't see them in the snapshot torender the confirmation dialog. Fixed by tracking confirm_changes in both
_emit_approval_request()and the predictive tools path.Contribution Checklist