dsh-health
DeepSeek Harness 会话循环健康度诊断:振荡 / 卡住 / 参数漂移 / per-tool / token / 压缩画像 + 可审计健康评分。
npm 包名:
dsh-health-cli(dsh-health在 npm 已被占位保留);命令仍是dsh-health。
当前里程碑:M7 + D(web 健康卡片 + 侧栏健康面板,本机已生效)。设计文档见DESIGN.md,进度见docs/PROGRESS.md。
界面预览
🟢 健康会话(100/100,无告警)与 能定位具体问题的诊断(80/100:参数漂移、per-tool 报错)
🔴 会话循环失控时实时标红:振荡循环 / 参数漂移 / per-tool 报错,每条发现附带可执行建议与证据 seq
直接嵌入 DSH 对话流(dsh-health-live 纯观察 bundle,不注入任何消息)。
安装
npm i -g dsh-health-cli # npm 发布版(命令 dsh-health)
# 或源码安装:npm i -g D:\path\to\dsh-health
零运行时依赖,要求 Node ≥ 22.19(内置 node:zlib zstd 与 node:sqlite 支持)。
快速上手
dsh-health # 等价 scan:列出最近会话
dsh-health scan # 列出会话(--sort time|score|tokens)
dsh-health diag <id> # 解码一个会话,打印 meta + 事件统计
dsh-health report <id> # 全检测器分析:健康评分 + 发现清单
dsh-health verify # 自检:后端可读 + 检测器可跑(30 秒)
dsh-health --help
CLI 自动定位本机 $DSH_HOME/sessions;--root <path> 可覆盖(隔离环境/测试);--sqlite <path> 显式指定 SQLite 库(默认自动探测)。
当前能力(M1–M7 + D 完整)
- 双后端会话读取:JSONL+zstd(多帧容器、packed 行展开、seq 校验、torn-tail)与官方 SQLite 存储(schema 17、只读打开、packed 行/zstd blob/varint 解码、外库拒绝)——统一接口自动嗅探;
- 7 检测器 + 0–100 可审计评分:振荡 / 参数漂移 / 卡住 / per-tool / token 成本 / 压缩健康 / 综合评分;每条发现带建议动作与证据 seq;
- live 实时镜像(
dsh-health-livebundle):静态 cordis 插件监听session/event增量落盘$DSH_HOME/.dsh-health/<sessionId>.jsonl——纯观察,不注入、不干扰 harness 循环; - watch 实时告警:
watch <id>单会话跟随(从日志 seed 历史 + live 增量 fold)、watch --all多会话概览、--interval控制轮询(默认 2s); - scan 排序:
--sort time(默认,header-only 快)/--sort score|tokens(全量分析,--max-scan上限防慢,默认 50); - 三格式输出:
--format text|json|md(report 与 scan 均支持); - 退出码门槛:
report时score < 60 → exit 2(CI 可用;边界 60 不触发); - verify 自检:JSONL/SQLite 发现、完整读 + 检测器、SQLite 只读打开——PASS/FAIL 输出;
- 与其他插件兼容(DESIGN.md §13,真机实测):只有
source.kind === 'user'算用户输入(dsh-mnemon 等插件注入不污染判定);未知事件类型/消息来源宽容跳过。
安装 live bundle(可选,watch 实时功能需要)
dsh plugin --profile web add dsh-health-live # npm 或本地路径
# 重启 dsh web 后生效;watch 无 live 时自动回退全量日志读
测试基础设施(M4)
SQLite 无真机数据(本机 rc.2 仍写 JSONL)——采用权威 fixture:scripts/build-sqlite-fixture.mjs 用官方 @deepseek-ai/dsh-session-persistence-sqlite(npm 0.1.1-rc.2)把真实会话事件写入 schema-17 库,验证读取器与官方写路径的互操作。官方包不可用时 SQLite 测试自动跳过(CI 无依赖仍跑 JSONL)。
路线图
| M | 内容 | 状态 |
|---|---|---|
| M1 | 仓库骨架 + JSONL 后端读取 + diag 骨架 | ✅ |
| M2 | 7 检测器 + 0–100 可审计评分 | ✅ |
| M3 | scan 排序 / --format md / 退出码门槛 |
✅ |
| M4 | SQLite 后端(官方存储迁移)+ verify 自检 |
✅ |
| M5 | dsh-health-live bundle + watch |
✅ 已本机验证 |
| M6 | 发布:GitHub Release + BWH 收录 + 官方展示 | ✅ |
| M7 | web 健康卡片(ConversationNode)+ 插件活动可见 | ✅ 代码完成,重启后生效 |
| D | 侧栏健康面板:方案 A 自绘左下角 z-30 覆盖层,全会话累计实时刷新 | ✅ 本机已生效 |
Web 健康面板(D)
浏览器端在会话流卡片之外,另挂一块健康面板(方案 A:自绘覆盖层,z-30,不依赖 better-sidebar;入口为侧边栏 🩺健康 按钮,点击在按钮右侧弹出 anchored 浮层;实测 z 层避让:better-sidebar host z=40 展开时盖住为合理优先,whale 挂件 z=9999 在右上角互不干扰)。面板内容为全会话累计:
- 评分徽标(🟢/🟡/🔴 + 0–100 可审计分数)、扣分明细(审计轨迹:每项 −points + 原因,bonus +5 绿标)、告警清单(严重度 + 建议动作)、per-tool 画像(种数/调用/错误/超时)、压缩健康(完整压缩/失败/阴影 token/剪枝)、插件活动、token/成本摘要;
- 会话健康一览(阶段 1):面板底部列出全部会话的健康徽标(🟢/🟡/🔴 + 分数 + 告警数)——数据来自 host 侧
sessionProjections投影单元(官方通道,dsh-base装配):host 用 JSON-safe 折叠(与 CLI 检测器 parity,10 项测试锁定)算出每会话 {score, findings},经session.listprojections / push 帧到达客户端。当前活跃会话实时有分;未打开会话的分依赖投影缓存冷读(阶段 2); - 数据流:一个不渲染的会话级
ConversationNodeDefinition(kindhealth-panel,
publication: 'none',按 turn 起止折叠)把实时事件流折进与 CLI/卡片相同的检测器;
折叠对事件 seq 幂等,窗口重放(打开/重连/补隙)不重复计数;切换会话自动重置; - 面板订阅模块级 store(
useSyncExternalStore)实时刷新,rAF 合帧; - 入口为侧边栏按钮(
🩺健康,与 dsh-mnemon「记忆系统」同款 DOM 注入,插在其旁;折叠 rail 只留图标)——点击在按钮右侧弹出 anchored 浮层,不占左下角、不遮挡侧边栏"设置"按钮(z-30,实测与设置零重叠); - 纯观察:只读事件流、折叠、渲染,不注入任何消息。
dsh plugin --profile web add dsh-health-live # 重启 dsh web 后生效
Web 健康卡片(M7)
dsh-health-live bundle 现包含浏览器端 client.js:注册一个 ConversationNodeDefinition
(kind health),把实时会话事件流折叠进与 CLI 相同的检测器,每个 turn 结束在会话流中
渲染一张健康卡片(评分徽标 + 告警列表 + 建议动作 + 插件活动)。
# 安装(bundle 已含 client.js + dsh.client 声明)
dsh plugin --profile web add dsh-health-live
# 重启 dsh web 后,client-modules 扫描到 dsh.client 声明 → 卡片出现在会话流
- 浏览器端与 CLI 共用同一套检测器(零依赖纯函数打包进 client.js),评分一致;
- 纯观察:只读事件流、折叠、渲染,不注入任何消息(§13 契约延续);
- 构建:
pnpm run build:bundle(tsdown → lib/client.js → 同步 bundle/); - compaction 真实词汇:检测器已适配 rc.2 的
compaction/prune(长会话稳态剪枝,
无 compactionId/turn),计入压缩健康画像但不产生告警(2026-08-26 真机 46728bf2 验证)。
测试
npm test # node --test --test-isolation=none "tests/*.spec.js"(79 项)
npm run smoke # 合成会话冒烟;或 node scripts/smoke-test.mjs <真实日志>
License
MIT