Streaming
Consuming AI event streams with async iterators
AI methods return a stream of typed events: the SDK handles the SSE plumbing, you get an async iterator.
The pattern
const stream = await bold.ai.chat({ prompt: 'Explain the pricing framework' });
for await (const event of stream) {
switch (event.type) {
case 'message_start':
// conversation is starting; store the ID for follow-ups
saveConversationId(event.conversationId);
break;
case 'progress':
// Bold is planning/retrieving: show a status line
setStatus(event.message); // e.g. "Working out the angle…"
break;
case 'text_delta':
appendToAnswer(event.delta); // concatenate deltas
break;
case 'sources':
showCitations(event.sources); // clips with video + timestamps
break;
case 'message_complete':
finalize(event.content, event.citations, event.responseType);
break;
case 'error':
if (event.retryable) retry();
else showError(event.message);
break;
}
}Event reference
The AIEvent union, as shipped in the SDK:
type | Fields | Notes |
|---|---|---|
message_start | conversationId?, videoId? | First event |
progress | stage, message | Planning/retrieval status, great for "thinking…" UI |
text_delta | delta | Incremental answer text |
sources | sources: Segment[] | Clips found during retrieval |
recommendations | recommendations | From ai.recommendations |
message_complete | content, citations, responseType, conversationId?, usage?, guidance? | The full answer; responseType is 'answer' or 'clarification' |
image_analysis | status, description? | When images are attached |
error | code, message, retryable | Handle and decide whether to retry |
Each Segment in sources/citations carries videoId, videoTitle, start, end, and the transcript text: everything you need to render a "jump to 12:34" citation link.
New event types may be added over time. A default: branch that ignores unknown events keeps you forward-compatible.
Non-streaming mode
Every AI method accepts stream: false and returns a single object instead:
const response = await bold.ai.chat({ prompt: '…', stream: false });
console.log(response.content); // the answer
console.log(response.sources); // citations
console.log(response.usage); // token usageA complete chat helper
async function askBold(prompt: string, conversationId?: string) {
const stream = await bold.ai.chat({ prompt, conversationId });
let answer = '';
let citations: Segment[] = [];
let convId = conversationId;
for await (const event of stream) {
if (event.type === 'message_start') convId = event.conversationId ?? convId;
if (event.type === 'text_delta') answer += event.delta;
if (event.type === 'message_complete') citations = event.citations;
if (event.type === 'error') throw new Error(event.message);
}
return { answer, citations, conversationId: convId };
}For the raw SSE format (if you're not using the SDK), see API Streaming.