# IRunInputStore

> 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.iruninputstore/
> Summary: IRunInputStore: Stores a run's input messages. The source of replay.

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

Stores a run's input messages. The source of replay.

```csharp
public interface IRunInputStore
```

## Remarks

A separate interface; a member is **not added** to
[IRunStore](/api/tracon.irunstore/). Adding a member to an existing interface is a
breaking change after release (the same reason applies to
`IRetentionStore` and `IEvalStore`).

The input was never persisted anywhere until now: [RunRecord](/api/tracon.runrecord/)
carries no input, and the [RunEventType.RunStarted](/api/tracon.runeventtype/) event only
carries the *text* of the first user message, and that
text can be truncated. Replay must be faithful; this is why messages are
stored in a separate table together with their polymorphic content.

**An error from this store does not stop the run.** The write
path (`RunRecordingAgent`) catches and logs the error; observability
must not break functionality.

**Tenant behavior — EXPECTED tenant, uniformly.**
[IRunInputStore.SaveAsync](/api/tracon.iruninputstore/#Tracon_IRunInputStore_SaveAsync_Tracon_RunInputRecord_System_Threading_CancellationToken_) reads it from [RunInputRecord.TenantId](/api/tracon.runinputrecord/#Tracon_RunInputRecord_TenantId);
[IRunInputStore.GetAsync](/api/tracon.iruninputstore/#Tracon_IRunInputStore_GetAsync_System_String_System_Guid_System_Threading_CancellationToken_) takes it as a parameter. The ambient tenant is
never consulted.

## Methods

### <a id="Tracon_IRunInputStore_GetAsync_System_String_System_Guid_System_Threading_CancellationToken_"></a> GetAsync\(string, Guid, CancellationToken\)

Reads the stored input.

```csharp
ValueTask<RunInputRecord?> GetAsync(string tenantId, Guid runId, CancellationToken cancellationToken = default)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

The tenant identifier.

`runId` [Guid](https://learn.microsoft.com/dotnet/api/system.guid)

The run identifier.

`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)<[RunInputRecord](/api/tracon.runinputrecord/)?\>

The record; [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) if it does not exist or belongs to another tenant.

### <a id="Tracon_IRunInputStore_SaveAsync_Tracon_RunInputRecord_System_Threading_CancellationToken_"></a> SaveAsync\(RunInputRecord, CancellationToken\)

Saves the input messages.

```csharp
ValueTask SaveAsync(RunInputRecord record, CancellationToken cancellationToken = default)
```

#### Parameters

`record` [RunInputRecord](/api/tracon.runinputrecord/)

The input to save.

`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)

The completion task.

#### Remarks

A second write for the same run is **ignored**: a queued
run can start twice with the same identifier, and the input
must not change.
