OA0
OA0 是一个探索 AI 的社区
现在注册
已注册用户请  登录
OA0  ›  技能包  ›  opencode-acp-control:通过 Agent Client 直接控制 OpenCode

opencode-acp-control:通过 Agent Client 直接控制 OpenCode

 
  fifty ·  2026-02-02 05:25:50 · 18 次点击  · 0 条评论  

名称: opencode-acp-control
描述: 通过 Agent Client Protocol (ACP) 直接控制 OpenCode。启动会话、发送提示、恢复对话并管理 OpenCode 更新。
元数据: {"version": "1.0.2", "author": "Benjamin Jesuiter bjesuiter@gmail.com", "license": "MIT", "github_url": "https://github.com/bjesuiter/opencode-acp-skill"}


OpenCode ACP 技能

通过 Agent Client Protocol (ACP) 直接控制 OpenCode。

元数据

  • ACP 协议文档(面向 Agent/LLM):https://agentclientprotocol.com/llms.txt
  • GitHub 仓库:https://github.com/bjesuiter/opencode-acp-skill
  • 如遇问题,请在此提交工单:https://github.com/bjesuiter/opencode-acp-skill/issues

快速参考

操作 方法
启动 OpenCode bash(command: "opencode acp", background: true)
发送消息 process.write(sessionId, data: "<json-rpc>\n")
读取响应 process.poll(sessionId) - 每 2 秒重复一次
停止 OpenCode process.kill(sessionId)
列出会话 bash(command: "opencode session list", workdir: "...")
恢复会话 列出会话 → 询问用户 → session/load
检查版本 bash(command: "opencode --version")

启动 OpenCode

bash(
  command: "opencode acp",
  background: true,
  workdir: "/path/to/your/project"
)

保存返回的 sessionId,后续所有命令都需要它。

协议基础

  • 所有消息均为 JSON-RPC 2.0 格式
  • 消息以 换行符分隔(每条消息以 \n 结尾)
  • 维护一个从 0 开始的 消息 ID 计数器

分步工作流

步骤 1:初始化连接

启动 OpenCode 后立即发送:

{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},"terminal":true},"clientInfo":{"name":"clawdbot","title":"Clawdbot","version":"1.0.0"}}}

轮询响应。预期收到 result.protocolVersion: 1

步骤 2:创建会话

