Stream.
Full event streaming from an agent run.
runner.stream(agent, input, options?)
Returns an async generator that yields AgentRunEvent objects as they arrive. This is the full event stream — tool calls, usage, status changes, safety replacements, and more.
for await (const event of runner.stream(
{ name: 'explainer', instructions: 'Explain quantum computing.' },
'What is quantum entanglement?',
)) {
switch (event.type) {
case 'run.started':
console.log(`Agent "${event.agentName}" started.`);
break;
case 'stream.started':
console.log(`Stream ${event.streamId} connected.`);
break;
case 'message.delta':
process.stdout.write(event.delta);
break;
case 'client.tool.requested':
console.log(`\nTool requested: ${event.name}`);
break;
case 'client.tool.result':
console.log(`Tool result: ${event.result}`);
break;
case 'usage':
console.log(`\nTokens: ${event.usage.output_tokens}`);
break;
case 'done':
console.log('\n[done]');
break;
case 'error':
console.error(`Error: ${event.code} — ${event.message}`);
break;
}
}AgentRunEvent
A discriminated union of 22 event types:
run.started
Emitted once at the start of a run with the agent's name.
{ type: 'run.started'; agentName: string }stream.started
Emitted once when the SSE stream connects, with the durable stream ID.
{ type: 'stream.started'; streamId: string }message.delta
A text chunk from the assistant.
{ type: 'message.delta'; delta: string }status.changed
Stream lifecycle status change.
{ type: 'status.changed'; status: 'thinking' | 'streaming' | 'queued' | 'idle' | 'done' | 'error' | string }queue.status
Queue position update while waiting for a free slot.
{ type: 'queue.status'; state: string; position: number; estimatedWaitSeconds: number }tool.started
A server-side tool invocation began.
{ type: 'tool.started'; tool: string; inputOrArgs?: string | Record<string, unknown>; output?: string }tool.progress
Progress update from a running server-side tool.
{ type: 'tool.progress'; tool: string; message: string }tool.completed
A server-side tool invocation finished.
{ type: 'tool.completed'; tool: string; status: 'success' | 'error'; input?: string; output?: string }client.tool.requested
The agent called a client tool. The SDK will execute the matching handler from toolHandlers.
{ type: 'client.tool.requested'; id?: string; name: string; args: Record<string, unknown> }client.tool.executing
The SDK is about to execute the handler for a requested client tool.
{ type: 'client.tool.executing'; id?: string; name: string; args: Record<string, unknown> }client.tool.result
A client tool handler returned a result.
{ type: 'client.tool.result'; id?: string; name: string; result: string; isError: boolean }client.tool.roundtrip
Emitted after each tool roundtrip cycle, showing progress against the maximum.
{ type: 'client.tool.roundtrip'; turn: number; maxTurns: number }turn.retrying
A retryable error occurred and the turn is being retried.
{ type: 'turn.retrying'; attempt: number; maxRetries: number; error: { code: string; message: string }; delayMs: number }generation.status
Generation phase update.
{ type: 'generation.status'; phase: string }safety.replace
The server replaced the output via a safety filter. message holds the replacement text; categories lists the safety categories.
{ type: 'safety.replace'; message?: string; categories: string[] }usage
Token usage data for the turn.
{ type: 'usage'; usage: UsageEvent }Where UsageEvent is:
interface UsageEvent {
output_tokens: number;
context_pct?: number;
context_messages_trimmed?: number;
context_budget_tokens?: number;
}cursor
Durable stream cursor (event ID). Persist this to resume from this point.
{ type: 'cursor'; lastEventId: string }truncated
The response was cut short.
{ type: 'truncated'; reason: string }replace
A generic replace event from the server.
{ type: 'replace' }done
The stream finished successfully.
{ type: 'done' }error
An error occurred during the stream.
{ type: 'error'; code: ChatErrorCode; message: string }