Skip to content

SDK · TypeScript

权威实现,基于 frontend/src/volo-ai-ctrl-kit。所有其他语言 SDK 以本 SDK 接口为契约源。


安装

bash
npm install @volo-ai/sdk
bash
pnpm add @volo-ai/sdk
bash
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必填,控制台获取
baseURLhttps://api.volo.ai自托管时可改
timeout30000非流式请求超时(ms)
retry{ maxAttempts: 3 }自动重试策略
fetchglobalThis.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 留在服务端

相关

Released under the Proprietary License.