{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/path/to/project","mcpServers":[]}}

轮询响应。保存 result.sessionId(例如 "sess_abc123")。

步骤 3:发送提示

{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_abc123","prompt":[{"type":"text","text":"您的问题在此"}]}}

每 2 秒轮询一次。您将收到:
- session/update 通知(流式内容)
- 包含 result.stopReason 的最终响应

步骤 4:读取响应

每次轮询可能返回多行。将每行解析为 JSON:

  • 通知method: "session/update" - 收集这些内容作为响应
  • 响应:具有与请求匹配的 id - 当出现 stopReason 时停止轮询

步骤 5:取消(如需要)

{"jsonrpc":"2.0","method":"session/cancel","params":{"sessionId":"sess_abc123"}}

无需等待响应 - 这是一个通知。

需要跟踪的状态

对于每个 OpenCode 实例,跟踪:
- processSessionId - 来自 bash 工具(clawdbot 的进程 ID)
- opencodeSessionId - 来自 session/new 响应(OpenCode 的会话 ID)
- messageId - 为发送的每个请求递增

轮询策略

  • 2 秒 轮询一次
  • 持续轮询直到收到包含 stopReason 的响应
  • 最长等待:5 分钟(150 次轮询)
  • 若无响应,视为操作超时

常见的停止原因

stopReason 含义
end_turn Agent 已完成响应
cancelled 您取消了提示
max_tokens 达到令牌限制

错误处理

问题 解决方案
轮询响应为空 继续轮询 - Agent 正在思考
解析错误 跳过格式错误行,继续
进程已退出 重启 OpenCode
5 分钟后无响应 终止进程,重新开始

示例:完整交互

1. bash(command: "opencode acp", background: true, workdir: "/home/user/myproject")
   -> processSessionId: "bg_42"

2. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":0,"method":"initialize",...}\n')
   process.poll(sessionId: "bg_42") -> 初始化响应

3. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/home/user/myproject","mcpServers":[]}}\n')
   process.poll(sessionId: "bg_42") -> opencodeSessionId: "sess_xyz789"

4. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_xyz789","prompt":[{"type":"text","text":"列出所有 TypeScript 文件"}]}}\n')

5. process.poll(sessionId: "bg_42") 每 2 秒一次,直到 stopReason
   -> 收集所有 session/update 内容
   -> 最终响应:stopReason: "end_turn"

6. 完成后:process.kill(sessionId: "bg_42")

恢复会话

通过让用户从可用会话中选择,恢复之前的 OpenCode 会话。

步骤 1:列出可用会话

bash(command: "opencode session list", workdir: "/path/to/project")

示例输出:

ID                                  更新于               消息数
ses_451cd8ae0ffegNQsh59nuM3VVy      2026-01-11 15:30     12
ses_451a89e63ffea2TQIpnDGtJBkS      2026-01-10 09:15     5
ses_4518e90d0ffeJIpOFI3t3Jd23Q      2026-01-09 14:22     8

步骤 2:请用户选择

向用户展示列表并询问要恢复哪个会话:

"您希望恢复哪个会话?

1. ses_451cd8ae... (12 条消息,更新于 2026-01-11)
2. ses_451a89e6... (5 条消息,更新于 2026-01-10)
3. ses_4518e90d... (8 条消息,更新于 2026-01-09)

请输入会话编号或 ID:"

步骤 3:加载所选会话

用户响应后(例如 "1"、"第一个" 或 "ses_451cd8ae..."):

  1. 启动 OpenCode ACP
    bash(command: "opencode acp", background: true, workdir: "/path/to/project")

  2. 初始化
    json {"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}

  3. 加载会话
    json {"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}

注意session/load 需要 cwdmcpServers 参数。

加载时,OpenCode 会将完整的对话历史流式传输给您。

恢复工作流摘要

function resumeSession(workdir):
    # 列出可用会话
    output = bash("opencode session list", workdir: workdir)
    sessions = parseSessionList(output)

    if sessions.empty:
        notify("未找到之前的会话。开始新会话。")
        return createNewSession(workdir)

    # 请用户选择
    choice = askUser("要恢复哪个会话?", sessions)
    selectedId = matchUserChoice(choice, sessions)

    # 启动 OpenCode 并加载会话
    process = bash("opencode acp", background: true, workdir: workdir)
    initialize(process)

    session_load(process, selectedId, workdir, mcpServers: [])

    notify("会话已恢复。对话历史已加载。")
    return process

重要说明

  • 历史回放:加载时,所有之前的消息会流式传回
  • 记忆保留:Agent 记住完整的对话
  • 进程独立:会话在 OpenCode 重启后依然存在

更新 OpenCode

OpenCode 在重启时会自动更新。使用此工作流检查和触发更新。

步骤 1:检查当前版本

bash(command: "opencode --version")

返回类似:opencode version 1.1.13

提取版本号(例如 1.1.13)。

步骤 2:检查最新版本

webfetch(url: "https://github.com/anomalyco/opencode/releases/latest", format: "text")

重定向 URL 包含最新的版本标签:
- 重定向至:https://github.com/anomalyco/opencode/releases/tag/v1.2.0
- 从 URL 路径提取版本(例如 1.2.0

步骤 3:比较并更新

如果最新版本 > 当前版本:

  1. 停止所有正在运行的 OpenCode 进程
    process.list() # 查找所有 "opencode acp" 进程 process.kill(sessionId) # 对每个运行实例执行

  2. 重启实例(OpenCode 在启动时自动下载新二进制文件):
    bash(command: "opencode acp", background: true, workdir: "/path/to/project")

  3. 重新初始化 每个实例(对现有会话执行 initialize + session/load)

步骤 4:验证更新

bash(command: "opencode --version")

如果版本仍与最新版不匹配:
- 通知用户:"OpenCode 自动更新可能失败。当前:X.X.X,最新:Y.Y.Y"
- 建议手动更新:curl -fsSL https://opencode.dev/install | bash

更新工作流摘要

function updateOpenCode():
    current = bash("opencode --version")  # 例如 "1.1.13"

    latestPage = webfetch("https://github.com/anomalyco/opencode/releases/latest")
    latest = extractVersionFromRedirectUrl(latestPage)  # 例如 "1.2.0"

    if semverCompare(latest, current) > 0:
        # 停止所有实例
        for process in process.list():
            if process.command.includes("opencode"):
                process.kill(process.sessionId)

        # 短暂等待进程终止
        sleep(2 seconds)

        # 重启触发自动更新
        bash("opencode acp", background: true)

        # 验证
        newVersion = bash("opencode --version")
        if newVersion != latest:
            notify("自动更新可能失败。建议手动更新。")
    else:
        notify("OpenCode 已是最新版本:" + current)

重要说明

  • 会话持久化opencodeSessionId 在重启后依然存在 — 使用 session/load 恢复
  • 自动更新:OpenCode 在重启时自动下载新二进制文件
  • 无数据丢失:对话历史在服务器端保留
18 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
关于 ·  帮助 ·  PING ·  隐私 ·  条款   
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
耗时 19 ms
Developed with Cursor