Skip to content
xsAI

Stream structured data ​

Read partial objects or array elements before the response ends.

This page describes the v0 API from v0.5.1. Use v0 package builds with these examples. Make sure that the service accepts the model ID and request protocol shown below. Install valibot and @valibot/to-json-schema for the schema examples.

These examples use valibot.

This package uses xsschema to convert schemas. Use a schema library from its supported vendor list.

See xsschema for more information.

sh
npm i @xsai/stream-object@0.5.1

Examples ​

Install the schema converter that your schema version requires before you run these examples.

Read the schema coverage reference.

Object ​

ts
const { partialObjectStream } = await streamObject({
  apiKey: env.OPENAI_API_KEY!,
  baseURL: 'https://api.openai.com/v1/',
  messages: [
    {
      content: 'Extract the event information.',
      role: 'system'
    },
    {
      content: 'Alice and Bob are going to a science fair on Friday.',
      role: 'user'
    }
  ],
  model: 'gpt-4o',
  schema: v.object({
    date: v.string(),
    name: v.string(),
    participants: v.array(v.string()),
  })
})

for await (const partialObject of partialObjectStream) { 
  console.log(partialObject)
}

Array ​

ts
const { elementStream } = await streamObject({
  apiKey: env.OPENAI_API_KEY!,
  baseURL: 'https://api.openai.com/v1/',
  messages: [
    {
      content: 'Generate 3 hero descriptions for a fantasy role playing game.',
      role: 'user'
    }
  ],
  model: 'gpt-4o',
  output: 'array', 
  schema: v.object({
    class: v.pipe(
      v.string(),
      v.description('Character class, e.g. warrior, mage, or thief.'),
    ),
    description: v.string(),
    name: v.string(),
  })
})

for await (const element of elementStream) { 
  console.log(element)
}

Streams ​

streamObject() is built on streamText(), so it also returns:

  • textStream: raw JSON text deltas
  • eventStream: normalized xsAI events
  • fullStream: parsed chat completion chunks from the provider

Utils ​

toElementStream ​

toElementStream converts ReadableStream<string> to ReadableStream<T>. Use it independently when you already have JSON text chunks.

ts
const elementStream = await fetch('https://example.com')
  .then(res => res.body!.pipeThrough(new TextDecoderStream()))
  .then(stream => toElementStream<{ foo: { bar: 'baz' } }>(stream))

toPartialObjectStream ​

toPartialObjectStream converts ReadableStream<string> to ReadableStream<PartialDeep<T>>. Use it independently for partial JSON objects.

ts
const partialObjectStream = await fetch('https://example.com')
  .then(res => res.body!.pipeThrough(new TextDecoderStream()))
  .then(stream => toPartialObjectStream<{ foo: { bar: 'baz' } }>(stream))

Result ​

Consume the returned streams to receive partial objects or complete array elements.