Skip to main content

Streaming

app.stream(input, mode) runs the graph like run() and yields events as it goes. Pick the mode for what you want to show.

Tokens as the model writes them:

// Tokens as the model writes them.
for await (const event of app.stream({ question: "What is a checkpoint?" }, "messages")) {
if (event.type === "message_delta") process.stdout.write(event.delta);
}

Progress, node by node:

// One event per finished node, with the channels it changed.
for await (const event of app.stream({ question: "What is a checkpoint?" }, "updates")) {
if (event.type === "state_update") console.log(event.nodeId, Object.keys(event.delta));
}

Modes​

ModeYieldsUse it for
"messages"message_delta: { delta, nodeId, messageId } for each token of each agentA chat UI
"updates"state_update: { nodeId, delta } when a node finishesA progress list
"values"state_value: { state }, the full state after each nodeDebugging, dashboards
"debug"debug: every lifecycle event, wrappedTracing

messageId groups the tokens of one agent turn, so you can show several agents side by side.

A stream only yields events of its own run, even when several runs of the same graph stream at once. Leaving the loop early with break is safe.

Subscribe to events​

app.onEvent(handler) receives the lifecycle events of every run of the graph: node_started, node_completed, run_suspended, run_completed, run_failed, and more. It returns an unsubscribe function. The full list is in Events; sending them to a tracing backend is covered in Observability.

Next​