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.
npm i @xsai/stream-object@0.5.1Examples
Install the schema converter that your schema version requires before you run these examples.
Read the schema coverage reference.
Object
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
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 deltaseventStream: normalized xsAI eventsfullStream: 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.
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.
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.
