.agents/skills/xsai/references/recipes.md
Use this reference when the user wants code, when you are editing xsAI code, or when a prompt needs a canonical minimal example.
@xsai/* imports in new examples.xsai package only when the repo already uses it or the user explicitly wants one dependency.baseURL and model explicit.apiKey for hosted providers. For local or proxy endpoints, only include it if the target actually requires one.import { env } from 'node:process'
import { generateText } from '@xsai/generate-text'
const { text } = await generateText({
apiKey: env.OPENAI_API_KEY!,
baseURL: 'https://api.openai.com/v1/',
messages: [
{
content: 'You are a helpful assistant.',
role: 'system',
},
{
content: 'Write one sentence about the moon.',
role: 'user',
},
],
model: 'gpt-4o',
})
Use this as the default starting point for simple scripts, tests, and one-shot helpers.
import { env } from 'node:process'
import { streamText } from '@xsai/stream-text'
import { tool } from '@xsai/tool'
import * as v from 'valibot'
const add = await tool({
description: 'Adds two numbers',
execute: ({ a, b }) => (Number.parseInt(a) + Number.parseInt(b)).toString(),
name: 'add',
parameters: v.object({
a: v.pipe(v.string(), v.description('First number')),
b: v.pipe(v.string(), v.description('Second number')),
}),
})
const { fullStream } = streamText({
apiKey: env.OPENAI_API_KEY!,
baseURL: 'https://api.openai.com/v1/',
maxSteps: 2,
messages: [
{
content: 'You are a helpful assistant.',
role: 'system',
},
{
content: 'What is 12 plus 30? Use the add tool.',
role: 'user',
},
],
model: 'gpt-4o',
toolChoice: 'required',
tools: [add],
})
const text: string[] = []
for await (const event of fullStream) {
if (event.type === 'text-delta') {
text.push(event.text)
}
if (event.type === 'tool-call' || event.type === 'tool-result') {
console.log(event)
}
}
console.log(text.join(''))
Use textStream for plain live text. Use fullStream when the caller needs tool events, reasoning deltas, or finish metadata.
Valibot examples require @valibot/to-json-schema in the project. If the repo already uses a different supported schema library, keep that choice.
import { env } from 'node:process'
import { generateObject } from '@xsai/generate-object'
import * as v from 'valibot'
const { object } = await generateObject({
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()),
}),
})
Prefer this over asking the model for free-form JSON.
import { env } from 'node:process'
import { streamObject } from '@xsai/stream-object'
import * as v from 'valibot'
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)
}
Use object mode for partial updates and output: 'array' with elementStream when the caller needs item-by-item results.
import { embed } from '@xsai/embed'
const { embedding, usage } = await embed({
baseURL: 'http://localhost:11434/v1/',
input: 'sunny day at the beach',
model: 'all-minilm',
})
Use embedMany for batch inputs with the same provider and model.