- openclaw.json
- plugins.allow 放行 acpx(限制性白名单,缺了后端不会加载)
- 新增 acp 策略段:enabled/dispatch、backend=acpx、defaultAgent=dsh、
allowedAgents=[dsh]、stream.deliveryMode=live
- 新增 plugins.entries.acpx.config:permissionMode=approve-all、
timeoutSeconds=900、cwd、agents.dsh = dsh --profile acp(绝对路径)
- 新增 OpenClaw agent dsh(runtime.type=acp → harness dsh),否则
sessions_spawn 会报 dispatch_failed: Unknown agent id "dsh"
- workspace-dsh/:该 agent 的身份文件(AGENTS/SOUL/IDENTITY/USER/BOOTSTRAP.md)。
其中的空 .git 由 `openclaw agents add` 的标准 provisioning 生成(非任何 agent 自建),
会让父仓库把它当 gitlink,已移除后纳入版本控制
- docs/bk02-dsh-openclaw-ACP集成.md:部署/配置/验证证据/排错/回滚全文
- docs/dsh-acp-smoke.mjs:ACP 独立冒烟(initialize→session/new→prompt→close)
- docs/dsh-lang-check.mjs:全局中文指令验证(英文提问看是否回中文)
- skills/delegate-to-dsh:让「交给 dsh」稳定走 ACP 派发;缺此技能时模型会
静默 fallback 到内嵌 subagent(已复现「假成功」并写入判据)
- agents/main/agent/workshop-skills/acp-backend-triage:ACP 后端排查技能
- plugin-skills/acp-router:acpx 插件自带技能(symlink,与既有渠道一致)
- .gitignore:workspace-dsh 沿用 workspace/ 白名单(只版本化顶层 *.md);
新增忽略 acpx/ 插件运行产物
验证:ACP 三条途径均通过(独立冒烟、显式 sessions_spawn、自然语言「转给 dsh」),
DSH 侧会话留痕与产物落地见 docs 文档 §5 与 §7。
24 KiB
bk02 · DSH × OpenClaw ACP 集成说明
用途:本机 DeepSeek Harness(dsh)的部署与「OpenClaw → DSH」ACP 协同链路的完整说明。新会话/新人接手读本文件即可,无需历史对话。 配套:
bk02-openclaw-系统说明.md(OpenClaw 本体)、openclaw-升级与维护.md主机:bk02 /xuan-asus-nj· Debian 12 bookworm · 首次落地 2026-09-16⚠️ 本目录不含明文口令,凭据位置见 §8。
0. 30 秒速览
| 项 | 值 |
|---|---|
| DSH 版本 | @deepseek-ai/dsh 0.1.5-rc.1(nvm Node v26.8.2,全局安装) |
| DSH ACP 入口 | dsh --profile acp —— 官方 @deepseek-ai/dsh-acp 的 ACP v1 stdio server |
| DSH Web 服务 | dsh-web.service(用户级 systemd),监听 127.0.0.1:18787 |
| Web 访问入口 | https://bk02.baiji-algieba.ts.net:18787/?token=<启动时打印>(tailscale serve,仅 tailnet 内可达) |
| OpenClaw 侧 | @openclaw/acpx 插件 2026.9.4,harness 别名 dsh,已注册为 OpenClaw agent dsh |
| 链路 | 微信/飞书 → OpenClaw agent → sessions_spawn(runtime:"acp", agentId:"dsh") → dsh --profile acp → 干活 → 结果回传 |
| DSH 状态目录 | ~/.dsh(profiles/ sessions/ .env / AGENTS.md) |
| 已装插件 | web profile:skillhub-plugin 0.2.16 + superpowers-dsh 0.1.1;acp profile:仅 superpowers-dsh(skillhub 的启动自检会往 stdout 打印,污染 ACP 协议流,见 §3.1) |
| 全局指令 | ~/.dsh/AGENTS.md —— 交互与思考一律中文,所有 profile / 所有会话生效 |
最常用的四条命令:
export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH # 每次登录先做
systemctl --user status dsh-web # DSH Web 状态
journalctl --user -u dsh-web -f # DSH Web 日志(含带 token 的访问 URL)
journalctl --user -u openclaw-gateway -f # OpenClaw 网关日志(ACP spawn 记录在这里)
node ~/.openclaw/docs/dsh-acp-smoke.mjs # DSH ACP 独立冒烟(不经过 OpenClaw)
1. 架构与职责边界
微信 / 飞书 / 其他渠道
│
▼
┌──────────────────────────────┐
│ OpenClaw Gateway (18789) │ ← 渠道接入、路由、会话、结果投递
│ @openclaw/acpx 插件 │ ← ACP 客户端侧(acpx 0.13.2 内嵌)
└──────────────────────────────┘
│ ACP v1 over stdio(JSON-RPC)
▼
┌──────────────────────────────┐
│ dsh --profile acp │ ← 每会话一个子进程;ACP server 侧
│ @deepseek-ai/dsh-acp │ 模型 deepseek-official / deepseek-v4-flash
│ dsh-base(工具/沙箱/持久化) │ 权限 preset workspace-write
└──────────────────────────────┘
│
▼
真实干活:读写文件、跑命令、再回传
职责分工(官方定位):
- OpenClaw 拥有:渠道、路由、后台任务状态、投递、绑定、策略。
- DSH 拥有:provider 登录、模型目录、文件系统行为、原生工具、会话持久化。
关键认知:ACP 是 stdio 直连,不需要任何网络暴露。DSH Web(18787)是给人用的浏览器界面,与 ACP 链路彼此独立。
2. 为什么不是「把 DSH 装成一个别的 ACP 工具」
DSH 自带官方 ACP 服务端,无需自研桥接:
- npm 包
@deepseek-ai/dsh-acp:Automation-only Agent Client Protocol server for driving DeepSeek Harness agents over JSON-RPC stdio。 - dsh ≥0.1.5 内置
acpprofile 模板(bundles =@deepseek-ai/dsh-base+@deepseek-ai/dsh-acp-app),dsh --profile acp开箱即用。 - 默认组合已配好
provider: deepseek-official/model: deepseek-v4-flash。 - ACP 能力:
initialize / session/new / session/list / session/resume / session/close / session/prompt / session/cancel / session/set_config_option、session/update语义流、session/request_permission权限询问、stdio 与 HTTP MCP。 - 明确不支持(写代码时别指望):
session/load、删除、fork、附加目录、SSE MCP、计划/终端/客户端文件系统操作、elicitation。
3. DSH 侧安装(可复现步骤)
# 1) 用 nvm 的 Node(系统 /usr/bin/node 是 22.x,不用)
export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH
# 2) 全局安装 dsh(必须显式放行 install scripts,否则 node-pty / spawn helper 不生成)
npm i -g --allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs \
@deepseek-ai/dsh@0.1.5-rc.1
# 3) 初始化 ACP profile(首次执行自动创建 ~/.dsh/profiles/acp)
dsh --profile acp --help
# 4) 写入模型凭据(600 权限;凭据来源优先级见 §8)
printf 'DEEPSEEK_API_KEY=<见 §8>\n' > ~/.dsh/.env && chmod 600 ~/.dsh/.env
# 5) 独立冒烟:不经过 OpenClaw,直接与 dsh 的 ACP server 对话
node ~/.openclaw/docs/dsh-acp-smoke.mjs
~/.dsh/profiles/acp/ 由 CLI 自动生成,不要手改(除非要换模型):
{ "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-acp-app"],
"patchReload": "startup" } } }
要改模型/provider,在 ~/.dsh/profiles/acp/cordis.patch.yml 里按 id 覆盖 acp 行:
- id: acp
config:
provider: deepseek-official
model: deepseek-v4-pro # 默认是 deepseek-v4-flash
3.1 插件与全局中文指令(2026-09-16 追加)
前置:dsh plugin 是 pnpm 的转发器,先装 pnpm(本机原先没有):
export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH
npm i -g pnpm # → pnpm 12.4.2,落在 ~/.nvm/versions/node/v26.8.2/bin/pnpm
装插件(插件是否属于某个 profile,取决于 dsh --profile <name>,所以要分别装):
# Web 界面用的 profile:两个都装(HTTP 传输,不受 stdout 约束)
dsh plugin --profile web add skillhub-plugin superpowers-dsh
# ACP 自动化 profile:只装 superpowers-dsh —— 详见下方「stdout 纪律」
dsh plugin --profile acp add superpowers-dsh
装完 profile 的 package.json 会自动登记(dsh plugin 会按已装状态 reconcile 层列表):
{ "dependencies": { "skillhub-plugin": "^0.2.16", "superpowers-dsh": "^0.1.1" },
"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app",
"skillhub-plugin", "superpowers-dsh"] } } }
校验(不需要起服务):
dsh --profile web --dump-config | grep -iE "skillhub|superpowers"
⚠️ stdout 纪律:skillhub-plugin 不能装进 acp profile
skillhub-plugin 0.2.16 在插件加载时跑一个 fire-and-forget 启动自检,用 console.log 往 stdout 打印:
[skillhub] self-check ok: 插件分页两页零重复(5+5 条, total=2714)
而 ACP 的 stdout 只允许承载协议流量(dsh-acp 文档原话:Stdout carries only protocol traffic, so keep logging off it)。该行会被 ACP 客户端当成非法 JSON 帧。实测:装进 acp profile 后,ACP 冒烟脚本每轮都会捕获到这条非 JSON 输出(脚本用宽容解析才没崩,acpx 的行为不作保证);从 acp profile 移除后立即干净:
dsh plugin --profile acp remove skillhub-plugin
node ~/.openclaw/docs/dsh-acp-smoke.mjs # 输出里不应再出现「非 JSON 的 stdout 输出」
该输出硬编码在 lib/host.js 的 selfCheckPluginPaging() 里(同函数另外两处用 console.error → stderr,无害),没有配置开关。若将来非要在 ACP 侧用技能市场,需要给该行打补丁改走 stderr,而不是直接安装。
全局中文指令(交互 + 思考)
~/.dsh/AGENTS.md(DSH_HOME 级,所有 profile、所有会话生效;权限 600):
# 用户全局指令(User-Global Instructions)
以下约定适用于所有 DSH 会话、所有项目目录,作为全局行为准则,优先于工具描述中的一般性提示:
## 语言
- 交互:与用户的所有交流(回复、提问、澄清、说明)一律使用中文。
- 思考:内部推理与思考过程也一律使用中文。
与 wit01 上 ~/.dsh/AGENTS.md 内容一致。验证方式(脚本 dsh-lang-check.mjs,走 ACP 提问,故意用英文):
| 提问 | DSH 回复 | 判定 |
|---|---|---|
Answer in ONE short sentence, English only: what is 2+2? |
2 + 2 = 4. |
用户显式指定 English → 遵从用户(预期行为) |
Reply with a single short sentence: name one benefit of unit tests. |
单元测试能在改动代码时快速发现回归缺陷。 |
✅ 未指定语言时输出中文,指令生效 |
判定中文指令是否生效,要用未指定语言的英文提问;像第一行那样显式要求 English only 时,模型服从当次用户指令是正确行为,不算指令失效。
4. OpenClaw 侧配置(4 处,缺一不可)
配置全部落在 ~/.openclaw/openclaw.json(用 openclaw config patch 写入,勿手改 JSON 后不校验)。
4.1 插件清单必须放行 acpx
plugins.allow 是限制性白名单,不在里面 = 插件被阻止加载(/acp doctor 会报缺失 allowlist 项):
"plugins": { "allow": ["deepseek","memory-core","ollama","searxng","openclaw-weixin",
"dingtalk-connector","openclaw-lark","feishu", "acpx"] }
4.2 acpx 插件里注册 DSH harness
"plugins": { "entries": { "acpx": { "enabled": true, "config": {
"permissionMode": "approve-all", // 非交互会话必需,否则写/执行被拒(见 §9 安全)
"timeoutSeconds": 900,
"cwd": "/home/yangxuan/.openclaw/workspace",
"agents": {
"dsh": {
"command": "/home/yangxuan/.nvm/versions/node/v26.8.2/bin/dsh",
"args": ["--profile", "acp"]
}
}
} } } }
agents.<id>是 acpx 插件自带的扩展点(schema:{ command, args? }),用绝对路径,因为网关服务的 PATH 未必包含 nvm 目录。
4.3 开启 ACP 策略
"acp": {
"enabled": true,
"dispatch": { "enabled": true },
"backend": "acpx",
"defaultAgent": "dsh",
"allowedAgents": ["dsh"],
"stream": { "deliveryMode": "live" }
}
4.4 把 dsh 注册成一个 OpenClaw agent(关键,易漏)
只做 4.2 + 4.3 会得到 dispatch_failed: Unknown agent id "dsh":ACP spawn 会拼出子会话键 agent:dsh:acp:<uuid>,Gateway 用 listAgentIds() 校验该 agent 必须真实存在。
openclaw agents add dsh --workspace /home/yangxuan/.openclaw/workspace-dsh --non-interactive
# 再用 config patch 给它接上 ACP 运行时:
# agents.entries.dsh.runtime = { type: "acp", acp: { agent: "dsh", backend: "acpx" } }
最终 agents.entries.dsh:
{
"name": "DSH",
"workspace": "/home/yangxuan/.openclaw/workspace-dsh",
"agentDir": "/home/yangxuan/.openclaw/agents/dsh/agent",
"runtime": { "type": "acp", "acp": { "agent": "dsh", "backend": "acpx" } }
}
改完配置:openclaw gateway restart(插件类改动必须重启;纯 agents.entries 改动可热加载)。
5. 验证(2026-09-16 实测,均已通过)
| 检查 | 命令 | 结果 |
|---|---|---|
| ACP 独立冒烟 | node ~/.openclaw/docs/dsh-acp-smoke.mjs |
initialize → deepseek-harness-acp 0.0.1;session/new → sessionId + 模型下拉(deepseek-v4-flash/pro…);session/prompt → 助手回「1+1 等于 2。」;stopReason: end_turn |
| 后端就绪 | 网关日志 | embedded acpx runtime backend registered (cwd: /home/yangxuan/.openclaw/workspace) → backend ready |
| 端到端派发 | openclaw agent --agent main --session-key acp-e2e -m "请调用 sessions_spawn(runtime=acp, agentId=dsh, task=在 /tmp/dsh-e2e/ 创建 proof2.txt …)" |
子会话 agent:dsh:acp:ce3e4ea5…,runId b175b303-…,约 5 秒完成 |
| DSH 侧留痕 | ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/<uuid>/session.v3.jsonl.zstd |
含 permission/preset: workspace-write、sandbox/mode: workspace-write、approval/policy: ask 及用户消息原文 |
| 产物落地 | ls /tmp/dsh-e2e/ |
proof2.txt / proof3.txt = dsh-acp-e2e-ok |
| Web 跨机访问 | curl -L "https://bk02.baiji-algieba.ts.net:18787/?token=<token>" |
303 → Set-Cookie → 200(27724 字节 HTML) |
| 自然语言派发(部署 skill 前) | openclaw agent --agent main -m "这个活我不想自己干,请转给 dsh 执行:…" |
❌ 假成功:回复称「已交给 dsh」,但 DSH 侧无新会话 —— 实际是默认 subagent + exec 干完再复述(工具轨迹 10 次调用 / 4 次失败) |
| 自然语言派发(部署 skill 后) | 同上措辞(用户不必知道参数) | ✅ DSH 侧新增会话 332ef715-28e4-4dfb-812e-4152f3c33afd(cwd=workspace-dsh、permission/preset: workspace-write),任务描述被自动补全验收标准,产物 nl2.txt = skill-ok |
证据判据:别只看 OpenClaw 的回复文本。回复正确可能来自 OpenClaw 内嵌运行时(
executionTrace.runner="embedded")。要确认真的走了 DSH,看两处:网关日志里的agent:dsh:acp:<uuid>子会话,以及~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/下是否新增会话目录。
6. DSH Web 界面(给人用,与 ACP 无关)
~/.config/systemd/user/dsh-web.service:
[Unit]
Description=DeepSeek Harness Web (dsh web on 18787, tailscale)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Environment=PATH=/home/yangxuan/.nvm/versions/node/v26.8.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=DSH_HOME=/home/yangxuan/.dsh
ExecStart=/home/yangxuan/.nvm/versions/node/v26.8.2/bin/node \
/home/yangxuan/.nvm/versions/node/v26.8.2/bin/dsh web \
--host 127.0.0.1 --port 18787 --no-open \
--trusted-host bk02.baiji-algieba.ts.net --trusted-host bk02.baiji-algieba.ts.net:18787 \
--trusted-host localhost:18787 --trusted-host 127.0.0.1:18787
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
对外暴露(仅 tailnet 可达,https,复用 tailscale 证书):
sudo -n tailscale serve --bg --https=18787 http://127.0.0.1:18787
sudo -n tailscale serve status # https://bk02.baiji-algieba.ts.net:18787 (tailnet only)
访问必须带 token(每次启动随机生成、只打印一次):
journalctl --user -u dsh-web --no-pager | grep -o 'token=[A-Za-z0-9]*' | tail -1
# → 浏览器打开 https://bk02.baiji-algieba.ts.net:18787/?token=<上面那串>
不带 token 访问返回 401 dsh web authentication required; reopen the URL printed by dsh web.;带 token 会用 303 + Set-Cookie: dsh-auth-* 落地,之后正常浏览。
两个已知坑:
--host只接受127.0.0.1或0.0.0.0;写--host 100.115.195.192会在启动时报ValidationError: $.host expected "127.0.0.1" | "0.0.0.0" but got "100.115.195.192"。 所以要「tailscale 上的 18787」就用127.0.0.1+tailscale serve(本方案),不要指望直绑 tailscale IP。- 首次启动会初始化
~/.dsh/profiles/web,约 10–40 秒才监听端口;systemd 里已在等待逻辑外,需自行ss -ltn | grep 18787确认。
7. 微信 → DSH 的接法(2026-09-16 实测结论)
结论:微信 / 飞书 / 钉钉只能走「助手按需派活」,渠道级 ACP 绑定在这三家都不存在。
7.1 渠道能力实测(为什么不能直接绑定会话)
OpenClaw 判定一个渠道能否「把当前会话绑到 ACP 会话」的代码是:
getChannelPlugin(id)?.conversationBindings?.supportsCurrentConversationBinding === true;持久 bindings[] type="acp" 还需要适配器提供 bindings.compileConfiguredBinding / matchInboundConversation(Telegram 适配器就是这么实现的)。
体检本机三个渠道插件的结果:
| 渠道 | 插件 | conversationBindings |
supportsCurrentConversationBinding |
threadBindings |
|---|---|---|---|---|
| 微信 | @tencent-weixin/openclaw-weixin 2.4.8 |
0 处 | 0 处 | 0 处 |
| 飞书 | ~/.openclaw/extensions/openclaw-lark |
0 处 | 0 处 | 0 处 |
| 钉钉 | @dingtalk-real-ai/dingtalk-connector |
0 处 | 0 处 | 0 处 |
| Telegram(对照组,官方内置) | dist/channel-*.mjs |
有 | true(bindingStore: "adapter") |
有 |
因此:
- ❌
/acp spawn dsh --bind here在微信/飞书/钉钉不可用(会得到 "Conversation bindings are unavailable …")。 - ❌ 持久
bindings[] type="acp"同样不可用(适配器没有绑定钩子)。 - ✅ 助手派活是最短可用路径(也是本机唯一路径)。
7.2 唯一可用路径:助手把活派给 DSH(已部署)
链路:微信消息 → OpenClaw main 助手 → sessions_spawn(runtime:"acp", agentId:"dsh") → dsh --profile acp → 干活 → 结果回传微信。
为了让它稳定,已部署技能 ~/.openclaw/skills/delegate-to-dsh/SKILL.md:触发词为「交给 dsh / 让 dsh 干 / 用 DSH 跑 / 转给 dsh」,并写明纪律(必须带 runtime:"acp"、禁止自己用 exec 或默认 subagent 兜底、派发失败要如实报错、结果原样回传)。
⚠️ 不加这个技能不可靠:实测 17:19 那次用户说「转给 dsh 执行」,
main声情并茂地回了"已交给 dsh 并执行完成",但工具轨迹里是sessions_spawn(默认subagent)+exec,DSH 侧没有任何新会话 —— 即它由 OpenClaw 内嵌运行时干完,然后复述成 dsh 的口气。技能上线后同一句话(17:21)DSH 侧新增会话332ef715…,cwd=/home/yangxuan/.openclaw/workspace-dsh,产物落地。
7.3 怎么确认真的交给了 DSH
# ① DSH 侧会话数是否 +1(最硬的证据)
ls -lt ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/ | head
# ② 网关日志里的 ACP 子会话 / 后端就绪
journalctl --user -u openclaw-gateway --since "10 minutes ago" | grep -iE "agent:dsh:acp:|acpx runtime backend"
# ③ 会话内容(含 cwd 与 permission preset)
L=$(ls -t ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/ | head -1)
zstd -dc ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/$L/session.v3.jsonl.zstd | head -5
判据:回复文本不算证据(见 7.2 的反例),要看 ①/③。
7.4 其他说明
agents.entries.dsh.runtime.type="acp"不会让发给dsh的普通消息自动走 ACP(实测openclaw agent --agent dsh仍是executionTrace.runner="embedded")。它的作用只有一个:让dsh能作为sessions_spawn(runtime:"acp", agentId:"dsh")的合法目标。- 想换成「某个微信账号的消息全量交给 DSH」,在当前渠道能力下做不到「消息直通」;可行的近似做法是把该账号绑定的 agent 换成
dsh,但那只会让 OpenClaw 内嵌运行时换个身份干活,不是 ACP。 - 若将来 OpenClaw 侧或渠道插件补上
conversationBindings,再考虑/acp spawn --bind here。
8. 凭据位置(本项目文档不含明文)
| 凭据 | 位置 | 说明 |
|---|---|---|
| DSH 模型 API Key | ~/.dsh/.env(600)里的 DEEPSEEK_API_KEY |
DSH 凭据解析优先级:继承的进程环境 > ~/.dsh/.credentials.yaml > 调用目录 .env > ~/.dsh/.env。写 .env 最省事;Web 的 Models 页写入则会落到 .credentials.yaml 并覆盖 .env |
| DSH Web 访问 token | 运行时随机生成 | 见 §6,从 journalctl 取;不落盘 |
| OpenClaw 各类密钥 | ~/.openclaw/.env / ~/.openclaw/openclaw.json |
见 bk02-openclaw-系统说明.md §6 |
9. 排错清单(按遇到概率排序)
| 症状 | 原因 | 处置 |
|---|---|---|
dispatch_failed: Unknown agent id "dsh" |
只注册了 acpx harness 别名,没建同名 OpenClaw agent | 做 §4.4:openclaw agents add dsh + runtime.type="acp" |
ACP runtime backend is not configured |
@openclaw/acpx 没装 / 被 plugins.allow 拦 / 网关没重启 |
openclaw plugins install @openclaw/acpx;把 acpx 加进 plugins.allow;重启网关 |
| 回复看着对但 DSH 侧没有新会话 | 其实是 OpenClaw 内嵌运行时干的 | 看 executionTrace.runner;确认 agent:dsh:acp:<uuid> 子会话与 ~/.dsh/sessions/...-workspace-dsh-- |
PermissionPromptUnavailableError: Permission prompt unavailable in non-interactive mode |
非交互 ACP 会话撞上写/执行门禁 | plugins.entries.acpx.config.permissionMode = "approve-all"(或 nonInteractivePermissions="deny" 降级) |
dsh: profile "acp" does not exist |
dsh 版本 < 0.1.5(无内置 acp 模板) | 升级 dsh,或 dsh plugin --profile acp add @deepseek-ai/dsh-acp 后手写 profile |
网关日志 security warning: dangerous config flags … permissionMode=approve-all |
预期告警 | approve-all 等于把 bk02 上的写/执行权限交给 DSH 会话,见下方安全说明 |
| Web 打开 401 | 没带 token | 从 journalctl --user -u dsh-web 取带 token 的 URL |
Web 启动即崩、日志报 $.host expected … |
--host 传了具体 IP |
改 127.0.0.1(+ tailscale serve) |
dsh 命令找不到 |
该 shell 没加载 nvm 的 Node | export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH |
dsh plugin … 报 pnpm not found on PATH |
本机没装 pnpm(dsh plugin 只是 pnpm 转发器) |
npm i -g pnpm |
| ACP 会话报 JSON 解析错 / 客户端把某行当非法帧 | acp profile 里装了会往 stdout 打印的插件(已知:skillhub-plugin 自检行) |
dsh plugin --profile acp remove skillhub-plugin;装任何插件后都跑一遍冒烟脚本确认无「非 JSON 的 stdout 输出」 |
安全说明:permissionMode=approve-all 让 DSH 会话在 bk02 上自动获得写文件/执行命令的许可(这是「让 DSH 干活」的代价)。可收紧为 approve-reads,但写/执行类任务会需要交互确认,非交互会话可能直接失败。DSH 自身仍带 workspace-write 沙箱 preset 与 approval/policy: ask 记录,可在 ~/.dsh/sessions/*/session.v3.jsonl.zstd 审计。
10. 回滚
# OpenClaw:配置回滚到接入前(备份在 ~/.openclaw/openclaw.json.bak-<ts>-pre-dsh-acp)
cp ~/.openclaw/openclaw.json.bak-20260916-170416-pre-dsh-acp ~/.openclaw/openclaw.json
openclaw gateway restart
# DSH Web:停用 + 撤掉 tailscale 暴露
systemctl --user disable --now dsh-web
sudo -n tailscale serve --https=18787 off
# DSH 本体
npm rm -g @deepseek-ai/dsh # 配置与历史留在 ~/.dsh(可整体删除)
11. 变更记录
| 时间 | 变更 |
|---|---|
| 2026-09-16 17:01 | bk02 安装 @deepseek-ai/dsh@0.1.5-rc.1(nvm v26.8.2),自动初始化 acp profile |
| 2026-09-16 17:02 | 写入 ~/.dsh/.env 的 DEEPSEEK_API_KEY;ACP stdio 冒烟通过 |
| 2026-09-16 17:04 | 安装 @openclaw/acpx;plugins.allow 放行;写入 acp 段与 acpx agents.dsh;网关重启 |
| 2026-09-16 17:11 | 创建 OpenClaw agent dsh(workspace-dsh)并接 ACP runtime |
| 2026-09-16 17:12 | 端到端 ACP 派发成功(proof2/proof3 由 DSH 创建) |
| 2026-09-16 17:15 | dsh-web.service 落地(127.0.0.1:18787)+ tailscale serve --https=18787;跨机访问 200 |
| 2026-09-16 17:20 | 查明微信/飞书/钉钉渠道均无 conversationBindings 能力(仅 Telegram 等内置渠道有)→ 排除 /acp spawn --bind here 与持久 bindings[] 两条路;部署技能 ~/.openclaw/skills/delegate-to-dsh/SKILL.md 并重启网关 |
| 2026-09-16 17:21 | 自然语言派发验证通过(DSH 侧新会话 332ef715…),「微信 → OpenClaw → DSH → 结果回传」链路可用 |
| 2026-09-16 17:23 | 装 pnpm 12.4.2;web profile 增装 skillhub-plugin + superpowers-dsh;写 ~/.dsh/AGENTS.md 全局中文指令(交互 + 思考) |
| 2026-09-16 17:24 | 发现 skillhub-plugin 自检用 console.log 污染 ACP stdout → 从 acp profile 移除(保留 superpowers-dsh),复测协议流干净;语言复测中文生效 |
| 2026-09-16 17:25 | 端到端回归:OpenClaw 派发仍正常(DSH 会话 6→7,产物 nl3.txt) |