Stream Events

Stream Events

Every event type emitted during an agent run, including text streaming, tool calls, usage tracking, and errors.

thread.run() returns an AsyncGenerator<StreamEvent>. Each event has a type field that determines its shape. Your application handles these events to build UIs, log activity, or track costs.

Event reference

EventFieldsDescription
text_deltatextIncremental text token from the model
tool_use_starttoolName, toolUseIdModel is calling a tool
tool_use_deltainputIncremental tool call arguments (JSON fragment)
tool_resulttoolUseId, toolName, resultTool execution completed
message_completemessageFull assistant message assembled
usageusage, modelToken usage for a single model call
turn_completeusage, model, callCountAccumulated usage for the full agent turn
compact_startAuto-compaction started
compact_completeAuto-compaction finished
errorerrorAn error occurred

Handling events

for await (const event of thread.run("Fix the bug")) {
  switch (event.type) {
    case "text_delta":
      // Stream text to the UI
      process.stdout.write(event.text);
      break;

    case "tool_use_start":
      console.log(`Calling ${event.toolName}...`);
      break;

    case "tool_result":
      if (event.result.isError) {
        console.error(`Tool error: ${event.result.content}`);
      }
      break;

    case "message_complete":
      // Full message is available
      console.log("\nDone:", event.message.content);
      break;

    case "usage":
      // Per-call token usage
      console.log(`Tokens: ${event.usage.total_tokens} (${event.model})`);
      break;

    case "turn_complete":
      // Accumulated across all model calls in this turn
      console.log(`Turn total: ${event.usage.total_tokens} tokens, ${event.callCount} calls`);
      break;

    case "error":
      console.error("Agent error:", event.error.message);
      break;
  }
}

Text streaming

text_delta events arrive as the model generates tokens. Concatenating all text values gives you the full response text, which also appears in the message_complete event.

Tool call flow

During a tool loop, events flow in this order:

  1. tool_use_start -- the model requests a tool call
  2. tool_use_delta (zero or more) -- incremental JSON argument fragments
  3. tool_result -- the tool has been executed
  4. The model may make another tool call (repeat from 1) or produce text

Token usage

Two usage-related events are emitted:

usage

Emitted after each individual model call completes. Useful for real-time cost tracking during tool loops where the model is called multiple times.

{
  type: "usage";
  usage: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
  model: string;
}

turn_complete

Emitted once at the end of the full agent turn, after message_complete. Contains usage accumulated across all model calls in the turn.

{
  type: "turn_complete";
  usage: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
  model: string;
  callCount: number;
}

The callCount tells you how many times the model was called during this turn. A simple text response has callCount: 1. A response that involved two tool calls has callCount: 3 (initial call + two follow-ups after tool results).

Abort

You can abort a running agent at any time:

const gen = thread.run("Do something");

// Start consuming events
for await (const event of gen) {
  if (shouldStop) {
    thread.abort();
    break;
  }
}

RunOptions

Pass options to thread.run():

const controller = new AbortController();

for await (const event of thread.run("prompt", {
  signal: controller.signal,
})) {
  // handle events
}
OptionTypeDescription
signalAbortSignalAbort signal for cancellation