-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Summary
The AG-UI workflow path emits function_approval_request events to the client (via _emit_content → _emit_approval_request), but if the client responds with function_approvals in messages rather than through the resume payload, those responses are silently dropped.
Root Cause
In _workflow_run.py, _extract_responses_from_messages (line ~126-135) only processes function_result content:
if content.type != "function_result" or not content.call_id:
continueThis skips function_approval_response content entirely. Meanwhile, the message adapter (_message_adapters.py) converts incoming function_approvals arrays into function_approval_response Content objects, which then go unprocessed.
Impact
- Functional: A valid approval response sent via
function_approvalsis silently lost. The workflow never receives it. - Not a security issue: No unauthorized tool execution occurs — the response is dropped, not executed. The workflow engine's
AgentExecutor._extract_function_responsesalso validates againstself.pending_requestsat a deeper level.
How it works today
The resume payload path (_resume_to_workflow_responses) is the primary mechanism CopilotKit uses to send responses back, and it works correctly. The gap only manifests if a client sends approval responses via the function_approvals message field instead.
Suggested fix
Either:
- Extend
_extract_responses_from_messagesto also processfunction_approval_responsecontent and map them to workflow responses - Or document that workflow approval responses must use the resume mechanism, not
function_approvals
Option 1 would make the workflow path consistent with how the agent path handles approval responses, reducing client-side confusion about which mechanism to use.