Skip to content

Python: [Bug]: AgentFrameworkAgent(require_confirmation=...) docstring is misleading — it also gates the confirm_changes HITL tool-call emission, not just "predictive updates" #6881

Description

@antsok

Description

In agent-framework-ag-ui, the require_confirmation parameter on AgentFrameworkAgent (and AgentConfig) is documented as:

require_confirmation: Whether predictive updates require user confirmation before applying

However, the actual implementation uses this flag as the master switch that controls whether a synthetic confirm_changes tool call is emitted for function-approval requests (tools with approval_mode="always_require"). This is the mechanism a human-in-the-loop (HITL) frontend (e.g. CopilotKit's useHumanInTheLoop({ name: "confirm_changes" })) relies on to render an approval card.

The docstring makes no mention of tool-approval / HITL, so users reasonably conclude the flag only affects predict_state_config-style predictive state updates. Setting require_confirmation=False silently disables the entire approval UI for gated tools, even though the tool is still gated server-side.

Where the behavior diverges from the docs

AgentConfig.__init__ / AgentFrameworkAgent.__init__ docstring (_agent.py):

require_confirmation: Whether predictive updates require user confirmation before applying

But in _run_common.py, _emit_approval_request(...) uses the same flag to decide whether to emit the confirm_changes tool call:

def _emit_approval_request(content, flow, predictive_handler=None, require_confirmation=True):
    ...
    # Always emitted: ToolCallEnd for the gated call + CustomEvent("function_approval_request") + RUN_FINISHED interrupt
    ...
    if require_confirmation:
        confirm_id = generate_event_id()
        events.append(ToolCallStartEvent(tool_call_id=confirm_id, tool_call_name="confirm_changes", ...))
        events.append(ToolCallArgsEvent(tool_call_id=confirm_id, delta=args_json))
        events.append(ToolCallEndEvent(tool_call_id=confirm_id))
        ...

And it is threaded through _emit_content(...):

if content_type == "function_approval_request":
    return events + _emit_approval_request(content, flow, predictive_handler, require_confirmation)

So for a tool marked approval_mode="always_require":

  • require_confirmation=True → the confirm_changes tool call is emitted → the HITL frontend renders an approval card.
  • require_confirmation=False → no confirm_changes tool call → the frontend never sees an approval prompt; the tool chip is stuck "Running" (only the non-standard CustomEvent / RUN_FINISHED.interrupt are emitted).

Impact

Users who want to disable predictive-state confirmation (per the docstring) but keep tool-approval HITL will inadvertently break their approval UI. Conversely, users troubleshooting a missing approval card have no way to discover from the docs that this flag is the cause.

Code Sample

Error Messages / Stack Traces

Package Versions

agent-framework-ag-ui: 1.0.0rc6

Python Version

Python 3.12

Additional Context

Suggested fix

Update the docstring for require_confirmation in both AgentConfig.__init__ and AgentFrameworkAgent.__init__ to reflect what it actually controls, e.g.:

require_confirmation: When True, function-approval requests (tools with approval_mode="always_require") are surfaced as a synthetic confirm_changes tool call so a human-in-the-loop frontend can render an approval prompt before the tool runs. Also gates confirmation for predictive state updates. When False, no confirm_changes tool call is emitted (only a function_approval_request custom event and a RUN_FINISHED interrupt).

Optionally, consider decoupling the two concerns into separate flags (e.g. require_tool_approval vs. require_predictive_confirmation) since they serve distinct purposes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    pythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowtriageUsage: [Issues], Target: All issues that still need to be triaged

    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