Repository navigation
Description
Summary
The Using function tools with human-in-the-loop approvals doc documents always-require / never-require approval, but not conditional (argument-based) approval, which is a shipped Agent Framework capability. The C# zone should add a section covering it.
Source file:
agent-framework/agents/tools/tool-approval.md(inMicrosoftDocs/semantic-kernel-pr).
What's missing
Conditional approval lets you auto-approve some calls to an approval-required tool based on their arguments (e.g., auto-approve transfers under $1,000 but prompt for larger ones), rather than the binary always/never on ApprovalRequiredAIFunction.
The C# API (shipped in Microsoft.Agents.AI 1.15.0, from agent-framework#6335, closes #6083):
- Wrap the tool in
ApprovalRequiredAIFunctionas usual, then layerAIAgentBuilder.UseToolApproval(new ToolApprovalAgentOptions { AutoApprovalRules = [...] }). - Each rule receives a
ToolAutoApprovalRuleContextexposing the pendingFunctionCallContent(tool name and arguments) and returnstrueto auto-approve orfalseto keep evaluating. Rules run after standing "always approve" decisions but before prompting; the firsttrueapproves the call. A call no rule approves raises the usual approval interrupt.
Suggested example (verified end-to-end)
using System.Text.Json;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AITool transfer = new ApprovalRequiredAIFunction(AIFunctionFactory.Create(
TransferFunds, name: "transfer_funds", description: "Transfer money to another account."));
AIAgent baseAgent = chatClient.AsAIAgent(new ChatClientAgentOptions
{
Name = "BankingAgent",
ChatOptions = new ChatOptions
{
Instructions = "You are a banking assistant. Use transfer_funds to move money.",
Tools = [transfer]
}
});
// Auto-approve transfers under $1,000 based on the tool call's arguments; larger
// transfers fall through to a human approval prompt.
static ValueTask<bool> AutoApproveSmallTransfers(ToolAutoApprovalRuleContext context)
{
if (context.FunctionCallContent.Name == "transfer_funds" &&
context.FunctionCallContent.Arguments is { } arguments &&
arguments.TryGetValue("amount", out object? value) && value is not null)
{
decimal amount = value is JsonElement json ? json.GetDecimal() : Convert.ToDecimal(value);
return ValueTask.FromResult(amount < 1000m);
}
return ValueTask.FromResult(false);
}
AIAgent agent = new AIAgentBuilder(baseAgent)
.UseToolApproval(new ToolApprovalAgentOptions { AutoApprovalRules = [AutoApproveSmallTransfers] })
.Build();A $500 transfer is auto-approved and runs to completion; a $5,000 transfer raises the approval interrupt for a human to confirm — from a single tool registration. (Verified end-to-end against GitHub Models, including over an AG-UI endpoint.)
Security note to include: auto-approval rules can match a tool call by name alone, so a rule should be scoped to the tool name and the specific arguments, and no unrelated tool should share a name a rule approves.
Why now / context
While updating the AG-UI C# docs (PR #430), we initially documented conditional approval in the AG-UI human-in-the-loop page. On review, tool approval (including selective and conditional) is a general Agent Framework capability, not AG-UI-specific, so we removed it from the AG-UI page and now reference this generic doc instead. This doc is the right home for the C# conditional-approval content.
Activity