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
| Event | Fields | Description |
|---|---|---|
text_delta | text | Incremental text token from the model |
tool_use_start | toolName, toolUseId | Model is calling a tool |
tool_use_delta | input | Incremental tool call arguments (JSON fragment) |
tool_result | toolUseId, toolName, result | Tool execution completed |
message_complete | message | Full assistant message assembled |
usage | usage, model | Token usage for a single model call |
turn_complete | usage, model, callCount | Accumulated usage for the full agent turn |
compact_start | — | Auto-compaction started |
compact_complete | — | Auto-compaction finished |
error | error | An 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:
tool_use_start-- the model requests a tool calltool_use_delta(zero or more) -- incremental JSON argument fragmentstool_result-- the tool has been executed- 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
}| Option | Type | Description |
|---|---|---|
signal | AbortSignal | Abort signal for cancellation |