DeepSeek Harness 插件

把 opencode 变成 DeepSeek Harness 里的子代理。

一个任务离开你的对话,进入 opencode 自己的进程,用它自己的模型跑完。答案回来,别的都不回来。

看源码

Two harnesses, one conversation.
The child takes the task and returns only the answer.

DSH opencode acp
  1. 发出 initialize
  2. 发出 session/new
  3. 发出 session/prompt
  4. 返回 agent_message_chunk ×5
  5. 返回 usage_update

一次运行,已缩短。方法名就是 README 里写的那些。

运行 0f3a9c 模型 big-pickle 耗时 42.1s token 3,204 完成

两个 harness,一段对话。

DSH 继续当驾驶。opencode 带来它自己的模型、工具和免费额度,它做的一切都不会进你的上下文,也不进你的账单。 子进程只拿到任务文本和工作目录:没有历史,没有计划,也没有它没要的文件。

每次运行都留下记录。

这个插件自己实现了 ACP,所以官方 provider 丢掉的东西它都留着:子进程的会话 id、真正跑的是哪个模型、 耗时、工具调用次数和 token。最后一行是一次值得保留的失败——它才是告诉你要修什么的那条。

示例记录。字段与 runs.json 一致。

示例运行记录
开始 模型 目录 毫秒 token 状态 详情
11:42:07 opencode/deepseek-v4.1-flash-free repo/web 6,317 ↑13,543 ↓81 完成
11:36:22 opencode-go/deepseek-v4.1-flash repo/api 4,102 ↑8,914 ↓204 完成
10:58:03 opencode/glm-5.3-flash-free repo/docs 31,884 ↑21,077 ↓1,340 完成
10:03:11 opencode/deepseek-v4.1-flash-free repo/web 3,967 — 额度用尽

六帧,一个答案。

因为 DSH 自己讲 ACP,它才能留下官方 provider 丢掉的那部分:子进程侧的会话 id、真正跑的模型、耗时、token。

  1. initialize发出

    协议版本、客户端能力。子进程先同意讲 ACP,之后才对它提要求。

  2. session/new发出

    在 opencode 里开一个会话,绑定到这次委派发起时所在的目录。

  3. session/prompt发出

    任务文本越过边界。载荷就这些:没有历史、没有附件、没有父级上下文。

  4. agent_message_chunk返回

    答案以分片流式回来。只收集文本,工具调用留在子进程自己的会话里。

  5. usage_update返回

    这次运行花掉的 token,答案落地时和模型、耗时记在一起。

  6. record写入

    会话 id、模型、毫秒、工具调用、用量。运行一结束,设置页里就能看到。

用的是它的免费额度。

模型目录在设置页刷新,然后花一次真实请求测一下已保存的模型,再决定信不信它。免费额度按账号走、还会变, 页面会告诉你哪个模型答了、哪个模型拒了。

刷新目录
跑一次 opencode models,把免费档模型并进下拉,缓存在 catalog.json
测试模型
用已保存的模型起一个一次性 ACP 会话;失败原文会作为诊断留在记录里
设置
模型、小模型、权限策略、工作目录——每次委派开始时读取
读得懂的失败
provider.free-limit · provider.internal · 退出码 · 有截断的 stderr

装上,然后发一次委派。

要求:DSH >=0.2.1-rc.1 <0.3.0,opencode v2 且带 acp 子命令,以及一个已经登录过的 opencode。

加插件

dsh plugin --profile default add dsh-opencode-acp

选模型

设置 → OpenCode 委派。刷新目录,测一个能用的,留着。

发委派

直接跟 agent 说,或者调 subagent_opencode。答案会作为完成通知回来。

看源码

限制也一起说清楚:一次性执行、不能追问 · 每次运行新起一个进程 · 子进程用你的账号跑,不受沙箱约束 · 本地设置路由按设计不做鉴权,只监听回环。