Skip to content

关键代码验证

会话生命周期管理

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 // 记住此选择
  }
})

参考资料