stream: true and you get chunks instead of one reply. Every model on the
roster that serves chat completions also serves them
streamed.
Consuming a stream
How each language decides
- Python
- Node
- Rust
chat_completions dispatches on the value of stream, matching the
official OpenAI SDK’s one-method shape. Runtime behaviour is exact.Static typing is best-effort: a dict literal carrying keys warpllm does not
model matches no TypedDict, so a checker may infer the non-streaming
return type. Where the annotation has to be right, call
chat_completions_stream(request) — same behaviour, precisely typed, and
it sets stream for you.The chunk shape
Each chunk is aCreateChatCompletionStreamResponse. The difference from a
whole reply is choices[].delta in place of choices[].message.
string
The text fragment. Absent on chunks that carry only a role or tool-call
fragment.
string
Usually present on the first chunk only.
array
Tool-call fragments, each with an
index to reassemble by. See
Tool calling.string | null
null until the final content chunk.model on every chunk is your provider/model routing string, not the
upstream name.Token usage on a stream
Ask for it explicitly; providers do not send it by default.usage with the same fields a whole reply has.
Knowing the reply is complete
This is the part worth getting right.1
The stream ending cleanly means the reply is whole
Python raises
StopIteration, Node’s for await finishes, Rust’s
next() returns None. In every case: the model finished.2
An upstream that stopped early raises instead
StreamTruncated arrives after every chunk that did make it, so a
truncated answer can never be mistaken for a finished one. Without this,
both endings would look identical.3
An error item is terminal
Whatever produced it also ended the stream. There is nothing left to read,
and warpllm sends no completion sentinel after a failure.
Through the gateway
The gateway serves streams as server-sent events, the shape an OpenAI SDK expects, terminated bydata: [DONE].
A failure that arrives before the response commits is an ordinary error
response with its real status and headers. A failure after the 200 is
committed travels as the last event, carrying the same OpenAI envelope — and no
[DONE] follows it, because the sentinel means the model finished.
Next
Tool calling
Reassembling streamed tool-call fragments.
Timeouts
The gap-based deadline that streams actually need.