Python: Add support for function approval flow in Foundry hosted agent#5666
Python: Add support for function approval flow in Foundry hosted agent#5666TaoChenOSU wants to merge 4 commits intomainfrom
Conversation
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
This PR adds a function/tool approval round-trip flow to the Foundry-hosted Responses server by persisting approval requests and resolving mcp_approval_* items back into Agent Framework function_approval_* content when requests return.
Changes:
- Added
ApprovalStorageplus in-memory and file-based implementations, and wired approval persistence intoResponsesHostServermessage/output conversion. - Updated the hosted tools sample to demonstrate
always_requireapproval mode and documented the approval request/response messages. - Expanded/updated unit + HTTP round-trip tests to cover approval storage and conversion paths, and converted relevant conversion tests to async.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| python/samples/04-hosting/foundry-hosted-agents/responses/02_tools/README.md | Documents the tool approval flow and shows example requests/responses. |
| python/samples/04-hosting/foundry-hosted-agents/responses/02_tools/main.py | Switches the run_bash tool to always_require to exercise the approval flow. |
| python/packages/foundry_hosting/tests/test_responses.py | Adds approval storage + conversion + round-trip tests and updates conversion tests for async APIs. |
| python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py | Implements approval storage, resolves mcp_approval_* items via storage, and persists approval requests emitted by the agent. |
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 77%
✓ Correctness
The PR introduces an AprovalStorage mechanism for persisting function approval requests across turns. The implementation is correct for the non-workflow agent path. However, the
_handle_inner_workflowmethod does not passapproval_storageto either_items_to_messagesor_to_outputs, meaning if a workflow agent emits afunction_approval_requestcontent, it will be surfaced to the client as anmcp_approval_requestbut never saved to storage—causing aValueErrorcrash when the client sends back anmcp_approval_response.
✓ Security Reliability
The PR adds approval storage classes (in-memory and file-based) and integrates them into the responses flow. Two reliability concerns: (1) the file-based storage has a TOCTOU race in
_create_storage_file_if_not_exists_syncthat could truncate data written by a concurrent caller, and (2) in_to_outputs, if the infrastructure fails to assign anitem.idto the emitted approval request event, the save is silently skipped with no warning, leading to a confusing KeyError on the subsequent approval response turn.
✓ Test Coverage
The test coverage for the new function approval storage and round-trip flow is comprehensive. Both storage implementations are tested for happy paths and error cases. The conversion functions are tested with and without storage. Full end-to-end round-trip tests cover non-streaming approve/reject flows, streaming persistence, and error handling for unknown IDs. Two minor gaps exist: (1) no test for
_to_outputswhenapproval_storage=Nonewith afunction_approval_requestcontent (verifying events emit but no save occurs), and (2) no streaming two-turn round-trip test verifying the approval response reaches the agent in streaming mode.
✓ Design Approach
I found two design-level issues in the new approval persistence approach. First, hosted approval state is written to a cwd-relative path instead of following the existing hosted checkpoint-storage pattern, so it is not using the same host-managed persisted location that the server already relies on for cross-turn state. Second,
mcp_approval_requestreplay was changed from a stateless reconstruction to an out-of-band storage lookup even though the response item already contains the full request payload; that couples ordinaryprevious_response_idhistory replay to a sidecar file and creates avoidable failure modes when that file is missing or from an older deployment.
Automated review by TaoChenOSU's agents
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 83%
✓ Correctness
The PR adds function approval storage (in-memory and file-based) to persist approval requests so they can be resolved on subsequent turns. The implementation is correct: all referenced Content class methods exist and behave as expected, additional_properties is always a dict (never None), the async/await conversions are consistently applied, and the storage implementations properly handle concurrency within a single process. Tests thoroughly cover the round-trip flow. No correctness issues found.
✓ Security Reliability
The PR introduces a well-structured function approval storage mechanism with atomic file writes, exclusive-create mode, and proper thread safety. The main reliability concern is an ordering issue in the streaming path: approval request events are yielded to the client before the approval request is persisted to storage, creating a window where a save failure leaves the client with an unresolvable approval request ID.
✓ Test Coverage
The test coverage for the new approval storage and round-trip functionality is solid. Tests cover both storage implementations (InMemory and FileBased), conversion functions with and without storage, and end-to-end round-trips for non-streaming flows (approve, reject, unknown ID). The streaming path verifies that approval requests are persisted. Assertions are meaningful—they check specific content types, field values, and the preservation of nested function_call data through serialization. The one notable gap is the absence of a test verifying that
_to_outputssilently skips saving whenapproval_storage=Nonewhile still emitting themcp_approval_requestto the client, which could lead to confusing failures on subsequent turns in the workflow path.
✗ Design Approach
I found two design-level problems in the approval round-trip changes. First, the new implementation makes
mcp_approval_requestreplay depend on side storage even though the request item already carries the full tool-call payload, which turns what should be a stateless history reconstruction path into a brittle file-backed dependency. Second, the workflow-hosted path was not wired into the new storage scheme, so approval responses for workflow agents still cannot be converted back into thefunction_approval_responsecontent thatWorkflowAgentexpects for pending-request continuation.
Automated review by TaoChenOSU's agents
Motivation and Context
Supersede #5537
The current implementation of Foundry Hosting lacks the function approval flow. This PR adds this feature.
Description
When a tool gets invoked but requires approval, agents in Agent Framework will return a
function_approval_requestand expect afunction_approval_response. These two types do not map to any type in the Foundry Hosted Agent layer.This PR maps
function_approval_requestandfunction_approval_responsetomcp_approval_requestandmcp_approval_responserespectively, allowing tools that require approval to work when the agent is hosted.The flow goes like:
function_approval_requestmcp_approval_requestand saves the original request for round trip look up.mcp_approval_responsewith the same ID as the request.Contribution Checklist