mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Fix function_approval_response extraction in AG-UI workflow path (#4550)
* Extract function_approval_response from workflow messages (#4546) _extract_responses_from_messages now handles function_approval_response content in addition to function_result content. Previously, approval responses sent via the messages field were silently dropped because the function only checked for content.type == "function_result". The approval response is keyed by content.id and includes the approved status, id, and serialized function_call — consistent with how _coerce_content identifies approval response payloads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply pre-commit auto-fixes * Fix #4546: Update docstring and add integration tests for message-based approvals - Update _extract_responses_from_messages docstring to reflect that it now handles function_approval_response content in addition to function_result content. - Add integration tests for run_workflow_stream across two turns with approval responses provided via messages (function_approvals) rather than resume.interrupts, covering both approved and denied scenarios. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback for #4546 - Use safer 'not .get("interrupt")' assertion instead of 'not in' to handle Pydantic v2 model_dump() including keys with None values - Add unit test for mixed function_result and function_approval_response in the same message to TestExtractResponsesFromMessages Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -124,14 +124,28 @@ def _request_payload_from_request_event(request_event: Any) -> dict[str, Any] |
|
||||
|
||||
|
||||
def _extract_responses_from_messages(messages: list[Message]) -> dict[str, Any]:
|
||||
"""Extract request-info responses from incoming tool/function-result messages."""
|
||||
"""Extract request-info responses from incoming messages.
|
||||
|
||||
Handles both ``function_result`` content (keyed by ``call_id``) and
|
||||
``function_approval_response`` content (keyed by ``id``), so that
|
||||
approval decisions sent via messages are forwarded into the workflow
|
||||
responses map.
|
||||
"""
|
||||
responses: dict[str, Any] = {}
|
||||
for message in messages:
|
||||
for content in message.contents:
|
||||
if content.type != "function_result" or not content.call_id:
|
||||
continue
|
||||
value = _coerce_json_value(content.result)
|
||||
responses[str(content.call_id)] = value
|
||||
if content.type == "function_result" and content.call_id:
|
||||
value = _coerce_json_value(content.result)
|
||||
responses[str(content.call_id)] = value
|
||||
elif content.type == "function_approval_response" and getattr(content, "id", None):
|
||||
approval_value: dict[str, Any] = {
|
||||
"approved": getattr(content, "approved", False),
|
||||
"id": str(content.id), # type: ignore[union-attr]
|
||||
}
|
||||
func_call = getattr(content, "function_call", None)
|
||||
if func_call is not None:
|
||||
approval_value["function_call"] = make_json_safe(func_call.to_dict())
|
||||
responses[str(content.id)] = approval_value # type: ignore[union-attr]
|
||||
return responses
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user