Chat stream

A model’s answer as it is written, step by step, read as events or collected whole.

A model’s answer as it is written. Read it as events with for await, or collect it with text() or done(). With tools, it carries on through every step: the tools run between steps, and their results arrive as events too.

interface ChatStream<Json> extends AsyncIterable<ChatEvent> {
  readonly requestId: string | undefined
  readonly processedIn: string | undefined
  text(): Promise<string>
  done(): Promise<ChatReply<Json>>
}

Fields

requestIdstring or undefined

The first answer’s ID with us. Quote it when you contact us.

processedInstring or undefined

The country where the model runs, such as Germany or United States.

text()Promise<string>

Reads the rest of the stream and returns the last answer’s text.

done()Promise<ChatReply>

Reads the rest of the stream and returns the whole chat reply. After the stream has been read, it returns straight away.

Events

Each event has a type:

TypeHoldsWhen
texttextThe next piece of the answer
reasoningtextThe next piece of what a reasoning model is thinking, before it answers
tool-inputcallId, name, textThe next piece of a tool call’s input, as JSON text, while the model writes it
tool-callcallA whole tool call, { id, name, input }, once the answer has finished
tool-resultresultWhat a tool gave back, { callId, name, input, output }, or error in place of output
jsonjsonWith schema or json: true, the object so far, each time it grows. Its last fields may be missing or cut short
stepstepA step has finished, with its text, calls, results, and usage
stream.ts
for await (const event of stream) {
  switch (event.type) {
    case "text":
      process.stdout.write(event.text)
      break
    case "tool-call":
      console.log(`\nLooking up ${event.call.name}…`)
      break
  }
}

Reading a stream

  • A stream can be read more than once. Each loop starts from the first event, and done() works before, during, or after a loop.
  • Stopping the only loop early, with break or return, closes the connection and stops the steps that were left, unless done() is waiting. done() then rejects with aborted.
  • The usage arrives at the end of each step, so the totals are only known once the stream has been read to the end.
  • When the service reports an error partway, the loop, text(), or done() rejects with that error as a SpaceError, such as model_unavailable. What the model wrote before it stopped still counts toward your AI units.
  • When the stream ends before the answer finished, it rejects with stream_interrupted, which is retryable.
  • timeoutMs and signal on the call cover every step and reading the stream too. Running out of time, cancelling, or losing the connection partway rejects with a SpaceError: timeout, aborted, or network_error.

See Stream answers for how streaming works in the service.

Returned by

Last updated