Skip to content
Tracon

TraconToolUsage

Namespace Tracon · Assembly Tracon.Core.dll

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

public static class TraconToolUsage
Inheritance
object ← TraconToolUsage
Inherited Members
object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
TraconToolUsage.Report(new ToolCallUsage
{
Unit = ToolUsageUnits.Characters,
Quantity = audio.CharactersBilled ?? request.Text.Length,
Cost = price,
Currency = "USD",
IsEstimated = audio.CharactersBilled is null,
});

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, and its ToolCallUsage.Cost joins the run’s non-token total (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 and does not carry the call identifier, while the static context is populated in the tool body. Dependencies resolve through AIFunctionArguments.Services.

Reports usage for the current tool call.

public static bool Report(ToolCallUsage usage)

usage ToolCallUsage

The usage measurement.

bool

true when the measurement is attached to a call. Returns false 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.

This method never throws, except for an empty argument. A false 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.

ArgumentNullException

usage is null.