Skip to content

IRunStore

Namespace AgentPrism · Assembly AgentPrism.Abstractions.dll

Store for run records and the event stream.

public interface IRunStore

Events are append-only. An implementation must never update or delete an event; it only adds them through IRunStore.AppendEventAsync.

Important: a failure in this store never interrupts the run. Observability must not break functionality. The caller (RunEventWriter) catches and logs the failure.

AppendEventAsync(RunEvent, CancellationToken)

Section titled “ AppendEventAsync(RunEvent, CancellationToken)”

Appends an event to the run stream.

ValueTask AppendEventAsync(RunEvent runEvent, CancellationToken cancellationToken = default)

runEvent RunEvent

The event to append. The caller assigns its sequence number.

cancellationToken CancellationToken

The cancellation token.

ValueTask

A task that completes when the event is written.

ClaimOrphanedRunsAsync(DateTimeOffset, int, CancellationToken)

Section titled “ ClaimOrphanedRunsAsync(DateTimeOffset, int, CancellationToken)”

Closes Running rows that have not sent a heartbeat for a long time as Failed and records the reason.

ValueTask<IReadOnlyList<RunRecord>> ClaimOrphanedRunsAsync(DateTimeOffset staleBefore, int max, CancellationToken cancellationToken = default)

staleBefore DateTimeOffset

Running rows whose last heartbeat is older than this — or that never sent one — count as orphaned (UTC).

max int

The maximum number of rows to close in this round.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<RunRecord>>

The records of the closed runs.

Closing also writes a RunEventType.RunFailed event to the stream — the process that was writing the run is gone, so this method emits the event itself. The sequence number is one past the current maximum.

Only Running rows are affected; Queued rows are owned by the job queue and this method DOES not TOUCH them.

[TenantAgnostic]: this is maintenance work and scans the orphaned rows of every tenant. Filtering by the ambient tenant would leave the rows of other tenants Running forever.

CompleteRunAsync(RunCompletion, CancellationToken)

Section titled “ CompleteRunAsync(RunCompletion, CancellationToken)”

Closes the run and updates its summary.

ValueTask CompleteRunAsync(RunCompletion completion, CancellationToken cancellationToken = default)

completion RunCompletion

The completion information.

cancellationToken CancellationToken

The cancellation token.

ValueTask

A task that completes when the record is updated.

GetExperimentResultsAsync(ExperimentResultsQuery, CancellationToken)

Section titled “ GetExperimentResultsAsync(ExperimentResultsQuery, CancellationToken)”

Summarizes an experiment per variant: count, failure rate, tokens, duration.

ValueTask<IReadOnlyList<ExperimentVariantResult>> GetExperimentResultsAsync(ExperimentResultsQuery query, CancellationToken cancellationToken = default)

query ExperimentResultsQuery

The filter.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<ExperimentVariantResult>>

Per-variant results. A variant that took no traffic is absent.

The experiment breakdown is available only through this query; experiment_id is not emitted as a metric tag, for cardinality reasons.

Gets a run record.

ValueTask<RunRecord?> GetRunAsync(Guid runId, CancellationToken cancellationToken = default)

runId Guid

The run id.

cancellationToken CancellationToken

The cancellation token.

ValueTask<RunRecord?>

The record, or null when it does not exist.

GetStatisticsAsync(RunStatisticsQuery, CancellationToken)

Section titled “ GetStatisticsAsync(RunStatisticsQuery, CancellationToken)”

Summarizes runs.

ValueTask<RunStatistics> GetStatisticsAsync(RunStatisticsQuery query, CancellationToken cancellationToken = default)

query RunStatisticsQuery

The filter.

cancellationToken CancellationToken

The cancellation token.

ValueTask<RunStatistics>

Counts, token totals and the per-agent breakdown.

The summary is computed inside the store. Fetching records and aggregating them in memory would cover only a paged subset and give the wrong answer.

GetTimeSeriesAsync(RunTimeSeriesQuery, CancellationToken)

Section titled “ GetTimeSeriesAsync(RunTimeSeriesQuery, CancellationToken)”

Produces the per-bucket time series of runs, failures, tokens and cost.

ValueTask<IReadOnlyList<TimeSeriesPoint>> GetTimeSeriesAsync(RunTimeSeriesQuery query, CancellationToken cancellationToken = default)

query RunTimeSeriesQuery

The filter.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<TimeSeriesPoint>>

The ordered bucket list. Empty buckets are returned too, with zero counts.

AgentPrismException

The requested range exceeds RunTimeSeriesBucketing.MaxBuckets.

GetToolUsageAsync(ToolUsageQuery, CancellationToken)

Section titled “ GetToolUsageAsync(ToolUsageQuery, CancellationToken)”

