Streaming
Consume normalized chat output as it is generated.
nirmos.gateway.chat.stream starts a streamed chat completion and returns a ChatStream.
const stream = await nirmos.gateway.chat.stream({
model: "openai/gpt-4.1-mini",
messages: [{ role: "user", content: "Write a product description." }],
});
for await (const event of stream) {
if (event.type === "content.delta") {
process.stdout.write(event.delta ?? "");
}
}The SDK parses Server-Sent Events, handles network chunk boundaries, normalizes provider-compatible chunks, and exposes one async iterable.
Event types
| Type | Meaning |
|---|---|
content.delta | New text for one choice |
toolCall.delta | Partial function tool call |
completion.completed | Fully assembled normalized completion |
Event type values are extensible. Ignore unrecognized events unless your application explicitly supports them.
for await (const event of stream) {
switch (event.type) {
case "content.delta":
process.stdout.write(event.delta ?? "");
break;
case "toolCall.delta":
console.log(event.toolCall);
break;
case "completion.completed":
console.log(event.completion?.usage);
break;
}
}Get the final completion
After iteration, call finalResponse() to get the same normalized response shape as chat.create:
const completion = await stream.finalResponse();
console.log(completion.outputText);
console.log(completion.usage.totalTokens);
console.log(completion.metadata.requestId);If you only need complete text, use text() instead of manually iterating:
const stream = await nirmos.gateway.chat.stream({
model: "openai/gpt-4.1-mini",
messages: [{ role: "user", content: "Summarize this incident." }],
});
const text = await stream.text();A stream has one consumption path. Do not iterate it from multiple tasks. Wait for active iteration to finish before calling finalResponse().
Cancellation
Pass an AbortSignal as the second argument:
const controller = new AbortController();
const stream = await nirmos.gateway.chat.stream(
{
model: "openai/gpt-4.1-mini",
messages: [{ role: "user", content: "Write a long report." }],
},
{ signal: controller.signal },
);
setTimeout(() => controller.abort(), 5_000);Cancellation raises RequestAbortedError, including after stream headers arrive. Timeouts raise TimeoutError. Invalid SSE data and server-declared stream failures raise StreamError.