Skip to content

Python: fix(ag-ui): clean confirm_changes approval payloads in snapshot#7316

Open
hsusul wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix-python-agui-confirm-changes-snapshot
Open

Python: fix(ag-ui): clean confirm_changes approval payloads in snapshot#7316
hsusul wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix-python-agui-confirm-changes-snapshot

Conversation

@hsusul

@hsusul hsusul commented Jul 25, 2026

Copy link
Copy Markdown

Motivation & Context

In AG-UI, when human-in-the-loop tool execution is approved via the confirm_changes flow (e.g., CopilotKit useHumanInTheLoop), the approval response payload ({"accepted": true}) remains in snapshot_messages because _clean_resolved_approvals_from_snapshot looks up tool results in result_by_call_id using snap_msg.toolCallId. For confirm_changes synthetic tool calls, toolCallId is the confirm_id, which does not match the original tool call ID in result_by_call_id.

As a result, the raw approval JSON payload persists in snapshot_messages and the original tool call result is omitted. On subsequent turns, clients that reconcile UI state from MESSAGES_SNAPSHOT (such as CopilotKit) see an un-resulted tool call and revert the completed tool chip back to "Running" / "in progress".

Description & Review Guide

  • What are the major changes?
    • Updated _clean_resolved_approvals_from_snapshot in agent_framework_ag_ui/_agent_run.py so that when toolCallId does not directly match result_by_call_id (e.g. confirm_changes synthetic approval tool calls), it still cleans the {"accepted": ...} approval payload and replaces it with the executed tool result (or confirmation summary).
    • Added unit test suite in tests/ag_ui/test_confirm_changes_snapshot.py verifying that confirm_changes approval and rejection payloads are cleaned up and replaced with actual tool results in snapshot messages.
  • What is the impact of these changes?
    • Tool chips in AG-UI clients (e.g. CopilotKit) remain in the completed state after human approval rather than reverting to "Running" on subsequent turns.
  • What do you want reviewers to focus on?
    • The fallback logic in _clean_resolved_approvals_from_snapshot for matching synthetic approval tool calls when tool_call_id is not present directly in result_by_call_id.

Related Issue

Fixes #6828

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change.

Copilot AI review requested due to automatic review settings July 25, 2026 04:23
@hsusul
hsusul temporarily deployed to github-app-auth July 25, 2026 04:23 — with GitHub Actions Inactive
@hsusul
hsusul temporarily deployed to github-app-auth July 25, 2026 04:23 — with GitHub Actions Inactive
@hsusul
hsusul temporarily deployed to github-app-auth July 25, 2026 04:23 — with GitHub Actions Inactive
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Jul 25, 2026
@github-actions github-actions Bot changed the title fix(ag-ui): clean confirm_changes approval payloads in snapshot Python: fix(ag-ui): clean confirm_changes approval payloads in snapshot Jul 25, 2026
@hsusul
hsusul temporarily deployed to github-app-auth July 25, 2026 04:23 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes AG-UI’s confirm_changes human-in-the-loop flow so that end-of-turn MESSAGES_SNAPSHOT no longer retains the raw approval payload ({"accepted": ...}) and instead preserves the executed tool result, preventing clients (e.g., CopilotKit) from reverting completed tool chips back to “Running” on subsequent turns.

Changes:

  • Updated _clean_resolved_approvals_from_snapshot to handle confirm_changes synthetic tool call IDs when replacing approval payloads in snapshot tool messages.
  • Added new unit tests to validate snapshot cleaning behavior for confirm_changes approval and rejection cases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py Adjusts snapshot post-processing to replace approval JSON payloads with tool results, including a fallback path for confirm_changes.
python/packages/ag-ui/tests/ag_ui/test_confirm_changes_snapshot.py Adds tests ensuring confirm_changes approval/rejection payloads are cleaned and replaced appropriately in snapshot messages.

Comment on lines +1455 to +1465
if replacement is None:
# For confirm_changes synthetic tool calls, tool_call_id is the confirm_id
# while result_by_call_id is keyed by the original tool call id.
if parsed.get("accepted"):
replacement = (
"\n\n".join(result_by_call_id.values())
if result_by_call_id
else "Changes confirmed and applied successfully."
)
else:
replacement = "Changes declined."
Comment on lines +34 to +38
{
"id": confirm_call_id,
"type": "function",
"function": {"name": "confirm_changes", "arguments": "{}"},
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: AG-UI confirm_changes approval-gated tool reverts to "in progress" after completing

2 participants