docs: add agent skills (#268)

* docs: add agent skills

* Update skills/xsai/SKILL.md

* Update skills/xsai/SKILL.md

---------

Co-authored-by: 藍+85CD <50108258+kwaa@users.noreply.github.com>
This commit is contained in:
RainbowBirdand藍+85CD authored and GitHub committed 2026-03-08 23:38:18 +08:00
1 parent e23b9da368
commit 4083aa48d9
2 files changed
+304

No files matched your search

+8
View File
@@ -93,6 +93,14 @@ deno install npm:xsai
<!-- /automd -->
### Agent Skills
Install the [xsai skill](https://skills.sh) to your AI coding agent:
```sh
npx skills add moeru-ai/xsai
```
### Getting Started
Read the [documentation](https://xsai.js.org/docs) to get started.
+296
View File
@@ -0,0 +1,296 @@
---
name: xsai
description: >-
Guide for using xsAI — an extra-small AI SDK for OpenAI and OpenAI-compatible APIs.
Use this skill whenever the user imports from 'xsai' or any '@xsai/*' package,
mentions xsai, needs to call OpenAI-compatible APIs with minimal bundle size,
wants generateText/streamText/generateObject/streamObject/tool calling, needs
embeddings, speech synthesis, image generation, or transcription via OpenAI API,
or asks about lightweight alternatives to the Vercel AI SDK (ai package). Also use
when the user needs structured output with Standard Schema (Zod, Valibot, ArkType)
via OpenAI-compatible endpoints.
license: MIT
metadata:
author: moeru-ai
version: "0.4.0"
---
# xsAI
Extra-small AI SDK — a Fetch API wrapper for OpenAI and OpenAI-compatible APIs.
142KB install size vs 5740KB for `ai` (40x smaller). Runtime-agnostic: Browser, Node.js, Deno, Bun, Edge.
## Packages
| Package | Description |
|---------|-------------|
| `xsai` | Umbrella — re-exports everything below |
| `@xsai/generate-text` | Text generation (unary) |
| `@xsai/stream-text` | Text generation (streaming) |
| `@xsai/generate-object` | Structured output (unary) |
| `@xsai/stream-object` | Structured output (streaming) |
| `@xsai/tool` | Tool/function calling helpers |
| `@xsai/embed` | Embeddings |
| `@xsai/generate-image` | Image generation |
| `@xsai/generate-speech` | Text-to-speech |
| `@xsai/generate-transcription` | Speech-to-text (unary) |
| `@xsai/stream-transcription` | Speech-to-text (streaming) |
| `@xsai/utils-chat` | Chat message utilities |
| `@xsai/utils-stream` | Stream utilities |
| `@xsai/utils-reasoning` | Reasoning/thinking utilities |
| `xsschema` | Standard Schema → JSON Schema conversion |
## Common Options
All chat functions share these base options:
```ts
{
model: string // required — model ID
baseURL: string | URL // required — API endpoint (e.g. 'https://api.openai.com/v1/')
apiKey?: string // API key
messages: Message[] // chat history
temperature?: number // 0-2 (default: 1)
topP?: number // (default: 1)
frequencyPenalty?: number // -2.0 to 2.0
presencePenalty?: number // -2.0 to 2.0
seed?: number
stop?: string | string[]
tools?: Tool[]
toolChoice?: 'auto' | 'none' | 'required'
maxSteps?: number // agentic loop steps (default: 1)
abortSignal?: AbortSignal
headers?: Record<string, string>
fetch?: typeof fetch // custom fetch implementation
}
```
## generateText
```ts
import { generateText } from '@xsai/generate-text'
const { text, finishReason, usage, toolCalls, toolResults, steps } = await generateText({
apiKey: env.OPENAI_API_KEY,
baseURL: 'https://api.openai.com/v1/',
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Hello!' },
],
})
```
**Result**: `{ text, finishReason, usage, messages, steps, toolCalls, toolResults, reasoningText }`
## streamText
```ts
import { streamText } from '@xsai/stream-text'
const { textStream, fullStream, messages, usage } = streamText({
apiKey: env.OPENAI_API_KEY,
baseURL: 'https://api.openai.com/v1/',
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Tell me a story' }],
onStepFinish: step => console.log('step done', step),
onFinish: step => console.log('all done'),
})
// Text-only stream
for await (const chunk of textStream) {
process.stdout.write(chunk)
}
// Or full event stream (text-delta, tool-call, tool-result, finish, error)
for await (const event of fullStream) {
if (event.type === 'text-delta') process.stdout.write(event.text)
}
```
**Result**: `{ textStream, fullStream, reasoningTextStream, messages (Promise), steps (Promise), usage (Promise), totalUsage (Promise) }`
## generateObject (Structured Output)
Uses Standard Schema (Zod, Valibot, ArkType, Effect, Sury) for type-safe structured output:
```ts
import { generateObject } from '@xsai/generate-object'
import { object, string, number, array } from 'valibot'
const { object: recipe } = await generateObject({
apiKey: env.OPENAI_API_KEY,
baseURL: 'https://api.openai.com/v1/',
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Give me a cookie recipe' }],
schema: object({ name: string(), ingredients: array(string()), cookTime: number() }),
schemaName: 'recipe',
schemaDescription: 'A cooking recipe',
})
```
Array mode:
```ts
const { object: recipes } = await generateObject({
...options,
output: 'array',
schema: object({ name: string() }),
})
// recipes: { name: string }[]
```
## streamObject
```ts
import { streamObject } from '@xsai/stream-object'
const { partialObjectStream } = await streamObject({
...options,
schema: mySchema,
})
// Object mode — partial objects as they build up
for await (const partial of partialObjectStream) {
console.log(partial) // { name?: string, ... }
}
// Array mode — fully parsed elements one by one
const { elementStream } = await streamObject({ ...options, output: 'array', schema: itemSchema })
for await (const item of elementStream) {
console.log(item)
}
```
## Tool Calling
```ts
import { tool } from '@xsai/tool'
import { description, object, pipe, string } from 'valibot'
const weather = await tool({
name: 'weather',
description: 'Get the weather in a location',
parameters: object({
location: pipe(string(), description('City name')),
}),
execute: ({ location }) => JSON.stringify({ location, temperature: 42 }),
})
const { text } = await generateText({
...options,
tools: [weather],
toolChoice: 'required',
maxSteps: 3, // allow multi-turn tool use
})
```
Raw JSON Schema tools (no schema lib needed):
```ts
import { rawTool } from '@xsai/tool'
const myTool = rawTool({
name: 'lookup',
description: 'Look up a value',
parameters: { type: 'object', properties: { key: { type: 'string' } }, required: ['key'] },
execute: ({ key }) => `value for ${key}`,
})
```
**execute** receives `(input, { messages, toolCallId, abortSignal })`.
## Embeddings
```ts
import { embed, embedMany } from '@xsai/embed'
const { embedding } = await embed({
model: 'text-embedding-3-small',
baseURL: 'https://api.openai.com/v1/',
apiKey: env.OPENAI_API_KEY,
input: 'Hello world',
dimensions: 512,
})
const { embeddings } = await embedMany({
...options,
input: ['Hello', 'World'],
})
```
## Image Generation
```ts
import { generateImage } from '@xsai/generate-image'
const { image, images } = await generateImage({
model: 'dall-e-3',
baseURL: 'https://api.openai.com/v1/',
apiKey: env.OPENAI_API_KEY,
prompt: 'A cat on a skateboard',
size: '1024x1024',
n: 1,
})
// image.base64 — data URL
// image.mimeType — 'image/png' etc.
```
## Speech / Transcription
```ts
import { generateSpeech } from '@xsai/generate-speech'
const audioBuffer = await generateSpeech({
model: 'tts-1',
baseURL: 'https://api.openai.com/v1/',
apiKey: env.OPENAI_API_KEY,
input: 'Hello world',
voice: 'alloy',
responseFormat: 'mp3',
})
```
```ts
import { generateTranscription } from '@xsai/generate-transcription'
const { text } = await generateTranscription({
model: 'whisper-1',
baseURL: 'https://api.openai.com/v1/',
apiKey: env.OPENAI_API_KEY,
file: audioBlob,
})
// Streaming transcription
import { streamTranscription } from '@xsai/stream-transcription'
const { textStream } = streamTranscription({ ...options, file: audioBlob })
for await (const chunk of textStream) {
process.stdout.write(chunk)
}
```
## Message Types
```ts
type Message =
| { role: 'system', content: string }
| { role: 'developer', content: string }
| { role: 'user', content: string | ContentPart[] }
| { role: 'assistant', content?: string, tool_calls?: ToolCall[], reasoning?: string }
| { role: 'tool', tool_call_id: string, content: string }
```
## Key Rules
1. **`model` and `baseURL` are always required** — xsAI is provider-agnostic, no defaults
2. **Standard Schema for structured output** — Zod, Valibot, ArkType, Effect all work. Use `xsschema` for conversion
3. **`streamText` is synchronous** — it returns immediately, streams resolve lazily. `streamObject` is async (needs schema conversion)
4. **`maxSteps`** enables agentic tool-use loops — each step makes a new API call with tool results appended
5. **No Node.js deps** — pure Fetch API, works everywhere including Edge Runtime
6. **Install granularly** — `@xsai/generate-text` alone is 22.6KB; use the umbrella `xsai` package only if you need most features
## Documentation
Read the full docs at https://xsai.js.org/docs or use context7 to query `xsai` documentation.