Skip to content

Follow a run's events

A run's events are its journal as it's written: the run starting, each step starting and ending, waits, and the run's end. Follow them to show progress, or to react when the run ends without polling.

const run = await kindgi.runs.start({
flow: 'acme.reserve-order',
input: { orderId: 'A-400' },
options: { wait: false },
});
for await (const event of kindgi.runs.follow(run.id)) {
console.log(event.sequence, event.kind, event.nodeId ?? '');
}
// The loop ends after run.completed, run.failed or run.cancelled.
0 run.started
2 run.step-started reserve
3 run.step-retry-scheduled reserve
4 run.step-retry-scheduled reserve
5 run.step-completed reserve
7 run.completed

The stream starts from the run's first event, whenever you open it, so you don't miss what happened before. It ends after run.completed, run.failed or run.cancelled; the last event's payload.output is the run's output.

Each event has the run's id, a kind, a sequence (its place in the journal), a timestamp, the step's nodeId for step events, and a payload:

kind When payload
run.started The run started. input
run.step-started A step started. input
run.step-completed A step ended. output
run.step-failed A step failed. message
run.step-retry-scheduled A step failed and will be retried. attempt, nextDelayMs, previousError
run.iteration-started, run.iteration-completed A pass of a loop. iteration, …
run.wait-suspended, run.wait-resumed The run stopped to wait, and went on (approvals).
run.completed The run completed. output
run.failed The run failed. message
run.cancelled The run was cancelled.

Edge decisions are in the journal, not in the stream.

The server ends a stream after 5 minutes; a run that waits longer needs a new one. Each event's id is <run id>:<sequence>, and a new stream opened with the last id you saw (the Last-Event-Id header) starts after it.

runs.follow does this for you, in TypeScript and Python: it reconnects after a dropped connection or the server's limit, and ends only with the run. runs.followProgress (Python: runs.follow_progress) follows the progress stream (no payloads) the same way.

  • In Python, runs.stream is the plain call: it ends when the server closes the stream, and last_event_id=f"{run.id}:{event.sequence}" opens it again after that event.
  • In TypeScript, runs.stream still follows the run to its end, as follow does, but it's deprecated: in a later release, announced in advance, it becomes the plain call, as in Python.
Terminal window
kindgi runs stream <run-id>

It prints one event per line, as JSON:

{"eventId":"28795fe7-a357-4d67-8740-1bda88f3b85c:0","runId":"28795fe7-a357-4d67-8740-1bda88f3b85c",…,"kind":"run.started","sequence":0,"payload":{"input":{"orderId":"A-300"}}}
{"eventId":"28795fe7-a357-4d67-8740-1bda88f3b85c:2",…,"kind":"run.step-started","sequence":2,"nodeId":"reserve","payload":{"input":{"orderId":"A-300"}}}
…
{"eventId":"28795fe7-a357-4d67-8740-1bda88f3b85c:7",…,"kind":"run.completed","sequence":7,"payload":{"output":{"attempt":3,"orderId":"A-300","reserved":true}}}

To show a run's progress in a browser, without giving the page your API token, see Follow a run from the browser.