Skip to main content
SmithersEvent is the discriminated union the runtime and observability layer understand. Runtime-emitted variants are persisted to the event log, passed to runWorkflow({ onProgress }), streamed by Gateway, and filtered by bunx smithers-orchestrator events --type <category>. Reserved variants appear here typed but not yet emitted. Every variant has type, runId, and timestampMs. Node-scoped variants add nodeId and iteration. Attempt-scoped variants add attempt. For subscription examples, CLI usage, and built-in metrics, see Events.

Status Types

Event Variants

Discriminate on the type field, e.g. event.type === "NodeFailed", to handle specific lifecycle moments.
Browser UIs see a different shape. useGatewayRunEvents and the vanilla streamRunEventsResilient yield GatewayEventFrame objects, not raw SmithersEvents: the event NAME is frame.event, and every other field lives under frame.payload. Client-side equivalent:
Use frame.event === "NodeStarted" | "NodeFinished" | "NodeFailed" to build a per-node status view, keyed by frame.payload.nodeId. The table below lists each variant’s fields; in a UI those live under frame.payload. Frames reconstructed from persisted rows also carry an optional timestampMs (epoch millis from the stored row) and surface stateVersion: 0.
RunStateChanged is typed and categorized for forward compatibility, but the current runtime does not emit it. Read derived run state with getRun or computeRunState, and watch RunStatusChanged for persisted status transitions. OpenApiToolCalled is typed and categorized for forward compatibility, but the current OpenAPI tool factory records Effect metrics and log spans rather than emitting that event onto the run event bus.

Agent Event Payload

Describes the .event field of the AgentEvent variant above; for structured traces, prefer AgentTraceEvent, AgentTraceSummary, and AgentSessionEvent. AgentEvent.event is the normalized CLI-agent event payload: