Skip to content

RunEvent

Namespace AgentPrism · Assembly AgentPrism.Abstractions.dll

A single event produced during a run. Events are append-only: they are never updated, only added.

public sealed record RunEvent : IEquatable<RunEvent>

objectRunEvent

IEquatable<RunEvent>

object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

RunEvent.Sequence comes from a single writer and increases from 0 within a run. That is what lets live streaming (SSE) and historical replay share one code path; a client can resume from the sequence number it reached when a connection dropped.

Which fields are populated for each event type:

Value Fields and meaning
RunEventType.RunStarted Text, the first user message that triggered the run. It is the ONLY place the input text is persisted.
RunEventType.MessageDelta Text
RunEventType.ToolInvoking RunEvent.ToolName, RunEvent.ToolCallId, RunEvent.Payload (arguments)
RunEventType.ToolInvoked RunEvent.ToolName, RunEvent.ToolCallId, RunEvent.Payload (result)
RunEventType.ToolFailed RunEvent.ToolName, RunEvent.ToolCallId, Text (error message)
RunEventType.RunFailed Text (error message)
public RunEvent()

Gets the free-form JSON payload that carries tool arguments and results.

public string? Payload { get; init; }

string?

Gets the run the event belongs to.

public required Guid RunId { get; init; }

Guid

Gets the sequence number within the run. It starts at 0 and increases without gaps.

public required long Sequence { get; init; }

long

Gets the EXPECTED tenant of the run the event is written to. Defence in depth.

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

string?

When populated, the store applies the write only if the target run belongs to that tenant; otherwise the write is dropped and an error is raised. When null no tenant check is made.

This field is not filled from the ambient tenant. TenantId may deliberately override the ambient tenant — that is how workflows and the job queue work — and filtering by the ambient value would silently drop legitimate writes. The value is the tenant known to whoever opened the run.

The field is WRITE-side only: it is not stored in a column, it is only the WHERE guard of the write. Reading it back would always give null, so it is removed from the transport contract with Serialization.JsonIgnoreAttribute.

Gets the text content. Its meaning depends on the event type.

public string? Text { get; init; }

string?

Gets the moment the event occurred (UTC).

public required DateTimeOffset Timestamp { get; init; }

DateTimeOffset

Gets the tool call id, which separates several calls to the same tool.

public string? ToolCallId { get; init; }

string?

Gets the tool name. Populated only on tool events.

public string? ToolName { get; init; }

string?

Gets the event type.

public required RunEventType Type { get; init; }

RunEventType

public override bool Equals(object? obj)

obj object?

bool

public bool Equals(RunEvent? other)

other RunEvent?

bool

public override int GetHashCode()

int

public override string ToString()

string

public static bool operator ==(RunEvent? left, RunEvent? right)

left RunEvent?

right RunEvent?

bool

public static bool operator !=(RunEvent? left, RunEvent? right)

left RunEvent?

right RunEvent?

bool