Summarizes usage per tool.

ValueTask<IReadOnlyList<ToolUsage>> GetToolUsageAsync(ToolUsageQuery query, CancellationToken cancellationToken = default)

query ToolUsageQuery

The filter.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<ToolUsage>>

Call counts, failure rates and average durations.

Same reason as IRunStore.GetStatisticsAsync: the summary is computed inside the store.

ListToolInvocationsAsync(Guid, CancellationToken)

Section titled “ ListToolInvocationsAsync(Guid, CancellationToken)”

Lists the tool calls of a run in chronological order.

ValueTask<IReadOnlyList<ToolInvocationRecord>> ListToolInvocationsAsync(Guid runId, CancellationToken cancellationToken = default)

runId Guid

The run id.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<ToolInvocationRecord>>

The call records.

QueryRunsAsync(RunQuery, CancellationToken)

Section titled “ QueryRunsAsync(RunQuery, CancellationToken)”

Lists runs that match a filter, newest first.

ValueTask<IReadOnlyList<RunRecord>> QueryRunsAsync(RunQuery query, CancellationToken cancellationToken = default)

query RunQuery

The filter.

cancellationToken CancellationToken

The cancellation token.

ValueTask<IReadOnlyList<RunRecord>>

The matching records.

ReadEventsAsync(Guid, long, CancellationToken)

Section titled “ ReadEventsAsync(Guid, long, CancellationToken)”

Reads the events of a run in sequence order. Live streaming and historical replay take the same path.

IAsyncEnumerable<RunEvent> ReadEventsAsync(Guid runId, long fromSequence = 0, CancellationToken cancellationToken = default)

runId Guid

The run id.

fromSequence long

Reading starts at this sequence number, inclusive.

cancellationToken CancellationToken

The cancellation token.

IAsyncEnumerable<RunEvent>

The ordered event stream.

RecordToolInvocationAsync(ToolInvocationRecord, CancellationToken)

Section titled “ RecordToolInvocationAsync(ToolInvocationRecord, CancellationToken)”

Records a settled tool call.

ValueTask RecordToolInvocationAsync(ToolInvocationRecord invocation, CancellationToken cancellationToken = default)

invocation ToolInvocationRecord

The call summary.

cancellationToken CancellationToken

The cancellation token.

ValueTask

A task that completes when the record is written.

Kept apart from the event stream because durations and per-tool totals must be queryable without scanning the whole event stream.

StartRunAsync(RunStartInfo, CancellationToken)

Section titled “ StartRunAsync(RunStartInfo, CancellationToken)”

Opens a new run record.

ValueTask<RunRecord> StartRunAsync(RunStartInfo info, CancellationToken cancellationToken = default)

info RunStartInfo

The start information.

cancellationToken CancellationToken

The cancellation token.

ValueTask<RunRecord>

The created record.

TouchHeartbeatAsync(IReadOnlyCollection<Guid>, DateTimeOffset, CancellationToken)

Section titled “ TouchHeartbeatAsync(IReadOnlyCollection<Guid>, DateTimeOffset, CancellationToken)”

Updates the “still here” mark of in-flight runs in one batch.

ValueTask TouchHeartbeatAsync(IReadOnlyCollection<Guid> runIds, DateTimeOffset at, CancellationToken cancellationToken = default)

runIds IReadOnlyCollection<Guid>

The ids of the runs to mark.

at DateTimeOffset

The mark time (UTC).

cancellationToken CancellationToken

The cancellation token.

ValueTask

A task that completes when the marks are written.

Only Running rows are affected; an id that does not exist or is in another status is skipped silently — this is a maintenance signal and must not interrupt a run.

[TenantAgnostic]: the ids come from the calling process’s own IRunCancellationRegistry and are therefore already limited to the runs that process actually executes. A tenant filter would also need one query per tenant, which defeats the point of a heartbeat: a cheap signal that stays off the hot path.

UpdateRunCostAsync(Guid, RunCost?, string?, CancellationToken)

Section titled “ UpdateRunCostAsync(Guid, RunCost?, string?, CancellationToken)”

Updates the cost of a run. Used only by the maintenance endpoint (POST /api/stats/recalculate-costs); on the normal path the cost is written once by IRunStore.CompleteRunAsync.

ValueTask UpdateRunCostAsync(Guid runId, RunCost? cost, string? tenantId = null, CancellationToken cancellationToken = default)

runId Guid

The run id.

cost RunCost?

The new cost. May be null.

tenantId string?

The EXPECTED tenant of the run. Defence in depth; when null no tenant check is made. TenantId.

cancellationToken CancellationToken

The cancellation token.

ValueTask

A task that completes when the record is updated.