# TraconToolUsage

> 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.tracontoolusage/
> Summary: TraconToolUsage: Lets a tool report non-token usage from its own body.

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

Lets a tool report non-token usage from its own body.

```csharp
public static class TraconToolUsage
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.tracontoolusage/">TraconToolUsage</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone">object.MemberwiseClone()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Examples

```csharp
TraconToolUsage.Report(new ToolCallUsage
{
    Unit = ToolUsageUnits.Characters,
    Quantity = audio.CharactersBilled ?? request.Text.Length,
    Cost = price,
    Currency = "USD",
    IsEstimated = audio.CharactersBilled is null,
});
```

## Remarks

Speech synthesis is billed by character and speech recognition by second. Neither
is a token and cannot be written to the cost columns of the `runs` table.
The measurement attaches to the current call's [ToolInvocationRecord](/api/tracon.toolinvocationrecord/),
and its [ToolCallUsage.Cost](/api/tracon.toolcallusage/#Tracon_ToolCallUsage_Cost) joins the run's non-token total
([RunRecord.NonTokenCost](/api/tracon.runrecord/#Tracon_RunRecord_NonTokenCost)), which the run's budget, the tenant's quota and
the `run.completed` webhook count beside the token cost.

A tool that reports more than once for the same call reports the total at the end:
the last report of a call replaces the earlier ones, in the record and in the total.

The amount reaches the call tree's budget the moment it is reported. Once the tree has
spent its ceiling (`AgentGraph.MaxTotalCost`), no tool call that has not started
begins: its result is a sentence that says the tool call did not start, and a streaming
run records the call as failed. The call that crosses the ceiling runs to its end, so a
tool should report when it knows the amount, not only at its last line.

It reads the call identifier from `FunctionInvokingChatClient.CurrentContext`.
This was verified by measurement on 2026-08-05. The `AIFunctionArguments.Context`
dictionary is [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) and does not carry the call identifier, while the
static context is populated in the tool body. Dependencies resolve through `AIFunctionArguments.Services`.

## Methods

### <a id="Tracon_TraconToolUsage_Report_Tracon_ToolCallUsage_"></a> Report\(ToolCallUsage\)

Reports usage for the current tool call.

```csharp
public static bool Report(ToolCallUsage usage)
```

#### Parameters

`usage` [ToolCallUsage](/api/tracon.toolcallusage/)

The usage measurement.

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) when the measurement is attached to a call. Returns
[false](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) when run recording is disabled, the call is not in a tool context,
or the measurement is outside what a record holds: an empty unit, a unit longer than 64
characters, a currency longer than 16, a provider longer than 100, a model longer than
200, a quantity outside 0 to 9,999,999,999 or an amount outside 0 to 1,000,000,000. A
refused measurement is attached to nothing and counts in no total.

#### Remarks

This method **never throws**, except for an empty argument. A
[false](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) result does not interrupt the tool. Observability does
not break functionality. This is the same rule that prevents a store error from stopping a run.

#### Exceptions

 [ArgumentNullException](https://learn.microsoft.com/dotnet/api/system.argumentnullexception)

`usage` is [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).
