# IToolApprovalPresenter

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.itoolapprovalpresenter/
> Summary: IToolApprovalPresenter: Resolves a human-readable presentation for a tool call that is about to publish an approval request — turning, for example, { "orderId": "ORD-1001" } into.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

Resolves a human-readable presentation for a tool call that is about to publish an
approval request — turning, for example, `{ "orderId": "ORD-1001" }` into
"Cancel order for Priya Shah".

```csharp
public interface IToolApprovalPresenter
```

## Examples

```csharp
public sealed class OrderApprovalPresenter(IServiceScopeFactory scopes) : IToolApprovalPresenter
{
    public async ValueTask<ToolApprovalPresentation?> PresentAsync(
        ToolApprovalContext context, CancellationToken cancellationToken = default)
    {
        if (context.GetString("orderId") is not { } orderId)
        {
            return null;
        }

        using var scope = scopes.CreateScope();
        var orders = scope.ServiceProvider.GetRequiredService<IOrderRepository>();
        var customerName = await orders.GetAsync(orderId);

        return new ToolApprovalPresentation
        {
            EntityType = "order",
            EntityId = orderId,
            EntityName = $"Order {orderId}",
            Message = $"Cancel order {orderId} for {customerName}.",
        };
    }
}
```

## Remarks

**Read-only and best-effort.** This is not an authorization boundary —
[IToolAuthorizationHandler](/api/tracon.itoolauthorizationhandler/) and [IToolArgumentsValidator](/api/tracon.itoolargumentsvalidator/) are
the gates, and both fail closed. A presenter fails *open*: registered or not,
resolving or not, timing out or throwing, the approval request is published either
way. A presentation error must never suppress a request that needs a decision. The
raw arguments ([PendingApproval.Arguments](/api/tracon.pendingapproval/#Tracon_PendingApproval_Arguments)) are always available beside
whatever this method returns, so an operator can still decide even when it returns
[null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).

**Register it as a singleton and resolve scoped dependencies through
`IServiceScopeFactory`.** This method runs on the tool-call path, where
Microsoft Agent Framework hands every tool an empty service provider
(`AIFunctionArguments.Services` resolves nothing — see the framework notes on
`IToolAuthorizationHandler`). The same limit applies here: a scoped dependency,
such as a `DbContext`, must be resolved through an injected
`IServiceScopeFactory`, not a constructor parameter.

**Tenant behavior — EXPECTED tenant.** The tenant is carried by
[ToolApprovalContext.TenantId](/api/tracon.toolapprovalcontext/#Tracon_ToolApprovalContext_TenantId), the same way the code-defined approval
policy callback (`ITraconBuilder.AddToolApprovalPolicy`) reads it — never the
ambient tenant, since a presenter's own scoped lookup must never leak another tenant's
entity name into this one's approval card.

## Methods

### <a id="Tracon_IToolApprovalPresenter_PresentAsync_Tracon_ToolApprovalContext_System_Threading_CancellationToken_"></a> PresentAsync\(ToolApprovalContext, CancellationToken\)

Resolves a presentation for one pending tool call.

```csharp
ValueTask<ToolApprovalPresentation?> PresentAsync(ToolApprovalContext context, CancellationToken cancellationToken = default)
```

#### Parameters

`context` [ToolApprovalContext](/api/tracon.toolapprovalcontext/)

The tool call the approval request was raised for.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[ToolApprovalPresentation](/api/tracon.toolapprovalpresentation/)?\>

The presentation, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when nothing could be resolved. A
thrown exception or a call that runs past the configured timeout
(`TraconToolOptions.ApprovalPresentationTimeout`) is treated the same way.
