Skip to content

Add conditional (argument-based) approval to the tool-approval doc (C#: UseToolApproval + AutoApprovalRules) #434

Description

@danroth27

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 (in MicrosoftDocs/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 ApprovalRequiredAIFunction as usual, then layer AIAgentBuilder.UseToolApproval(new ToolApprovalAgentOptions { AutoApprovalRules = [...] }).
  • Each rule receives a ToolAutoApprovalRuleContext exposing the pending FunctionCallContent (tool name and arguments) and returns true to auto-approve or false to keep evaluating. Rules run after standing "always approve" decisions but before prompting; the first true approves 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions