0%

opencode 官方文档学习(2):开发

这篇文章继续学习 OpenCode 的官方文档,学习基于 OpenCode 进行二次开发,从而对 OpenCode 进行二次扩展。

SDK

opencode JS/TS SDK 提供了一个类型安全的客户端,用于与服务器进行交互。 你可以用它来构建集成方案,并以编程方式控制 opencode。

  • 通过如下方式安装 SDK
1
npm install @opencode-ai/sdk
  • 创建一个 opencode 实例:这会同时启动服务器和客户端
1
2
3
import { createOpencode } from "@opencode-ai/sdk"

const { client } = await createOpencode()
  • 你可以传入一个配置对象来自定义行为。实例仍然会读取你的 opencode.json,但你可以通过内联方式覆盖或添加配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
import { createOpencode } from "@opencode-ai/sdk"

const opencode = await createOpencode({
hostname: "127.0.0.1",
port: 4096,
config: {
model: "anthropic/claude-3-5-sonnet-20241022",
},
})

console.log(`Server running at ${opencode.server.url}`)

opencode.server.close()
  • 如果你已经有一个正在运行的 opencode 实例,可以创建一个客户端实例来连接它:
1
2
3
4
5
import { createOpencodeClient } from "@opencode-ai/sdk"

const client = createOpencodeClient({
baseUrl: "http://localhost:4096",
})

SDK 通过类型安全的客户端暴露所有服务器 API,具体参见 SDK

如下是使用opencode SDK 的一个完整例子,它使用了自定义 provider 来提供 model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { createOpencode } from "@opencode-ai/sdk"

async function main() {
const { client, server } = await createOpencode({
config: {
model: "chaitin/glm-4.7",
provider: {
chaitin: {
name: "chaitin",
options: {
apiKey: "your api key",
baseURL: "your base url",
},
models: {
"glm-4.7": {
name: "GLM-4.7",
},
},
},
},
}
})

console.log("Server started at:", server.url)

const session = await client.session.create({
body: { title: "Test Session" },
})

console.log("Session:", session.data.id)

const result = await client.session.prompt({
path: { id: session.data.id },
body: {
parts: [{ type: "text", text: "中国首都在哪里?" }],
},
})

console.log("\n回复:", JSON.stringify(result, null, 2))

server.close()
}

main().catch(console.error)

服务器

当你运行 opencode 时,它会启动一个 TUI 和一个服务器。TUI 是与服务器通信的客户端。服务器暴露一个 OpenAPI 3.1 规范端点。该端点也用于生成 SDK。这种架构让 opencode 支持多个客户端,并允许你以编程方式与 opencode 交互

你可以运行 opencode serve 来启动一个独立的服务器。如果你已经在运行 opencode TUI,opencode serve 会启动一个新的服务器。服务器暴露的具体 API 可以参考这里

插件

插件允许你通过挂钩各种事件和自定义行为来扩展 OpenCode。你可以创建插件来添加新功能、集成外部服务,或修改 OpenCode 的默认行为。

有两种方式加载插件。

  • 从本地文件加载:将 JavaScript 或 TypeScript 文件放置在插件目录中,这些目录中的文件会在启动时自动加载。

    • .opencode/plugins/ - 项目级插件
    • ~/.config/opencode/plugins/ - 全局插件
  • 从 npm 加载:在配置文件中指定 npm 包,支持常规和带作用域的 npm 包

1
2
3
4
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}

npm 插件在启动时使用 Bun 自动安装。包及其依赖项会缓存在 ~/.cache/opencode/node_modules/ 中。本地插件直接从插件目录加载。如果需要使用外部包,你必须在配置目录中创建 package.json,或者将插件发布到 npm 并将其添加到配置中。

插件从所有来源加载,所有钩子按顺序执行。加载顺序为:

  • 全局配置 (~/.config/opencode/opencode.json)
  • 项目配置 (opencode.json)
  • 全局插件目录 (~/.config/opencode/plugins/)
  • 项目插件目录 (.opencode/plugins/)

创建插件

插件是一个 JavaScript/TypeScript 模块,它导出一个或多个插件函数。每个函数接收一个上下文对象,并返回一个钩子对象。

  • 本地插件和自定义工具可以使用外部 npm 包。在配置目录中添加一个 package.json,列出所需的依赖项。
  • OpenCode 会在启动时运行 bun install 来安装这些依赖项。之后你的插件和工具就可以导入它们了

如下是一个插件的基本结构:

1
2
3
4
5
6
7
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")

return {
// Hook implementations go here
}
}

插件函数接收以下参数:

  • project:当前项目信息
  • directory:当前工作目录
  • worktree:git 工作树路径
  • client:用于与 AI 交互的 OpenCode SDK 客户端
  • $:Bun 的 Shell API,用于执行命令

插件可以订阅事件,这里是具体的事件列表

生态系统

这里介绍了基于 OpenCode 构建的社区项目合集。除此之外,您还可以查看 awesome-opencodeopencode.cafe,这是一个聚合生态系统与社区资源的社区。