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

Core streaming

EventFieldsDescription
text_deltatextIncremental text token from the model
thinking_deltatextIncremental thinking/reasoning token (extended thinking)
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
errorerrorAn error occurred

Usage and cost

EventFieldsDescription
usageusage, modelToken usage for a single model call
turn_completeusage, model, callCountAccumulated usage for the full agent turn
cost_updatesummaryUpdated cost summary after a model call

Permissions

EventFieldsDescription
permission_requesttoolName, input, messageTool call requires user approval
permission_grantedtoolName, inputPermission was granted for a tool call
permission_deniedtoolName, input, messagePermission was denied for a tool call
denial_limit_exceededconsecutiveDenials, totalDenialsDenial tracking limits hit; agent should stop retrying

Compaction

EventFieldsDescription
compact_startAuto-compaction started
compact_completeAuto-compaction finished
microcompact_completetokensFreedMicrocompaction freed tokens from tool results
tool_result_truncatedtoolCallId, originalChars, truncatedCharsA tool result was truncated by the budget system

Retry

EventFieldsDescription
retry_attemptattempt, maxRetries, delayMs, errorA retryable error occurred; waiting before retry
retry_exhaustedattempts, errorAll retry attempts failed

Subagents and user input

EventFieldsDescription
subagent_starttoolUseId, promptA subagent is being spawned
subagent_endtoolUseId, resultA subagent finished
user_input_requesttoolUseId, questionThe agent is asking the user a question

Session and recovery

EventFieldsDescription
session_resumedsessionId, messageCountA previous session was restored
checkpoint_snapshotmessageIdA file checkpoint was taken before edits
recovery_filteredfilterName, removedCountCorrupt entries were filtered during session restore
interrupted_turn_detectedkindA previous turn was interrupted (interrupted_tool or interrupted_prompt)

Memory and tracing

EventFieldsDescription
memory_updatecreated, updated, deletedMemories were extracted from the conversation
span_startname, spanIdAn OpenTelemetry-compatible span started
span_endname, spanId, durationMs, error?A span ended
git_operationoperation, detailsA git operation was detected (commit, push, pr_create, merge, rebase)

Structured output and limits

EventFieldsDescription
structured_outputdata, schemaStructured output was produced matching the requested schema
max_turns_reachedmaxTurns, turnCountThe agent hit the maxTurns limit and stopped

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
maxTurnsnumberMaximum number of agent turns before stopping. Emits max_turns_reached when hit.
outputFormatOutputFormatRequest structured JSON output from the model (JSON schema or JSON object mode).
structuredOutputMode"alongside_tools" | "final_response"When to apply structured output: during tool use or only on the final response.