Skip to content

5.10c SDK V2:下一代 API

一句话总结:V2 是 OpenCode SDK 的下一代入口,引入 client.v2.* 命名空间、独立的 Permission/Question 模块,以及 Session3 的 interrupt/wait/compact 等增强方法。

⚠️ 实验性功能

V2 入口(@opencode-ai/sdk/v2)当前标记为实验性,API 签名可能随版本变化。生产环境建议继续用 V1(@opencode-ai/sdk)。本章基于源码 packages/sdk/js/src/v2/,版本 1.17.14,以源码为准。


学完你能做什么

  • 区分 V1 和 V2,知道什么时候用哪个
  • @opencode-ai/sdk/v2 创建客户端
  • 理解 client.*client.v2.* 两层访问路径
  • 使用 Permission、Question 独立模块
  • 调用 Session3 的增强方法(interrupt、wait、compact 等)
  • 从 V1 迁移到 V2

V2 是什么

V1 和 V2 的定位

OpenCode SDK 包(@opencode-ai/sdk)通过 package.jsonexports 暴露两个入口:

入口路径版本状态适合谁
@opencode-ai/sdkV1稳定大多数用户、生产环境
@opencode-ai/sdk/v2V2实验性需要新能力、愿意跟随变化的进阶用户

来源:packages/sdk/js/package.json:12-21

V2 重新设计了 API 结构,和 V1 不完全兼容。在 V2 稳定前,两个入口并存。

V2 的两层客户端结构(重要)

V2 客户端最大的特点是两层访问路径,理解这个就理解了 V2 的核心:

