SDK · TypeScript
权威实现,基于
frontend/src/volo-ai-ctrl-kit。所有其他语言 SDK 以本 SDK 接口为契约源。
安装
bash
npm install @volo-ai/sdkbash
pnpm add @volo-ai/sdkbash
yarn add @volo-ai/sdk包发布状态
@volo-ai/sdk npm 包目前 未公开发布。当前权威源在仓库 frontend/src/volo-ai-ctrl-kit/,可作 git submodule 引入。
[TODO: npm 包公开发布时间待定]
初始化
ts
import { VoloClient } from '@volo-ai/sdk'
const client = new VoloClient({
apiKey: process.env.VOLO_API_KEY!,
baseURL: 'https://api.volo.ai',
timeout: 30000,
})| 选项 | 默认值 | 说明 |
|---|---|---|
apiKey | — | 必填,控制台获取 |
baseURL | https://api.volo.ai | 自托管时可改 |
timeout | 30000 | 非流式请求超时(ms) |
retry | { maxAttempts: 3 } | 自动重试策略 |
fetch | globalThis.fetch | 自定义 fetch 实现(用于 SSR) |
1 · Chat · 流式对话
基础对话
ts
const stream = await client.chat.stream({
sessionId: crypto.randomUUID(),
userMessage: '你好,请用一句话介绍 VOLO AI',
executionMode: 'AUTO',
})
for await (const event of stream) {
if (event.type === 'ASSISTANT_DELTA') {
process.stdout.write(event.content)
}
}完整事件处理
ts
import type { AgentEvent } from '@volo-ai/sdk'
for await (const event of stream) {
switch (event.type) {
case 'PROGRESS':
console.log(`[进度] ${event.message}`)
break
case 'ASSISTANT_DELTA':
process.stdout.write(event.content)
break
case 'TOOL_START':
console.log(`\n[工具] 调用 ${event.toolName}...`)
break
case 'TOOL_END':
console.log(`[工具] ${event.toolName} 完成`)
break
case 'RENDER_UI':
// event.uiComponentType: 27 种之一
console.log(`[UI] 渲染 ${event.uiComponentType}`)
break
case 'INTERACTION':
// AI 需要用户响应
const userInput = await prompt(event.message)
await client.chat.respond({
turnId: event.turnId,
response: userInput,
})
break
case 'ERROR':
console.error(`[错误] ${event.message}`)
break
case 'COMPLETE':
console.log('\n[完成]')
break
}
}停止生成
ts
await client.chat.stop({ sessionId })流中追加上下文(G1)
ts
// 在 streaming 期间另一协程调用
await client.chat.append({
sessionId,
appendedText: '顺便加个夜间模式',
})
// 不打断流,下一轮 prompt 自动带上恢复执行(HITL)
ts
const resumeStream = await client.chat.resume({
turnId: pendingTurnId,
response: '选择 B 方案',
})
for await (const event of resumeStream) { /* ... */ }工具审批
ts
await client.chat.approveToolCall({
toolCallId,
turnId,
approved: true,
reason: '用户已确认',
})2 · Memory · 记忆相册
上传
ts
import { readFileSync } from 'node:fs'
const file = new File(
[readFileSync('/path/to/photo.jpg')],
'photo.jpg',
{ type: 'image/jpeg' }
)
const memory = await client.memory.upload({
file,
userTitle: '春节家宴',
userDescription: '2026 春节,全家在北京聚餐',
})
console.log(memory.memoryId, memory.thumbnailUrl)列出
ts
const page = await client.memory.list({ page: 0, pageSize: 20 })
page.items.forEach((m) => console.log(m.userTitle, m.createdAt))
console.log('共', page.total, '条,还有', page.hasMore ? '更多' : '没了')语义搜索
ts
const results = await client.memory.search({
query: '春节',
topK: 10,
minScore: 0.6,
})删除
ts
await client.memory.delete(memoryId)3 · Skill · 技能市场
列出
ts
const page = await client.skill.list({
page: 0,
pageSize: 20,
category: 'design',
keyword: 'critique',
})获取详情
ts
const skill = await client.skill.get(skillId)
const markdown = await client.skill.getContent(skillId)
const byName = await client.skill.getByName('h-frontend-design')安装/卸载
ts
await client.skill.install(skillId)
await client.skill.uninstall(skillId)我已安装
ts
const mySkills = await client.skill.listMine({ page: 0, pageSize: 50 })Skill Package · 子技能开关
ts
const children = await client.skill.getChildren(packageId)
await client.skill.toggleChild({
packageId,
childSkillId,
enabled: false,
})在对话中触发
直接在 userMessage 中带 /skill-name:
ts
await client.chat.stream({
sessionId,
userMessage: '/h-frontend-design 设计一个登录页',
executionMode: 'MAX',
})4 · Auth · 鉴权
ts
// 登录
const { accessToken, refreshToken, user } = await client.auth.loginByEmail({
email: 'user@example.com',
code: '123456',
})
// 刷新 Token(SDK 自动处理,也可手动)
const tokens = await client.auth.refresh(refreshToken)
// 登出
await client.auth.logout()高级:volo-ai-ctrl-kit 集成
volo-ai-ctrl-kit 是 VOLO AI 前端操控 SDK,让 AI 看见并操控页面元素。在 Vue 项目中使用:
ts
// main.ts
import { createCtrlKit } from '@volo-ai/sdk/vue'
app.use(createCtrlKit({
security: {
maxActionsPerMinute: 30,
requireConfirmFor: ['delete', 'submit'],
}
}))vue
<!-- 组件中 -->
<button v-ctrl:button="'发送'" @click="handleSend">发送</button>
<script setup>
import { useCtrl } from '@volo-ai/sdk/vue'
const { register } = useCtrl()
register({
id: 'chat-input-bar',
name: '消息输入区',
role: 'chat',
operations: {
type: { execute: ({ text }) => inputValue.value = text },
send: { execute: () => handleSend() },
},
})
</script>完整文档:frontend/src/volo-ai-ctrl-kit/README.md(仓库内)。
类型定义
所有事件、请求、响应都有完整 TypeScript 类型:
ts
import type {
AgentEvent,
ChatRequest,
ExecutionMode,
EventType,
MemoryVO,
SkillVO,
UIComponentType,
CtrlContext,
CtrlCommand,
} from '@volo-ai/sdk'EventType / UIComponentType 等枚举与后端 AgentExecutionEvent.java 单一权威源同步生成(不允许自创字符串,违反 VOLO_AI_PROTOCOL_SPEC)。
浏览器使用
SDK 支持浏览器环境(fetch + ReadableStream),但 API Key 不应暴露到前端——推荐通过 BFF 转发:
Browser → Your BFF → VOLO AI
↑ API Key 留在服务端