Skip to content

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

Description

@antsok

Description

When a tool is gated by human-in-the-loop approval over AG-UI using the confirm_changes flow (AgentFrameworkAgent(require_confirmation=True), as CopilotKit uses), the tool's executed result is emitted only as a transient TOOL_CALL_RESULT event and is never recorded in flow.tool_results. As a result, the end-of-turn MESSAGES_SNAPSHOT omits the tool-result message.

Clients that reconcile rendered state from MESSAGES_SNAPSHOT (e.g. CopilotKit) then revert the already-completed tool call back to "in progress": the tool chip flips from done → running right after approval, and again on the next turn's snapshot.

Package Versions

agent-framework-core: 1.9.0, agent-framework-ag-ui:1.0.0rc5, agent-framework-ollama:1.0.0b260521, ollama: 0.5.3

Python Version

Python 3.12

Additional Context

Minimal reproduction

MAF advisor exposed over AG-UI (add_agent_framework_fastapi_endpoint, require_confirmation=True) with a tool requiring approval (e.g. the Microsoft Learn MCP with require_approval=True), driven by a CopilotKit useHumanInTheLoop({ name: "confirm_changes" }) client. Ask a question that calls the gated tool, approve it: the tool chip stays "Running" after the result returns, and remains "Running" after the next turn.

Root cause

_make_approval_tool_result_events (agent_framework_ag_ui/_agent_run.py) builds the TOOL_CALL_RESULT event but does not append to flow.tool_results, which is what _build_messages_snapshot uses to attach tool-result messages.

_clean_resolved_approvals_from_snapshot does patch the direct approval_mode flow — there the approval-response tool message is keyed by the original call_id, so it gets replaced with the executed result (covered by test_approval_resume_snapshot_replaces_approval_payload_with_tool_result). It does not cover the confirm_changes flow, where the HITL tool call carries its own id, so the original call's result never lands in the snapshot.

Expected vs actual

  • Expected: after approval, the tool chip shows a completed/result state and stays there across subsequent snapshots.
  • Actual: the chip reverts to "in progress" / "Running" after the tool has already produced its result.

Additional info

Regression-style: the direct approval_mode flow is fine; only the confirm_changes flow is affected. A fix PR follows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ag-uiUsage: [Issues, PRs], Target: AG-UI protocol integrationpythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

    Type

    Fields

    No fields configured for Bug.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions