Client SDK · Chat

Streaming.

Full event streaming from the chat API.

chat.stream(params, options?)

Returns an async generator that yields MatildaChatStreamEvent objects as they arrive over SSE. This is the full event stream — tool calls, usage, status changes, safety replacements, and more.

TypeScript
for await (const event of client.chat.stream({ input: 'Explain quantum computing.' })) {
  switch (event.type) {
    case 'response.created':
      console.log(`Stream started: ${event.streamId}`);
      break;
    case 'response.output_text.delta':
      process.stdout.write(event.delta);
      break;
    case 'response.tool_call.started':
      console.log(`\nTool: ${event.tool}`);
      break;
    case 'response.usage':
      console.log(`\nTokens: ${event.usage.output_tokens}`);
      break;
    case 'response.completed':
      console.log('\n--- Done ---');
      break;
    case 'response.error':
      console.error(`Error: ${event.code}${event.message}`);
      break;
  }
}

MatildaChatStreamEvent

A discriminated union of 14 event types:

response.created

Emitted once at stream start with the durable stream ID.

TypeScript
{ type: 'response.created'; streamId: string }

response.output_text.delta

A text chunk from the assistant.

TypeScript
{ type: 'response.output_text.delta'; delta: string }

response.output_text.replace

The server replaced the output (e.g. safety filter). The content field holds the replacement text; categories lists the safety categories that triggered the replacement.

TypeScript
{ type: 'response.output_text.replace'; content?: string; categories?: string[] }

response.status

Stream lifecycle status change.

TypeScript
{ type: 'response.status'; status: 'thinking' | 'streaming' | 'queued' | 'idle' | 'done' | 'error' | string }

response.queued

Queue position update while waiting for a free slot.

TypeScript
{ type: 'response.queued'; state: string; position: number; estimatedWaitSeconds: number }

response.tool_call.started

A server-side tool invocation began.

TypeScript
{ type: 'response.tool_call.started'; tool: string; inputOrArgs?: string | Record<string, unknown>; output?: string }

response.tool_call.progress

Progress update from a running tool.

TypeScript
{ type: 'response.tool_call.progress'; tool: string; message: string }

response.tool_call.completed

A tool invocation finished.

TypeScript
{ type: 'response.tool_call.completed'; tool: string; status: 'success' | 'error'; input?: string; output?: string }

response.generation_status

Generation phase update.

TypeScript
{ type: 'response.generation_status'; phase: string }

response.usage

Token usage data for the turn.

TypeScript
{ type: 'response.usage'; usage: UsageEvent }

Where UsageEvent is:

TypeScript
interface UsageEvent {
  output_tokens: number;
  context_pct?: number;              // context window usage (0-100)
  context_messages_trimmed?: number; // messages trimmed to fit context budget
  context_budget_tokens?: number;    // total context budget in tokens
}

response.cursor

Durable stream cursor (Redis stream entry ID). Persist this to resume from this point.

TypeScript
{ type: 'response.cursor'; lastEventId: string }

response.truncated

The response was cut short.

TypeScript
{ type: 'response.truncated'; reason: string }

response.completed

The stream finished successfully.

TypeScript
{ type: 'response.completed' }

response.error

An error occurred during the stream.

TypeScript
{ type: 'response.error'; code: ChatErrorCode; message: string }