# ToolInvocationRecord

> 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.toolinvocationrecord/
> Summary: ToolInvocationRecord: The summary of a single completed tool call.

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

The summary of a single completed tool call.

```csharp
public sealed record ToolInvocationRecord : IEquatable<ToolInvocationRecord>
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.toolinvocationrecord/">ToolInvocationRecord</a></dd><dt>Implements</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.iequatable-1">IEquatable&lt;ToolInvocationRecord&gt;</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.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>

## Remarks

This record is a *projection* of the event stream: the same
information also exists in the [RunEventType.ToolInvoking](/api/tracon.runeventtype/) and
[RunEventType.ToolInvoked](/api/tracon.runeventtype/) events. It is kept in a separate
table so that [ToolInvocationRecord.Duration](/api/tracon.toolinvocationrecord/#Tracon_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.

## Constructors

### <a id="Tracon_ToolInvocationRecord__ctor"></a> ToolInvocationRecord\(\)

```csharp
public ToolInvocationRecord()
```

## Properties

### <a id="Tracon_ToolInvocationRecord_Arguments"></a> Arguments

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

```csharp
public string? Arguments { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_ToolInvocationRecord_AuthorizationDenied"></a> AuthorizationDenied

Whether [IToolAuthorizationHandler](/api/tracon.itoolauthorizationhandler/) denied this call before it ran.

```csharp
public bool AuthorizationDenied { get; init; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

#### Remarks

A denied call is **not** an error: [ToolInvocationRecord.Error](/api/tracon.toolinvocationrecord/#Tracon_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.

### <a id="Tracon_ToolInvocationRecord_CreatedAt"></a> CreatedAt

The moment the call settled (UTC).

```csharp
public required DateTimeOffset CreatedAt { get; init; }
```

#### Property Value

 [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)

### <a id="Tracon_ToolInvocationRecord_Duration"></a> Duration

The call's duration. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) if the event pair did not match.

```csharp
public TimeSpan? Duration { get; init; }
```

#### Property Value

 [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)?

### <a id="Tracon_ToolInvocationRecord_Error"></a> Error

The error message. Populated only if the call errored.

```csharp
public string? Error { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_ToolInvocationRecord_Id"></a> Id

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

```csharp
public required Guid Id { get; init; }
```

#### Property Value

 [Guid](https://learn.microsoft.com/dotnet/api/system.guid)

### <a id="Tracon_ToolInvocationRecord_LateCompletedAt"></a> LateCompletedAt

The moment a call that had already been reported as timed out actually
settled (UTC). [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) for every call that settled
within its own timeout.

```csharp
public DateTimeOffset? LateCompletedAt { get; init; }
```

#### Property Value

 [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)?

#### Remarks

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](/api/tracon.toolinvocationrecord/#Tracon_ToolInvocationRecord_Result),
[ToolInvocationRecord.Usage](/api/tracon.toolinvocationrecord/#Tracon_ToolInvocationRecord_Usage) and [ToolInvocationRecord.Duration](/api/tracon.toolinvocationrecord/#Tracon_ToolInvocationRecord_Duration) are filled in on this
same row and this field records when that happened.

[ToolInvocationRecord.TimedOut](/api/tracon.toolinvocationrecord/#Tracon_ToolInvocationRecord_TimedOut) stays [true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) and
[ToolInvocationRecord.Error](/api/tracon.toolinvocationrecord/#Tracon_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".

### <a id="Tracon_ToolInvocationRecord_Result"></a> Result

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

```csharp
public string? Result { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_ToolInvocationRecord_RunId"></a> RunId

The run that made the call.

```csharp
public required Guid RunId { get; init; }
```

#### Property Value

 [Guid](https://learn.microsoft.com/dotnet/api/system.guid)

### <a id="Tracon_ToolInvocationRecord_Source"></a> Source

The tool's source. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) for tools defined in code;
the server name for MCP tools.

```csharp
public string? Source { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_ToolInvocationRecord_Succeeded"></a> Succeeded

Whether the call finished successfully.

```csharp
public bool Succeeded { get; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_ToolInvocationRecord_TenantId"></a> TenantId

The EXPECTED tenant of the run that made the call. Defense in depth; if [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null), no tenant check is performed.

```csharp
[JsonIgnore]
public string? TenantId { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

#### Remarks

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](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/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.

### <a id="Tracon_ToolInvocationRecord_TimedOut"></a> TimedOut

Whether the call ended because its execution timeout elapsed
([TraconToolTimeoutException](/api/tracon.tracontooltimeoutexception/)).

```csharp
public bool TimedOut { get; init; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_ToolInvocationRecord_ToolCallId"></a> ToolCallId

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

```csharp
public string? ToolCallId { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_ToolInvocationRecord_ToolName"></a> ToolName

The name of the tool called.

```csharp
public required string ToolName { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_ToolInvocationRecord_Usage"></a> Usage

The call's non-token measurement and cost. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) if
the tool reported no measurement — which is empty for the vast
majority of calls.

```csharp
public ToolCallUsage? Usage { get; init; }
```

#### Property Value

 [ToolCallUsage](/api/tracon.toolcallusage/)?

#### Remarks

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

## Methods

### <a id="Tracon_ToolInvocationRecord_Equals_System_Object_"></a> Equals\(object?\)

```csharp
public override bool Equals(object? obj)
```

#### Parameters

`obj` [object](https://learn.microsoft.com/dotnet/api/system.object)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_ToolInvocationRecord_Equals_Tracon_ToolInvocationRecord_"></a> Equals\(ToolInvocationRecord?\)

```csharp
public bool Equals(ToolInvocationRecord? other)
```

#### Parameters

`other` [ToolInvocationRecord](/api/tracon.toolinvocationrecord/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_ToolInvocationRecord_GetHashCode"></a> GetHashCode\(\)

```csharp
public override int GetHashCode()
```

#### Returns

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_ToolInvocationRecord_ToString"></a> ToString\(\)

```csharp
public override string ToString()
```

#### Returns

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Operators

### <a id="Tracon_ToolInvocationRecord_op_Equality_Tracon_ToolInvocationRecord_Tracon_ToolInvocationRecord_"></a> operator ==\(ToolInvocationRecord?, ToolInvocationRecord?\)

```csharp
public static bool operator ==(ToolInvocationRecord? left, ToolInvocationRecord? right)
```

#### Parameters

`left` [ToolInvocationRecord](/api/tracon.toolinvocationrecord/)?

`right` [ToolInvocationRecord](/api/tracon.toolinvocationrecord/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_ToolInvocationRecord_op_Inequality_Tracon_ToolInvocationRecord_Tracon_ToolInvocationRecord_"></a> operator \!=\(ToolInvocationRecord?, ToolInvocationRecord?\)

```csharp
public static bool operator !=(ToolInvocationRecord? left, ToolInvocationRecord? right)
```

#### Parameters

`left` [ToolInvocationRecord](/api/tracon.toolinvocationrecord/)?

`right` [ToolInvocationRecord](/api/tracon.toolinvocationrecord/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)