client                         OpencodeClient(27 个模块)
├── session  → Session2        旧路由 /session/*(基础方法)
├── permission → Permission    /permission/*(跨 session 权限)
├── question → Question        /question/*(跨 session 提问)
├── part     → Part            消息部件 CRUD
├── sync     → Sync            workspace 同步
├── worktree → Worktree        git worktree
├── experimental → Experimental 实验功能集合
├── ...
└── v2       → V2              新路由 /api/* 命名空间(17 个子模块)
    ├── session    → Session3  /api/session/*(增强方法)
    ├── permission → Permission3 /api/session/{}/permission
    ├── question   → Question3 /api/session/{}/question
    ├── health     → Health    /api/health
    ├── agent      → Agent     /api/agent
    ├── model      → Model     /api/model
    ├── fs         → Fs        /api/fs/*
    └── ...

关键区分

访问路径路由用途
client.sessionSession2/session/*基础方法(list/create/prompt)
client.v2.sessionSession3/api/session/*增强方法(interrupt/wait/compact/switchModel)
client.permissionPermission/permission/*跨 session 权限管理
client.v2.permissionPermission3/api/session/{}/permissionsession 级权限

来源:sdk.gen.ts:6990-7075(V2 类定义)、sdk.gen.ts:7077-7219(OpencodeClient 定义)

一句话记忆

增强的 session 方法在 client.v2.session,不是 client.sessionclient.session 是兼容旧路由的基础方法。

参数风格:平铺(不是嵌套)

V2 所有方法的参数都是平铺的,不再用 V1 的 { path: {...}, body: {...} } 嵌套结构。框架内部用 buildClientParams 自动把字段分发到 path/query/body。

typescript
// ❌ V1 风格(V2 中不适用)
client.permission.reply({
  path: { requestID: "req-1" },
  body: { response: "always" },
})

// ✅ V2 风格(平铺)
client.permission.reply({
  requestID: "req-1",
  reply: "always",
})

来源:sdk.gen.ts:3121-3144buildClientParams 自动分发)


开始使用 V2

安装

V2 和 V1 在同一个 npm 包里,不需要额外安装:

bash
npm install @opencode-ai/sdk

创建客户端

typescript
import { createOpencodeClient } from "@opencode-ai/sdk/v2"

const client = createOpencodeClient({
  baseUrl: "http://localhost:4096",
  directory: "/path/to/my-project",        // 项目目录
  experimental_workspaceID: "ws-123",      // 可选:workspace 标识
})

客户端配置参数

参数类型说明
baseUrlstring服务器 URL,默认 http://localhost:4096
directorystring项目目录,通过 X-Opencode-Directory header 传递
experimental_workspaceIDstringworkspace 标识,通过 X-Opencode-Workspace header 传递
fetchfunction自定义 fetch 实现
headersobject自定义请求头

来源:v2/client.ts:50-92

directory 和 workspaceID 怎么传递的?

directory 被编码后放入 X-Opencode-Directory header,experimental_workspaceID 放入 X-Opencode-Workspace header。客户端拦截器还会把它们改写进 query string(/api/* 路由用 location[directory] 参数),确保多项目隔离。


OpencodeClient 27 个模块总览

V2 的 OpencodeClient 暴露 27 个模块属性。

来源:sdk.gen.ts:7077-7219

兼容 V1 的模块(19 个)

global project pty config tool instance path vcs command provider find file app mcp lsp formatter tui auth event

这些模块和 V1 基本一致,用法参考 5.10b API 参考

V2 新增/增强的模块(8 个)

模块访问路径说明
sessionclient.session / client.v2.session两层:Session2 基础 + Session3 增强
permissionclient.permission跨 session 权限管理
questionclient.question跨 session 提问管理
partclient.part消息部件 CRUD
syncclient.syncworkspace 同步
worktreeclient.worktreegit worktree 管理
experimentalclient.experimental实验功能集合
v2client.v2/api/* 新路由命名空间(17 个子模块)

下面逐一详解。


V2 核心新能力详解

1. Permission 独立模块

V1 响应权限请求要用超长的 postSessionIdPermissionsPermissionId(),且只能响应特定 session 的请求。V2 把权限管理提升为独立模块,支持跨 session 查询和响应。

方法路由说明
permission.list()GET /permission列出所有 session 的待处理权限请求
permission.reply()POST /permission/{requestID}/reply响应权限请求
permission.respond()POST /session/{sessionID}/permissions/{permissionID}⚠️ 已废弃,用 reply 代替

来源:sdk.gen.ts:3085-3193

typescript
// 列出所有待处理的权限请求(跨 session)
const pending = await client.permission.list()
for (const request of pending.data ?? []) {
  console.log(`[${request.sessionID}] ${request.permission}: ${request.patterns.join(", ")}`)
}

// 响应某个权限请求(注意:字段名是 reply,不是 response)
await client.permission.reply({
  requestID: "req-123",
  reply: "always",     // "once" | "always" | "reject"
})

字段名注意

reply() 方法的 body 字段名是 reply(不是 response)。response 是已废弃的 respond() 方法的字段名。

和 V1 的对比

操作V1V2
列出权限请求❌ 不支持permission.list()
响应权限postSessionIdPermissionsPermissionId({path:{id,permissionID},body:{response}})permission.reply({requestID, reply})
跨 session 查询

2. Question 独立模块

Agent 可以通过 question 工具向你提问。V1 没有统一管理接口,V2 新增独立模块。

方法路由说明
question.list()GET /question列出所有待回答的提问
question.reply()POST /question/{requestID}/reply回答提问
question.reject()POST /question/{requestID}/reject拒绝提问

来源:sdk.gen.ts:2982-3084

typescript
// 查看所有待回答的提问
const questions = await client.question.list()
for (const q of questions.data ?? []) {
  console.log(`[${q.sessionID}] ${q.questions[0]?.header ?? "(no question)"}`)
}

// 回答某个提问
await client.question.reply({
  requestID: "q-456",
  answers: [["选项 A"]],
})

// 拒绝提问
await client.question.reject({ requestID: "q-456" })

权限和提问的区别

  • Permission:Agent 要执行某个操作(如运行命令、编辑文件),请求你授权。
  • Question:Agent 需要信息(如选择方案、确认偏好),向你提问。

3. Session 增强(client.v2.session)

这是 V2 最容易踩坑的地方。增强的 session 方法在 client.v2.session(Session3 类),不是 client.session(Session2 类)。

Session2(client.session):兼容旧路由 /session/*,有 list/create/prompt/messages 等基础方法。

Session3(client.v2.session):新路由 /api/session/*,新增一组控制方法。

来源:sdk.gen.ts:5426-5875(Session3 类)

Session3 新增方法

方法路由说明
interrupt()POST /api/session/{sessionID}/interrupt中断当前执行
wait()POST /api/session/{sessionID}/wait等待 session 空闲
compact()POST /api/session/{sessionID}/compact触发上下文压缩
context()GET /api/session/{sessionID}/context获取当前上下文
history()GET /api/session/{sessionID}/history获取历史记录
switchModel()POST /api/session/{sessionID}/model切换模型
switchAgent()POST /api/session/{sessionID}/agent切换 agent
events()GET /api/session/{sessionID}/eventsession 级事件流
typescript
const sessionID = "sess-abc"

// 注意:这些方法都在 client.v2.session(Session3)
await client.v2.session.interrupt({ sessionID })
await client.v2.session.wait({ sessionID })
await client.v2.session.compact({ sessionID })

// 切换模型
await client.v2.session.switchModel({
  sessionID,
  model: { providerID: "anthropic", id: "claude-sonnet-4-20250514" },
})

// 切换 agent
await client.v2.session.switchAgent({ sessionID, agent: "plan" })

// 获取上下文
const ctx = await client.v2.session.context({ sessionID })

最常见的坑

把增强方法写在 client.session 上会报错。记住:

  • client.session.prompt() ✅(基础方法在 Session2)
  • client.v2.session.interrupt() ✅(增强方法在 Session3)
  • client.session.interrupt() ❌(Session2 没有这个方法)

4. Part 模块(消息部件 CRUD)

V2 新增了对消息部件(Part)的细粒度操作。一条消息由多个 Part 组成,V2 支持删除和更新单个 Part。

方法路由说明
part.delete()DELETE /session/{sessionID}/message/{messageID}/part/{partID}删除部件
part.update()PATCH /session/{sessionID}/message/{messageID}/part/{partID}更新部件

来源:sdk.gen.ts:4330-4406

typescript
// 更新某个文本部件
await client.part.update({
  sessionID: "sess-abc",
  messageID: "msg-1",
  partID: "part-3",
  part: { type: "text", text: "修改后的内容" },
})

// 删除某个部件
await client.part.delete({
  sessionID: "sess-abc",
  messageID: "msg-1",
  partID: "part-3",
})

5. Sync 模块(workspace 同步)

Sync 是 V2 的多 workspace 事件同步机制。

方法路由说明
sync.start()POST /sync/start启动同步循环
sync.replay()POST /sync/replay回放同步事件
sync.steal()POST /sync/steal将 session 转移到当前 workspace
sync.history.list()POST /sync/history列出同步事件历史

来源:sdk.gen.ts:4448-4576(Sync 类)、4413-4447(History 类)

注意

sync.history 是一个 getter 属性(返回 History 类实例),不是方法。要调用 sync.history.list()

typescript
// 启动同步
await client.sync.start()

// 查看同步事件历史(history 是 getter,再调 list)
const history = await client.sync.history.list({
  body: { "sess-abc": 10 },  // 返回 seq > 10 的事件
})
Sync 是什么场景用的?

当你同时在多个 workspace 运行 OpenCode,session 可能需要在不同 workspace 间迁移。Sync 提供事件日志机制,确保迁移可追溯、可回放。这是为未来的分布式/集群场景设计的,单机用户一般用不到。

6. Worktree 模块(git worktree 管理)

V2 新增了 git worktree 的完整管理接口。

方法路由说明
worktree.list()GET /experimental/worktree列出所有 worktree
worktree.create()POST /experimental/worktree创建 worktree
worktree.remove()DELETE /experimental/worktree删除 worktree 及分支
worktree.reset()POST /experimental/worktree/reset重置到默认分支

来源:sdk.gen.ts:1582-1724

typescript
// 列出所有 worktree
const worktrees = await client.worktree.list()

// 创建新 worktree
await client.worktree.create({
  worktreeCreateInput: { branch: "feature-experiment" },
})

// 删除
await client.worktree.remove({
  worktreeRemoveInput: { branch: "feature-experiment" },
})

和 5.25 Git Worktree 课程的关系

本节是 SDK 编程接口。手动使用 worktree 请参考 5.25 Git Worktree 工作流

7. Experimental 模块集合

client.experimental 是聚合模块,包含 workspace、resource、capabilities、console、control-plane 等前沿功能。

子功能路由前缀说明
workspace/experimental/workspace多工作空间管理
resource/experimental/resourceMCP 资源查询
capabilities/experimental/capabilities能力声明
console/experimental/console控制台(组织切换)
controlPlane/experimental/control-plane控制平面(session 迁移)
session/experimental/session实验性会话(background 子代理)

来源:sdk.gen.ts:1243-1317

实验性 session 的 background 方法可以把阻塞的子代理转为后台执行:

typescript
// 把阻塞的子代理转到后台继续运行
await client.experimental.session.background({ sessionID: "sess-abc" })

完整示例:用 V2 构建自动化助手

typescript
import { createOpencodeClient } from "@opencode-ai/sdk/v2"

const client = createOpencodeClient({
  baseUrl: "http://localhost:4096",
  directory: "/path/to/my-project",
})

async function runTask(task: string) {
  // 1. 创建 session(client.session 是 Session2,基础方法)
  const session = await client.session.create({
    title: task.slice(0, 50),
    agent: "build",
  })
  const sessionID = session.data!.id

  // 2. 异步发送任务(平铺参数)
  await client.session.promptAsync({
    sessionID,
    parts: [{ type: "text", text: task }],
    model: { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" },
  })

  // 3. 轮询权限请求,自动允许只读操作
  const poll = setInterval(async () => {
    const pending = await client.permission.list()
    for (const req of pending.data ?? []) {
      // permission 是操作类型(如 "read"、"grep"),patterns 是匹配模式
      if (req.permission === "read" || req.permission === "grep") {
        await client.permission.reply({
          requestID: req.id,
          reply: "always",   // 注意字段名是 reply
        })
      }
    }
  }, 1000)

  // 4. 等待 session 完成(增强方法在 client.v2.session)
  await client.v2.session.wait({ sessionID })
  clearInterval(poll)

  // 5. 获取结果(基础方法回到 client.session)
  const messages = await client.session.messages({ sessionID })
  const last = messages.data?.at(-1)

  // 6. 读取 Token 消耗和费用(V1/V2 都支持)
  if (last?.info.role === "assistant") {
    console.log(`费用: $${last.info.cost}`)
    console.log(`Token: 输入 ${last.info.tokens.input} / 输出 ${last.info.tokens.output}`)
  }

  return last
}

const result = await runTask("分析项目结构并生成 README")
console.log(result)

核心要点:基础方法(create/promptAsync/messages)在 client.session,增强方法(wait/interrupt/compact)在 client.v2.session。混用时注意切换路径。


V1 → V2 迁移指南

导入路径

typescript
// V1
import { createOpencodeClient } from "@opencode-ai/sdk"

// V2
import { createOpencodeClient } from "@opencode-ai/sdk/v2"

参数结构

typescript
// V1:嵌套结构
await client.session.create({ body: { title: "xxx" } })
await client.session.prompt({ path: { id: "sess-1" }, body: { parts: [...] } })

// V2:平铺结构
await client.session.create({ title: "xxx" })
await client.session.prompt({ sessionID: "sess-1", parts: [...] })

权限响应

typescript
// V1:超长方法名 + 嵌套参数
await client.postSessionIdPermissionsPermissionId({
  path: { id: sessionID, permissionID: "perm-1" },
  body: { response: "always" },
})

// V2:独立模块 + 平铺参数
await client.permission.reply({
  requestID: "req-1",
  reply: "always",   // 字段名变了:response → reply
})

会话控制

typescript
// V1:没有 interrupt/wait/compact

// V2:增强方法在 client.v2.session
await client.v2.session.interrupt({ sessionID })
await client.v2.session.wait({ sessionID })
await client.v2.session.compact({ sessionID })
await client.v2.session.switchModel({ sessionID, model: { ... } })
await client.v2.session.switchAgent({ sessionID, agent: "plan" })

能力对照表

功能V1V2
权限响应postSessionIdPermissionsPermissionIdpermission.reply
权限列表permission.list
提问管理question.list/reply/reject
中断会话v2.session.interrupt
等待完成❌(自己轮询)v2.session.wait
触发压缩v2.session.compact
切换模型v2.session.switchModel
切换 agentv2.session.switchAgent
消息部件 CRUDpart.update/delete
worktreeworktree.list/create/remove/reset
workspace 同步sync.start/replay/steal/history.list

踩坑提醒

现象原因解决
createOpencodeClient is not exported导入路径错了V2 用 @opencode-ai/sdk/v2
client.session.interrupt is not a function用错了访问路径增强方法在 client.v2.session
参数报类型错误用了 V1 的 {path, body} 嵌套V2 参数全部平铺
permission.reply 报字段错误字段名写成了 responseV2 字段名是 reply
sync.history is not a functionhistory 是 getter 不是方法调用 sync.history.list()
请求返回 HTML连的是 V1 服务器,不支持 /api/*确认服务器版本支持 V2
V2 方法签名和文档不一致V2 是实验性,API 会变以源码 sdk.gen.ts 为准
v2.session.wait 一直阻塞session 一直在运行v2.session.interrupt 或设超时

本课小结

你学会了:

  1. V2 定位:实验性下一代 API,和 V1 并存于同一个 npm 包
  2. 两层结构client.*(基础 + 新概念)和 client.v2.*(/api/* 新路由)
  3. 参数风格:全部平铺,不是 V1 的嵌套
  4. 核心新能力:Permission/Question 独立模块、Session3 增强方法(在 client.v2.session)、Part CRUD、Sync、Worktree
  5. 迁移要点:导入路径、参数结构、权限字段名、session 访问路径的差异

相关资源


附录:源码参考

点击展开查看源码位置

更新时间:2026-07-07

功能文件路径行号
V2 入口(exports 配置)packages/sdk/js/package.json12-21
V2 index(createOpencode)packages/sdk/js/src/v2/index.ts1-23
V2 客户端(createOpencodeClient)packages/sdk/js/src/v2/client.ts50-92
V2 服务器(ServerOptions)packages/sdk/js/src/v2/server.ts5-30
OpencodeClient 27 模块sdk.gen.ts7077-7219
V2 命名空间(17 子模块)sdk.gen.ts6990-7075
Permission 模块sdk.gen.ts3085-3193
Question 模块sdk.gen.ts2982-3084
Session3 模块(增强方法)sdk.gen.ts5426-5875
Session2 模块(基础方法)sdk.gen.ts3362-4329
Part 模块(update/delete)sdk.gen.ts4330-4406
Sync 模块 + History 类sdk.gen.ts4413-4576
Worktree 模块sdk.gen.ts1582-1724
Workspace 模块(experimental)sdk.gen.ts1006-1242
Experimental 模块(聚合)sdk.gen.ts1243-1317

关键类

  • OpencodeClient:V2 客户端主类,27 个模块属性
  • V2client.v2 命名空间,17 个 /api/* 子模块
  • Session2client.session):旧路由基础方法
  • Session3client.v2.session):新路由增强方法(interrupt/wait/compact/switchModel/switchAgent)
  • Permissionclient.permission):跨 session 权限管理
  • Questionclient.question):跨 session 提问管理

注意packages/client/@opencode-ai/client)是私有包,基于 Effect HttpApi 生成,非公开 SDK,不在本章范围。