Description
The Python core function-invocation path currently trusts the function_call embedded in a caller-supplied approved function_approval_response. A response can therefore carry a valid or fabricated approval id while changing the tool name or arguments from the request that the framework surfaced.
Bind approval responses to framework-issued unresolved requests before execution:
- record each surfaced local approval request in session state by request id;
- validate and rebind an inbound response to the recorded tool name and canonical arguments;
- consume matched requests exactly once so approvals cannot be replayed;
- ignore or reject responses that do not match a framework-issued unresolved request;
- preserve the existing hosted boundaries where AG-UI and Foundry hosting already bind against server-side pending approval state;
- document any compatibility behavior for sessions serialized before binding state existed.
This is the Python parity follow-up to .NET PR #7111.
Dependency
Do not start implementation until PR #7345 has merged. It changes the same approval normalization and execution paths; starting earlier would create avoidable conflicts and risk validating against a moving transcript contract.
Context
Raised during review of #7345:
Description
The Python core function-invocation path currently trusts the
function_callembedded in a caller-supplied approvedfunction_approval_response. A response can therefore carry a valid or fabricated approval id while changing the tool name or arguments from the request that the framework surfaced.Bind approval responses to framework-issued unresolved requests before execution:
This is the Python parity follow-up to .NET PR #7111.
Dependency
Do not start implementation until PR #7345 has merged. It changes the same approval normalization and execution paths; starting earlier would create avoidable conflicts and risk validating against a moving transcript contract.
Context
Raised during review of #7345: