⚠️ 当前版本为 BETA:DSH 上游处于 developer preview(0.1.2-rc.x),本 addon 的适配层(认证注入、ingress 兼容、会话中继)随上游变动快速迭代,功能可能不稳定。遇到问题请先更新 addon 与 DSH 至最新版,并在 issue 中附上 addon 日志。
将 DeepSeek Harness(DSH) —— 上游开源的 AI Agent 运行框架("一切皆插件")—— 封装为 Home Assistant Addon。
- 通过 HA Ingress 访问 DSH Web UI(无需额外端口暴露)
- 内置桥接 API(
deepseek_harness自定义集成依赖此稳定契约) - 可选接入 HA 原生 MCP Server,让 DSH 控制家里设备
- Web 一键更新:DSH 更新到上游最新版,无需重新发布 addon
- 多轮会话中继:HA 对话接进 DSH Agent 真实会话,跨轮保留上下文
- 将本仓库添加为 HA Add-on 仓库(Repository URL:
https://github.com/C3H3-AI/ha-dsh-addon) - 安装 DeepSeek Harness addon
- 配置页填写:
api_key:DeepSeek API Key(必填)api_token:桥接 API 共享密钥(强烈建议设置,见下方"安全")model/provider/base_url:模型配置(默认 deepseek-v4-flash / deepseek-official)ha_mcp_enabled/ha_mcp_url/ha_mcp_token:可选接入 HA MCP Server
- 启动 addon,侧边栏出现 DSH Agent 面板
配套自定义集成:
deepseek_harness(HA 商店可搜),用于 Assist 语音/文本对话与运行时状态传感器。
[HA Ingress] ──► [HTTP 代理 :3080] ──► [DSH Web UI 127.0.0.1:3081]
│ (注入脚本 / 改写 host.describe)
[桥接 API :3082] ◄── [deepseek_harness 集成]
├ GET /api/status (只读, 放行)
├ POST /api/session (需 Bearer token, 多轮会话中继 —— 当前对话路径)
├ POST /api/chat (需 Bearer token, headless 一次性调用, 已不再使用)
├ POST /api/restart (需 Bearer token)
├ GET /api/update/status (需 Bearer token)
└ POST /api/update (需 Bearer token, 一键更新)
- 持久化:所有数据在
/data/dsh/(会话、设置、凭据、vendor 更新) - DSH 安全限制:DSH 自身禁止绑定
0.0.0.0,仅监听127.0.0.1:3081,对外由代理接管
- 桥接 API 共享密钥:addon 配置
api_token后,所有写操作(chat / restart / update)要求Authorization: Bearer <api_token>;未配置时写操作返回 401(fail-closed)。集成侧配置时填入相同值。 - 仅 Ingress 暴露:addon 不发布任何宿主端口(无
ports),Web UI 只能通过 HA 登录后的 Ingress 访问,避免 DSH(具备代码执行能力)暴露到局域网/公网。 - 桥接 API 监听容器内
3082,不映射到宿主机。
DSH 处于测试期(rc.x),更新频繁。本 addon 提供 Web 一键更新,让用户自主升级 DSH 到上游最新版,无需维护者重新发布 addon:
- 打开 DSH Web UI(侧边栏 → DSH Agent)
- 进入 设置(Settings) 页面,底部出现 DSH 更新 卡片
- 点击 → 确认 → 自动:
npm install @deepseek-ai/dsh@next到/data/dsh/vendor→ 原子切换 → 容器重启
- 更新后的 DSH 装在持久化目录
/data/dsh/vendor,镜像内置版保留作离线兜底与回滚 - addon 壳依赖 DSH 的会话 RPC 契约(session.create / session.history / session.prompt);契约变化时只改 addon 桥接层,HA 集成不动
/data/dsh/ 位于 addon 的 /data 目录,随 HA 的 addon 备份自动包含(会话记录、设置、vendor 更新均被覆盖)。无需额外备份配置。
注意:卸载 addon 或变更 slug 会清空
/data目录,属于预期行为。如果你需要保留对话历史,请在卸载前手动备份/data/dsh/。正常更新 addon(包括 rebuild)时/data必定保留,无需担心。
| 通道 | 说明 |
|---|---|
latest |
npm 稳定 tag(当前 0.1.2-rc.1),方案 A 首次自动安装与镜像内置版默认目标 |
next |
npm 预发布 tag(当前 0.1.2-rc.1,与 latest 相同),手动一键更新默认目标 |
addon 兼容层的目标是当前 DSH 版本线(0.1.2-rc.1,镜像内置与 vendor 自动安装同源)。针对 rc.1 的关键适配由 addon 自动完成,用户无感知:
- 强制浏览器会话认证(rc.1+ 对全部 API 401 拦截):代理自动从持久化凭据生成签名 Cookie 并注入全部转发请求与 WebSocket,桥接层同样按需生成、401 自动重试。
- Ingress 查询串规范化:HA ingress 转发会重编码查询串,破坏 DSH 插件打包器 URL(
/plugins/??列表&rev=x)的精确匹配;代理自动还原。 - 对不启用强制认证的旧版 DSH,上述注入/规范化均为无害空操作。
DSH 上游若再变更加密方案、bundler URL 形态或 RPC 契约,需要发布新版 addon 适配(proxy 对关键改写点带有"上游模式变化"告警日志,可快速定位)。
- 🐛 修复设置持久化改写未到达浏览器:模块系统按
__DSH_BOOT__图 JSON 的 per-module URL 取包,指纹现覆盖该形态,普通刷新即可生效。
- 🐛 修复聚合包改写对老访客不生效:聚合包 URL 不变且无可缓存校验头,浏览器沿用缓存里的旧包。现给 bundler URL 追加代理版本指纹参数
&px=N(转发前剥离),代理改写行为变化时浏览器自动拉取新包,普通刷新即可生效。
- 🐛 修复 Ingress 下设置不持久:DSH 0.1.2-rc.1 起插件代码经
/plugins/??聚合包下发且 isLoopback 计算形态变更,原改写未命中导致设置后端退化为 memory(弹窗/语言每次重置、报 "settings are unavailable in this browser")。代理现对聚合包按新形态强制isLoopback: true,设置恢复正常持久化。
- 🐛 修复 ingress 下 WebUI 401:DSH 0.1.2-rc.1+ 强制浏览器会话认证,代理自动生成签名 Cookie 并注入 HTTP/WS 请求。
- 🐛 修复 ingress 下插件加载失败 "HTML did not preload":HA ingress 重编码查询串导致打包器 URL 404,代理自动规范化。
- 🐛 修复新装首启动桥接 401:桥接 Cookie 改为惰性生成 + 401 重试,secret 晚于桥接启动也能自动恢复。
- 🐛 HTML 响应强制 no-store:避免浏览器缓存旧版页面引用失效资产。
- ✨ 侧边栏面板:
panel: true,安装后侧边栏出现 DSH Agent 入口。
- ✨ 首次启动自动安装最新版(方案 A):新客户首次启动自动
npm install @deepseek-ai/dsh@latest到持久化/data/dsh/vendor,装完即用稳定通道最新版;失败静默回退镜像内置版,下次启动自动重试。run.sh新增install_dsh_vendor()/vendor_integrity_ok(),与一键更新同源(npmmirror + vendor.tmp 原子切换)。 - 🔄 内置版默认通道
@next→@latest:Dockerfile 与首次自动安装改走稳定通道(当前latest/next同指0.1.2-rc.1);手动一键更新保持next默认、可选latest。 - 🐛 修复按钮 202 契约:
trigger_update()接受 200/202,修复“更新 DSH”按钮误报失败(桥接层成功返回 202 后台异步执行)。 - 🐛 修复按钮国际化:
button平台改用translation_key(en/zh-Hans 生效,英文界面不再显示中文硬编码名);更新按钮成功后即时推送last_update_version。 - 🐛 补齐 icon.png:发布源集成目录补上 manifest 声明的
icon.png。
- ✨ HA 界面控制按钮:新增
button平台(“重启 DSH” / “更新 DSH”)。 - 🔄 移除
/api/chatheadless 死代码;契约测试迁移到/api/session(12 项断言)。
- ✨ 多轮会话中继
POST /api/session:HA 对话接进 DSH Agent 真实会话,跨轮保留上下文。 - 🐛 修复限流:新对话不再复用"最近活跃的其它会话"(曾导致所有对话堆积进一个 105K token 的臃肿会话而触发 LLM 限流),改为 conversation_id 有效则复用、否则新建。
- 🐛 修复 HA 对话在 DSH 界面不可见:会话需注册到 workspace 才会被 DSH 会话树渲染;新建时带
workspaceId,游离会话用session.create({workspaceId, sessionId})补认领(沿用 dsh-im 思路)。 - 🐛 修复 HA 2026.8 兼容:
conversation.result()已移除,改返回conversation.ConversationResult(...),否则调用返回 500。
- 🐛 修复:桥接 API
sendJson幂等化,杜绝/api/status、/api/restart在 DSH Web 响应超时时因timeout+error双回调二次writeHead触发ERR_HTTP_HEADERS_SENT导致的桥接进程崩溃(日志曾见WARNING: bridge API died, respawning...)。
详见 docs/DESIGN.md(完整设计方案与关键决策记录)。
-
排障与调试经验(踩坑实录、排查顺序、常用命令):docs/DEBUGGING.md
-
本地测试:
node api_server.js(需DSH_API_TOKEN环境变量) -
双轨版本号:addon 轨
config.yaml==Dockerfile(当前0.2.43);集成轨const.py==manifest.json(当前0.2.4)。两轨独立、不跨轨比较。CI 通过scripts/check-versions.sh校验各自一致。 -
测试与 CI:桥接 API 契约测试在
tests/(随仓库提交),CI(.github/workflows/ci.yml)跑 lint + 版本校验 + 契约测试 + 镜像构建。
MIT