Streaming
client.chat.stream() sends a message and delivers the response incrementally
over Server-Sent Events. It is callback-driven and resolves with the final
assembled ChatMessage.
const finalMessage = await client.chat.stream(thread.id, "Tell me a story", { assistantName: "your-assistant-id", // required — the release's assistant/model id onChunk: (text) => process.stdout.write(text), onComplete: (message) => console.log("\n\ndone:", message.id), onError: (error) => console.error(error),});Signature
Section titled “Signature”stream( chatId: string, content: string, options?: SendMessageOptions & StreamOptions,): Promise<ChatMessage>options accepts everything send() accepts (assistantName,
attachments, metadata, replyTo, …) plus the streaming callbacks below.
Stream callbacks
Section titled “Stream callbacks”| Callback | Fires when |
|---|---|
onChunk(text) | A content delta arrives. The simplest way to render tokens. |
onComplete(message) | The full message is assembled. |
onError(error) | The stream fails (a typed DivinciError). |
onArenaVariant(variant) | An arena variant arrives (arena mode). |
onArenaComplete(variants) | All arena variants have arrived. |
onEvent(event) | Low-level access to every event (see below). |
Fine-grained events with onEvent
Section titled “Fine-grained events with onEvent”For richer UIs (showing RAG sources, render-then-finalize, arena skeletons), use
onEvent, which receives a discriminated union:
await client.chat.stream(thread.id, "What's covered under warranty?", { assistantName: "your-assistant-id", onEvent: (event) => { switch (event.type) { case "start": beginBubble(event.messageId); break; case "chunk": appendText(event.content); break; case "context": renderSources(event.context); // RAG citations break; case "done": finalize(event.message, event.usage); break; case "error": showError(event.error); break; case "arena-variant": renderVariant(event.variantIndex, event.variant); break; case "arena-complete": enableVariantPicker(event.variants); break; } },});Cancelling a stream
Section titled “Cancelling a stream”Pass an AbortSignal to stop generation (e.g. a “Stop” button):
const controller = new AbortController();
const promise = client.chat.stream(thread.id, "Write a long essay", { assistantName: "your-assistant-id", onChunk: render, signal: controller.signal,});
stopButton.onclick = () => controller.abort();Aborting rejects the promise; catch it and treat it as a user cancellation rather than an error.
React pattern
Section titled “React pattern”function useStreamingSend(client: DivinciClient, threadId: string) { const [text, setText] = useState(""); const controller = useRef<AbortController>();
const send = useCallback(async (prompt: string) => { setText(""); controller.current = new AbortController(); await client.chat.stream(threadId, prompt, { assistantName: "your-assistant-id", onChunk: (delta) => setText((prev) => prev + delta), signal: controller.current.signal, }); }, [client, threadId]);
const stop = () => controller.current?.abort(); return { text, send, stop };}