deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
按自然日统计 DeepSeek Harness(DSH)Web 的 LLM token 用量,按提供商 / 模型拆分, 持久化到磁盘,并在 Web GUI 的多个位置展示。
assistant/message 的
usage 与 message.source.{provider,model},与 token-meter 同源)。
失败回合、被重试的尝试不计入。inputTokens(未缓存输入)、outputTokens、cacheReadTokens(缓存读)、
cacheWriteTokens(缓存写)、reasoningTokens(推理)inputTokens + cacheReadTokens + cacheWriteTokensYYYY-MM-DD)聚合,历史保留 366 天(可配)。$DSH_HOME/sessions 下今天有写入的 zstd/jsonl 日志,完整解码全部 zstd 帧),
再叠加实时订阅的新事件。插件无论何时安装/重启/热重载,今天的数据都以日志为准,
不漏计、不重复计数。shell.overlay):右下角一只圆滚滚的史莱姆
(纯 CSS/SVG 绘制,无图片资源)。v0.8.0 参考 Codex 桌宠(Boba / Desk Otter)设计语言:
角色描边 + 底部暗影 + 地面阴影落地、尺寸加大(64px)、hover 探头、双击逗宠物
(4 颗爱心依次飘起,最大一颗最后飞出 + 蹦跳 + 开心脸)。v0.9.0 赋予生命力:
情绪切换 180ms 弹入过渡、待机身体浮动 + 眼睛左顾右盼、工作态屏幕光标闪烁 +
加载点、晕眩双星对称环绕 + 身体摇摆;面板头部显示当前状态行(工作中/忙到冒汗/
转圈圈/打瞌睡/休息中/干完活啦,彩色圆点)。情绪 = 实时工作状态 + 今日用量:activity(上次活动时刻 + 最近完成列表)
附带进 /token-stats/summary,客户端 2.5s 轮询;只要任何会话在活动
(turn/start、tool/call、assistant/chunk 等事件都会刷新活动时刻),
宠物就"专注盯小电脑"(表情 + 打字颠簸 + 白屏小电脑蓝色进度条动画 +
右上角脉冲点动画 + 扩散光环动画),悬停气泡显示「正在干活…」;0 请求 → 打瞌睡、轻用量 → 休息眯眼、<300k → 冒汗、
≥300k → 晕眩(阈值可改 src/client.ts 的 MOOD_BUSY_AT /
MOOD_DIZZY_AT);✅ 任务完成 · 输入/输出 · 子代理 提示(v0.8.0 起带小史莱姆图标 + 绿边
卡片)+ 扩散光环 + 蹦一下(普通单会话回复不打扰);整段多任务全部收工弹
💤 收工啦~(蓝边卡片);顶层会话 X + 子代理会话 Y(n 个)= 总计 Z,
说明插件统计全部会话(含子代理),GUI 会话列表只显示顶层/usage 命令:对话中输入 /usage 直接查看今日用量(缩写 + 子代理对账行,
结果渲染为对话流节点)。设置 → 插件 页出现 token-stats 卡片,
可修改 storagePath / keepDays,保存即实时生效(改路径会先把旧数据落盘,
再在新路径从日志重建今天)。统计面板本身在 设置 → 用量统计(插件页不展示
统计内容,那是独立的 settings 分区)。GET /token-stats/summary?day=YYYY-MM-DD(默认今天)GET /token-stats/history?days=N(默认 7,上限 30)GET /token-stats/sessions?day=YYYY-MM-DD(v0.3.0:按会话明细,含子代理标记)从 GitHub 安装(推荐,锁定版本标签):
dsh plugin --profile web add "github:FantasyStarry/dsh-token-stats#v0.4.0"
本地源码安装(开发调试):
# 1. 安装进 web profile(file: 引用源码目录)
dsh plugin --profile web add "file:C:/path/to/dsh-token-stats"
# 2. 在 $DSH_HOME/profiles/web/cordis.patch.yml 中激活:
# - insert:
# - id: token-stats
# name: dsh-token-stats
# 3. 重启 dsh web(服务端插件代码变更需要重启加载;浏览器刷新页面加载客户端插件)
开发迭代注意:本机 profile 的
nodeLinker: hoisted(pnpm v11)会把file:依赖拷贝进node_modules,并非符号链接。改代码后需要重新dsh plugin --profile web add "file:..."或手动把lib/同步到node_modules/dsh-token-stats/lib/:客户端 bundle(client.js)是每次请求实时 读文件的,同步后刷新浏览器即生效;服务端(index.js)需要重启 dsh web。
升级插件:改代码 → 提交推送 → 打新标签(如 v0.2.0)→
dsh plugin --profile web add "github:FantasyStarry/dsh-token-stats#v0.4.0" → 重启 dsh web。
注意(v0.1.0 已知问题,v0.1.1 修复):DSH 会话日志(
session.jsonl.zstd)是 多帧 zstd 容器——每批事件追加一个独立压缩帧。v0.1.0 的回填用zstdDecompressSync解整个文件只能得到第一帧(通常是 session 头),导致启动回填 实际读到 0 条 usage:插件加载之前发生的调用全部漏计(实测漏掉约 3/4 的用量)。 v0.1.1 改为按帧完整解码 + 每次加载重建今天,数据与日志完全一致。
cordis.patch.yml 行支持 config:
- insert:
- id: token-stats
name: dsh-token-stats
config:
storagePath: C:/path/to/token-stats.json # 默认 $DSH_HOME/storages/token-stats.json
keepDays: 366 # 历史保留天数
默认 $DSH_HOME/storages/token-stats.json(原子写入,防抖落盘):
{
"days": {
"2026-08-14": {
"opencode-go": {
"deepseek-v4-flash": {
"requests": 29, "inputTokens": 8000, "outputTokens": 16000,
"cacheReadTokens": 6800000, "cacheWriteTokens": 0, "reasoningTokens": 0
}
}
}
}
}
src/index.ts 服务端插件源码(TypeScript,strict)
src/client.ts 客户端插件源码(AMD bundle,window.__ModuleLoader__ 加载)
lib/index.js tsc 编译产物(运行/发布用,改 src 后 pnpm build 重新生成)
lib/client.js tsc 编译产物
tsconfig.json strict 编译配置(ES2022 + ESNext 模块,输出 lib/)
test-standalone.mjs 服务端逻辑独立测试(pnpm test)
audit-sessions.mjs 会话日志审计工具:完整解码所有日志并与插件统计对比
verify-real.mjs 用真实日志验证重建逻辑(storage 指向临时文件,不碰真实数据)
verify-ui.py Playwright 端到端验证(python verify-ui.py)
verify-pet.py Playwright 用量宠物验证:情绪/气泡/面板/拖拽/开关 + 截图
(python verify-pet.py)
verify-live.py Playwright 实时活动验证:路由注入 activity,验证工作脸/脉冲点/
完成提示/收工提示/休息表情(python verify-live.py)
开发流程:改 src/*.ts → pnpm build(tsc 生成 lib/*.js)→ 把 lib/ 同步到
profile 的 node_modules/dsh-token-stats/lib/ → 刷新浏览器(客户端)/ 重启
dsh web(服务端)。服务端插件对 @deepseek-ai/schemastery、@deepseek-ai/dsh-settings
使用动态 import + 优雅降级(解析不到时仅无配置表单)。
assistant/message 事件在适配器上报时携带 usage
(DeepSeek 官方适配器与 pi-ai 适配器均上报)。未上报的调用不会计入。dsh.client 字段的包并通过
/plugins/<id>/client.js 运行时提供。CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。