Skip to content
Tracon

ToolInvocationRecord

Namespace Tracon · Assembly Tracon.Abstractions.dll

The summary of a single completed tool call.

public sealed record ToolInvocationRecord : IEquatable<ToolInvocationRecord>
Inheritance
object ← ToolInvocationRecord
Implements
IEquatable<ToolInvocationRecord>
Inherited Members
object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

This record is a projection of the event stream: the same information also exists in the RunEventType.ToolInvoking and RunEventType.ToolInvoked events. It is kept in a separate table so that ToolInvocationRecord.Duration and per-tool totals can be queried without scanning the whole event stream.

The record is written only when the call settles; its duration is computed from correlating the ToolInvoking and ToolInvoked event pair.

public ToolInvocationRecord()

The call arguments. Raw text; may not be valid JSON.

public string? Arguments { get; init; }

string?

Whether IToolAuthorizationHandler denied this call before it ran.

public bool AuthorizationDenied { get; init; }

bool

A denied call is not an error: ToolInvocationRecord.Error stays empty and Result carries the denial text the model saw. This field is the only way to tell “the model chose not to call it” apart from “the caller was not allowed to call it” when reading the record back.

The moment the call settled (UTC).

public required DateTimeOffset CreatedAt { get; init; }

DateTimeOffset

The call’s duration. null if the event pair did not match.

public TimeSpan? Duration { get; init; }

TimeSpan?

The error message. Populated only if the call errored.

public string? Error { get; init; }

string?

The record identifier. A time-ordered UUID (v7).

public required Guid Id { get; init; }

Guid

The moment a call that had already been reported as timed out actually settled (UTC). null for every call that settled within its own timeout.

public DateTimeOffset? LateCompletedAt { get; init; }

DateTimeOffset?

A timeout stops the wait. A tool body that does not honour the cancellation it is then handed keeps running, and it can still succeed and still spend real money. When it does, ToolInvocationRecord.Result, ToolInvocationRecord.Usage and ToolInvocationRecord.Duration are filled in on this same row and this field records when that happened.

ToolInvocationRecord.TimedOut stays true and ToolInvocationRecord.Error keeps the timeout message: both describe what the MODEL was told, which does not change after the fact. This field is what distinguishes “it timed out and was never heard from again” from “it timed out and then finished anyway”.

The call result. Raw text; may not be valid JSON.

public string? Result { get; init; }

string?

The run that made the call.

public required Guid RunId { get; init; }

Guid

The tool’s source. null for tools defined in code; the server name for MCP tools.

public string? Source { get; init; }

string?

Whether the call finished successfully.

public bool Succeeded { get; }

bool

The EXPECTED tenant of the run that made the call. Defense in depth; if null, no tenant check is performed.

[JsonIgnore]
public string? TenantId { get; init; }

string?

See TenantId for the reason and why the ambient tenant is not used.

This field is WRITE-SIDE ONLY: it is not written to a column, it is only used as the write’s WHERE guard. It would always be null when read back, so it is excluded from the HTTP contract with Serialization.JsonIgnoreAttribute. Otherwise the OpenAPI document would declare a field that never gets populated.

Whether the call ended because its execution timeout elapsed (TraconToolTimeoutException).

public bool TimedOut { get; init; }

bool

The call identifier generated by the model. Distinguishes multiple calls of the same kind.

public string? ToolCallId { get; init; }

string?

The name of the tool called.

public required string ToolName { get; init; }

string

The call’s non-token measurement and cost. null if the tool reported no measurement — which is empty for the vast majority of calls.

public ToolCallUsage? Usage { get; init; }

ToolCallUsage?

The value is reported by the tool’s own body with TraconToolUsage.Report(...) and linked to this record by the call identifier.

public override bool Equals(object? obj)

obj object?

bool

public bool Equals(ToolInvocationRecord? other)

other ToolInvocationRecord?

bool

public override int GetHashCode()

int

public override string ToString()

string

operator ==(ToolInvocationRecord?, ToolInvocationRecord?)

Section titled “ operator ==(ToolInvocationRecord?, ToolInvocationRecord?)”
public static bool operator ==(ToolInvocationRecord? left, ToolInvocationRecord? right)

left ToolInvocationRecord?

right ToolInvocationRecord?

bool

operator !=(ToolInvocationRecord?, ToolInvocationRecord?)

Section titled “ operator !=(ToolInvocationRecord?, ToolInvocationRecord?)”
public static bool operator !=(ToolInvocationRecord? left, ToolInvocationRecord? right)

left ToolInvocationRecord?

right ToolInvocationRecord?

bool