Skip to content

.NET: [BREAKING] Bind tool-approval responses to surfaced approval requests - #7111

Merged
Roger Barreto (rogerbarreto) merged 7 commits into
microsoft:mainfrom
rogerbarreto:rogerbarreto/harden-tool-approval-response-binding
Jul 21, 2026
Merged

Roger Barreto (rogerbarreto) merged 7 commits into
microsoft:mainfrom
rogerbarreto:rogerbarreto/harden-tool-approval-response-binding

Conversation

@rogerbarreto

@rogerbarreto Roger Barreto (rogerbarreto) commented Jul 14, 2026

Copy link
Copy Markdown
Member

Motivation and Context

Tool approvals in the .NET stack are honored from the ToolApprovalResponseContent carried in the message stream. This change hardens that flow so an approved tool call always corresponds to the approval request the framework actually surfaced, keeping the human-in-the-loop control aligned with what a user was asked to approve.

Description

Adds ApprovalResponseBindingChatClient, registered as the outermost decorator above FunctionInvokingChatClient in the default ChatClientAgent pipeline:

  • Outbound: records each model-originated ToolApprovalRequestContent into the session AgentSessionStateBag, keyed by request id.
  • Inbound: binds each ToolApprovalResponseContent to its recorded request, rebinds the response tool call to the recorded call, consumes matched entries for one-time use, and honors only approvals tied to a framework-issued request.
  • Outside an agent run (no session): no-op passthrough with a warning.

Applies the same binding in the ToolApprovalAgent harness by tracking surfaced requests and binding collected responses to them during a queue cycle.

Adds ChatClientAgentOptions.DisableApprovalResponseBinding (default off) and a UseApprovalResponseBinding builder extension for custom chat client stacks. The Foundry hosting path already reconstructs the call from the server-side approval map and is unaffected.

Contribution Checklist

  • Unit tests for the decorator and the harness; full unit suite green
  • dotnet format clean on changed files

Breaking change

Approval-response binding introduces new session state for surfaced/recorded approval requests. A session serialized by an older build while an approval was still outstanding deserializes with this state empty, so its approval responses no longer bind to a request and are ignored on resume. Re-issue the request to obtain a fresh approval.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible .NET Usage: [Issues, PRs], Target: .Net

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants