Appearance
关键代码验证
会话生命周期管理
OpenCode 的会话生命周期管理是其核心能力之一,完整的生命周期包括创建、使用、压缩、共享、删除等阶段。本节通过概念性代码展示如何使用 SDK 和 API 管理会话。
创建会话
使用 SDK 创建新会话:
typescript
import { createOpencode } from "@opencode-ai/sdk"
const opencode = await createOpencode()
// 创建新会话
const session = await opencode.client.session.create({
body: {
title: "新功能开发",
parentID: undefined // 可选:创建子会话时指定父会话 ID
}
})
console.log("会话 ID:", session.data.id)会话操作与会话
从现有会话创建分支:
typescript
// 在指定消息处 fork 会话
const forkedSession = await opencode.client.session.fork({
path: { id: session.data.id },
body: {
messageID: "msg-123" // 可选:从特定消息处分支
}
})发送消息
同步发送消息并等待响应:
typescript
const result = await opencode.client.session.prompt({
path: { id: session.data.id },
body: {
model: {
providerID: "anthropic",
modelID: "claude-3-5-sonnet-20241022"
},
agent: "build", // 使用 build 代理
parts: [
{
type: "text",
text: "创建一个简单的 Express 服务器"
}
]
}
})异步发送消息(不等待响应):
typescript
await opencode.client.session.prompt({
path: { id: session.data.id },
body: {
noReply: true, // 仅注入上下文,不触发 AI 响应
parts: [
{
type: "text",
text: "系统上下文:这是一个 Node.js 项目"
}
]
}
})会话状态管理
获取会话状态:
typescript
// 获取单个会话
const sessionDetail = await opencode.client.session.get({
path: { id: session.data.id }
})
// 获取所有会话
const allSessions = await opencode.client.session.list()
// 获取会话状态
const status = await opencode.client.session.status()
// 返回: { [sessionID: string]: SessionStatus }会话压缩 (Compaction)
会话压缩是 OpenCode 的关键特性,用于管理长时间会话的 token 消耗:
typescript
// 压缩会话(自动进行)
// 当会话消息达到一定长度时,OpenCode 会自动压缩
// 保留重要上下文,移除冗余信息
// 自定义压缩行为(通过插件)
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// 注入额外上下文
output.context.push(`
## 项目上下文
- 项目名称: ${ctx.project.name}
- 当前任务: 实现用户认证功能
- 重要文件:
- src/auth/auth.service.ts
- src/auth/auth.controller.ts
`)
// 或者完全替换压缩提示
// output.prompt = "自定义压缩提示..."
}
}
}会话共享与取消共享
typescript
// 共享会话
const sharedSession = await opencode.client.session.share({
path: { id: session.data.id }
})
// 获取共享链接
console.log("共享链接:", sharedSession.data.shareUrl)
// 取消共享
await opencode.client.session.unshare({
path: { id: session.data.id }
})会话历史与 Diff
typescript
// 获取会话 diff
const diff = await opencode.client.session.diff({
path: { id: session.data.id },
query: { messageID: "msg-123" } // 可选:从特定消息开始
})
// diff 包含所有文件变更
console.log("文件变更数:", diff.data.length)删除会话
typescript
// 删除会话及其所有数据
await opencode.client.session.delete({
path: { id: session.data.id }
})子代理生命周期
子代理由主代理调用,用于处理特定任务。
调用子代理
typescript
// 方式 1: 使用 @ 提及(在用户消息中)
// 用户输入: "@general 搜索这个函数"
// 方式 2: 主代理自动调用(基于任务描述)
// 方式 3: 通过 SDK 调用
const result = await opencode.client.session.command({
path: { id: session.data.id },
body: {
command: "general",
arguments: {
query: "搜索这个函数"
}
}
})子代理事件监听
typescript
// 监听子代理创建
const events = await opencode.client.event.subscribe()
for await (const event of events.stream) {
if (event.type === "session.created") {
console.log("新子代理会话创建:", event.properties.sessionID)
}
}工具生命周期
工具由代理调用,执行具体操作。
自定义工具
typescript
import { tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin = async (ctx) => {
return {
tool: {
// 创建自定义工具
database: tool({
description: "查询数据库",
args: {
query: tool.schema.string(),
limit: tool.schema.number().optional()
},
async execute(args, ctx) {
// 执行数据库查询
const results = await queryDatabase(args.query, args.limit)
return results
}
}),
// 自定义 API 调用工具
apiCall: tool({
description: "调用外部 API",
args: {
url: tool.schema.string(),
method: tool.schema.enum(["GET", "POST"]),
body: tool.schema.any().optional()
},
async execute(args, ctx) {
const response = await fetch(args.url, {
method: args.method,
body: JSON.stringify(args.body)
})
return await response.json()
}
})
}
}
}工具执行事件
typescript
export const ToolLoggerPlugin = async (ctx) => {
return {
"tool.execute.before": async (input, output) => {
console.log("工具执行前:", input.tool, output.args)
},
"tool.execute.after": async (input, output) => {
console.log("工具执行后:", input.tool, output.result)
}
}
}配置生命周期
配置在启动时加载,可以在运行时更新。
更新配置
typescript
// 获取当前配置
const config = await opencode.client.config.get()
// 更新配置
await opencode.client.config.patch({
body: {
model: "anthropic/claude-3-5-sonnet-20241022",
agent: {
build: {
temperature: 0.3,
maxSteps: 50
}
}
}
})插件生命周期
插件在启动时加载,可以监听各种事件。
基本插件结构
typescript
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async (ctx) => {
const { project, client, $, directory, worktree } = ctx
// 插件初始化逻辑
console.log("插件初始化:", project.name)
return {
// 会话创建时触发
"session.created": async (input, output) => {
await client.app.log({
service: "my-plugin",
level: "info",
message: `会话创建: ${output.sessionID}`
})
},
// 会话空闲时触发
"session.idle": async (input, output) => {
console.log("会话完成:", output.sessionID)
},
// 文件编辑时触发
"file.edited": async (input, output) => {
console.log("文件编辑:", output.filePath)
}
}
}插件配置
在 opencode.json 中配置插件:
json
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"opencode-helicone-session",
"opencode-wakatime",
"@my-org/custom-plugin"
]
}事件流处理
OpenCode 提供服务器发送事件 (SSE) 流,用于实时监控。
typescript
// 订阅事件流
const events = await opencode.client.event.subscribe()
for await (const event of events.stream) {
switch (event.type) {
case "server.connected":
console.log("服务器已连接")
break
case "session.created":
console.log("会话创建:", event.properties.sessionID)
break
case "session.idle":
console.log("会话空闲:", event.properties.sessionID)
break
case "message.updated":
console.log("消息更新:", event.properties.messageID)
break
case "tool.execute.before":
console.log("工具执行:", event.properties.tool)
break
default:
console.log("未知事件:", event.type)
}
}TUI 控制
可以通过 SDK 控制 TUI 界面。
typescript
// 在 TUI 中附加文本
await opencode.client.tui.appendPrompt({
body: {
text: "自动注入的上下文"
}
})
// 提交提示
await opencode.client.tui.submitPrompt()
// 清除提示
await opencode.client.tui.clearPrompt()
// 显示通知
await opencode.client.tui.showToast({
body: {
title: "任务完成",
message: "代码审查已完成",
variant: "success"
}
})
// 打开会话选择器
await opencode.client.tui.openSessions()
// 执行命令
await opencode.client.tui.executeCommand({
body: {
command: "/help"
}
})文件操作
typescript
// 搜索文本
const textResults = await opencode.client.find.text({
query: {
pattern: "function.*opencode"
}
})
// 查找文件
const files = await opencode.client.find.files({
query: {
query: "*.ts",
type: "file",
limit: 100
}
})
// 读取文件
const content = await opencode.client.file.read({
query: {
path: "src/index.ts"
}
})
console.log("文件内容:", content.data.content)权限响应
typescript
// 响应权限请求
await opencode.client.postSessionByIdPermissionsByPermissionId({
path: {
id: session.data.id,
permissionId: "perm-123"
},
body: {
response: "allow", // 或 "deny"
remember: true // 记住此选择
}
})