Streaming
The TypeScript SDK uses fetch + ReadableStream for SSE streaming, enabling POST requests with custom headers — something EventSource cannot do.
Basic Streaming
import { FaosClient } from '@faos/sdk';
const client = new FaosClient({ apiKey: 'faos_sk_...' });
for await (const chunk of client.agents.stream(
'credit-risk-analyst',
{ query: 'Analyze Q1 2024' },
)) {
switch (chunk.type) {
case 'text':
process.stdout.write(chunk.data);
break;
case 'tool_call':
console.log(`Tool: ${chunk.data.name}`, chunk.data.input);
break;
case 'metadata':
console.log('Metadata:', chunk.data);
break;
case 'error':
console.error(`Error: ${chunk.data.code} - ${chunk.data.message}`);
break;
case 'done':
console.log('\nDone:', chunk.data);
break;
}
}
Text-Only Convenience
Use streamText for a simpler API that yields only text strings:
for await (const text of client.agents.streamText(
'credit-risk-analyst',
{ query: 'Analyze Q1 2024' },
)) {
process.stdout.write(text);
}
StreamChunk Types
The StreamChunk is a discriminated union:
type StreamChunk =
| { type: 'text'; data: string; index: number }
| { type: 'tool_call'; data: { name: string; input: Record<string, unknown> }; index: number }
| { type: 'metadata'; data: Record<string, unknown>; index: number }
| { type: 'error'; data: { code: string; message: string }; index: number }
| { type: 'done'; data: { usage: TokenUsage; durationMs: number }; index: number };
TypeScript narrows the data type based on chunk.type.
Reconnection
Pass lastEventId to resume a stream after disconnection (ADR-FE-2):
for await (const chunk of client.agents.stream(
'analyst',
{ query: '...' },
{ lastEventId: 'evt-42' },
)) {
// Resumes from where the previous stream left off
}
Building a Chat UI
async function streamToUI(agentId: string, query: string) {
const client = new FaosClient({ apiKey: 'faos_sk_...' });
let fullText = '';
for await (const chunk of client.agents.stream(agentId, { query })) {
if (chunk.type === 'text') {
fullText += chunk.data;
// Update UI incrementally
updateChatBubble(fullText);
}
}
return fullText;
}
Browser Usage
The SDK works in browsers with native fetch — no polyfills needed:
// Works in any modern browser
const client = new FaosClient({ apiKey: 'faos_sk_...' });
for await (const text of client.agents.streamText('analyst', { query })) {
document.getElementById('output')!.textContent += text;
}