deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
面向 DSH(DeepSeek Harness)Web GUI 的本地用量看板:Token、费用、时长与会话明细,全部在本机聚合,不上传任何会话内容。
🌐 语言 / Language: English · 中文
dsh-usage-dashboard 是一个 DSH bundle 插件。它直接读取 DSH 本地会话数据,在 设置 → 数据看板 中提供用量统计。所有聚合都在本机完成,不会向外部服务发送任何会话内容。
交互参考 VibeCafe.ai 的 Vibe Usage,提供指标切换、分布 hover 与明细浏览;统计与聚合完全在本地完成。

顶部筛选器支持时间范围 今天 / 24H / 7D / 30D / 90D / 自定义(自定义可填起止日期);模型筛选为多选、按厂商分组(可展开勾选具体模型,选中后按钮显示「N项」);项目下拉可选单个项目;有筛选时可一键清除。所选范围、筛选与显示偏好保存在本地(localStorage),重开设置或重载插件后仍保留。数据刷新期间显示「统计中」。
共 9 张指标卡片:预估费用、总 Token、输入 / 输出 / 缓存 Token、活跃时长、总时长、会话数、总消息数、用户消息数。每张卡片带相对上一周期的环比百分比(基线为零时隐藏)。
随所选范围自动切换粒度:今天 / 24H 为每小时,7D / 30D 为每日,90D 为每周(自定义范围按跨度:≤48 小时用小时、≤62 天用天,更长用周)。可在 Token / 费用 / 时长 三种口径间切换:
点击任意柱子高亮该项(其余变淡),再次点击空白处取消;悬停查看明细。X 轴标签按固定步长标注(今天每 3 小时一格、30D 每 4/5 天一格、90D 每 2 周一格)。

7 行(周几)× 24 列(小时) 网格,可在 Token / 费用 / 时长 三种指标间切换;悬停任意单元格显示精确数值与时刻,图例为 少 → 多。(上图下半部分即为此图。)
两张环形图分别从 Token(或费用)视角拆解用量:模型分布按模型拆分,项目分布按项目(基于会话 cwd 与 DSH workspace 归属)拆分。可在 Token / 费用间切换;占比前 6 项各有固定配色,其余聚合为「其他」,总量守恒。悬停图例项或扇区时,其余项与扇区变淡,圆环中心切换为当前项的 Token 与费用摘要。

最近 40 周的 7 行 × 40 列 日历网格,单元格固定为正方形并带圆角;按每日 Token 量分 8 档着色(无 Token / ≥1M / ≥10M / ≥30M / ≥60M / ≥100M / ≥200M / ≥250M)。边缘日期的浮动 tooltip 自动限制在视口内。
按「时间桶 × 模型 × 项目」分组的明细表,列为 时间 / 项目 / 模型 / 工具 / 输入 / 输出 / 缓存 / 费用(工具列固定为 dsh);同一小时用多个模型时分别成行。分页展示(每页 20 条),右上角显示「显示 x–y 条,共 z 条」,底部可翻页。

六轴雷达图,展示当前筛选窗口内调用量前 4 的模型。各维度使用固定外圈基准值归一化到 0–1,因此不同时间窗口之间可直接比较。方向统一:越靠外圈越好。
| 维度 | 含义 | 外圈 | 中心 |
|---|---|---|---|
| 响应速度 | 一次请求通常要等多久(P50) | 1 s | 120 s |
| 输出速度 | 每秒吐出多少 tokens | 166 t/s | 1 t/s |
| 平均输出量 | 平均每次回复写多少 tokens | 1,645 tok/次 | 50 tok/次 |
| 平均输入量 | 平均每次读入多少计费输入 tokens | 29.4 万 tok/次 | 5,000 tok/次 |
| 稳定性 | 最慢的 5% 请求比典型请求慢几倍(P95/P50) | 慢 ≤8.3 倍 | 慢 125 倍 |
| 实际单价 | 每百万 tokens 实际花多少钱(全口径反向) | ¥0.10/M | ¥2/M |
各维度均使用双端对数带宽 log(v / floor) / log(ceil / floor) 归一化。图上顶点标注实测真值(如 8.0s、¥0.09/M);右侧为图例(含调用次数)与标尺行数值卡——每轴一条细轨道,四个模型的得分落点以小圆点同屏对比,当前模型放大高亮。模型未匹配定价表时,「实际单价」轴留空并标注。
点击雷达上的点或图例项可高亮单个模型(其余变淡):图例 hover 保持高亮,点击为锁定、再点取消。标题旁 ⓘ 弹窗按轴说明含义与外圈参考值。
一条时间序列 + 一张排行榜,展示所选范围内每个时间桶的缓存效率。
切换视图带过渡动画(折线描边生长、柱状从基线弹起并错峰、KPI 与图例淡入)。

看板跟随 DSH 的明暗主题:颜色统一由 CSS 变量表驱动(作用域 body[data-ds-dark-theme]),图表元素使用图形专用颜色变量,在两种主题下均有足够对比度。

pricing/vibe-usage-model-pricing-extended.csv(覆盖 280 个模型,由构建脚本生成 lib/core/pricing.js);表内单价已直接以人民币元 / 百万 token 计价,无需汇率换算。未匹配的模型暂不计费(明细表中显示 ¥0,可在 ⓘ 弹窗查看覆盖率)。模型 id 匹配不区分大小写,provider 目录中的 Qwen3.8-Flash 等写法按规范价目计费。deepseek-flash、deepseek-v4-pro)按北京时间计费——工作日高峰为 9:00–12:00 与 14:00–18:00,周末及其余时段为空闲(价格为高峰一半)。V4.1 Flash 新价自 2026-09-10 12:00 起生效,V4 Pro 自 2026-09-14 12:00 起路由到 Flash 计费;已下线的旧名与第三方转售商变体名按 Flash 计费,峰谷价生效前的历史事件按当时的静态价计算。cwd,再结合 DSH workspace membership 回填;路径分隔符、大小写和尾部斜杠会统一后再分组。delegationDepth > 0 或含 parentSession)与旧布局的裸 <uuid> 目录不计入,因此看板的会话数少于 ~/.dsh/sessions 下的目录总数。无法读取的日志(格式迁移失败、文件损坏)会被跳过。cacheRead / cacheObserved × 100%:cacheRead = provider 显式报告的 usage.cacheReadTokens 之和。cacheObserved = provider 报告了 cacheReadTokens 或 cacheWriteTokens 的行,取这些行的 inputTokens + cacheRead + cacheWrite 之和(即带 telemetry 的计费输入)。未报告的行不计入分母。billedInput = 全窗口 inputTokens + cacheTokens 之和,包含未提供 telemetry 的行。cacheObserved / billedInput × 100%;无 telemetry 时覆盖率为 0%,命中率显示「—」。| 项 | 要求 |
|---|---|
| DSH | 0.1.3-alpha.2 及以上(已在 0.2.0-rc.1 上验证) |
| Node.js | >=18(package.json 的 engines 声明) |
| 运行环境 | DSH Web / Desktop GUI(客户端半边注册为 settings.section) |
插件通过特性探测适配不同 DSH 版本:sessionPersistence 可用时直读单会话日志(快路径),否则回退到 sessionQuery.listSessions;timer 服务缺失时仅周期 reconcile 与预热降级,HTTP 路由不受影响。完整能力矩阵、rc.1 → rc.2 差异与升级例行程序见 COMPAT.md。
打开 DSH 设置,找到插件管理入口,点击「添加插件」,在输入框中填入以下任一内容:
| 来源 | 填写内容 | 示例 |
|---|---|---|
| 包名 | npm 包名 | @skkjkk/dsh-usage-dashboard |
| GitHub 仓库 | 仓库地址 | https://github.com/skkjkk/dsh-usage-dashboard |
| 本地目录 | 绝对路径 | D:\path\to\dsh-usage-dashboard |
右上角「安装源」可选择 npm 源(默认 / 中国大陆镜像源)。安装完成后重启 DSH,打开 设置 → 数据看板。
# 从 npm 安装
dsh plugin --profile web add @skkjkk/dsh-usage-dashboard
# 从 GitHub 安装(开发版本)
dsh plugin --profile web add "github:skkjkk/dsh-usage-dashboard#main"
# 从本地目录安装(开发调试)
dsh plugin --profile web add link:/path/to/dsh-usage-dashboard
没有 dsh CLI 时,可以手动安装:
pnpm --dir ~/.dsh/profiles/web add @skkjkk/dsh-usage-dashboard
然后在 profile 的 package.json 中确认插件位于 dsh.profile.bundles:
{
"dsh": {
"profile": {
"bundles": ["@skkjkk/dsh-usage-dashboard"]
}
}
}
dsh plugin --profile web remove @skkjkk/dsh-usage-dashboard
# 查看插件依赖关系
dsh plugin --profile web why @skkjkk/dsh-usage-dashboard
host 半边在 DSH 的 web server 上注册三条只读 JSON GET 路由(返回本地聚合结果,不含会话原文):
| 路由 | 说明 | 主要参数 |
|---|---|---|
GET /dash-api/usage |
KPI 总计 + 趋势桶 + 热力图 + 模型/项目分布 + 定价覆盖 | range、from、to、models、projects |
GET /dash-api/detail |
明细行(按「时间桶 × 模型 × 项目」分组) | 同上 + offset、limit(上限 200,默认 100) |
GET /dash-api/calendar |
日历热力图逐日 Token | models、projects、now |
range 取 today / 24h / 7d / 30d / 90d / custom(缺省 today);custom 需配合 from / to(epoch 毫秒)。models / projects 为逗号分隔的多值参数。响应形如:
// /dash-api/usage
{ "totals": { "cost": 0, "totalTokens": 0, "sessions": 0, "cacheHitRate": null, ... },
"buckets": [{ "label": "9/26", "input": 0, "output": 0, "cache": 0, "costIn": 0, ... }],
"granularity": "day",
"heat": { "token": [], "cost": [], "dur": [], "active": [] },
"meta": { "models": [], "projects": [], "vendors": {}, "pricing": {}, "dist": {} } }
请求级缓存为 30 秒 TTL + stale-while-revalidate + 单飞,重复调用为毫秒级。这些路由不经过 DSH GUI 的会话鉴权,可直接访问(端口为 DSH 实例实际监听的端口):
curl -s "http://127.0.0.1:<port>/dash-api/usage?range=7d" | head -c 200
可选的 debugCache 开关用于诊断磁盘 rollup 缓存,开启后向 stderr 输出 [dash-cache] / [dash-pending] / [dash-load] / [dash-event] 诊断行。在 profile 的 cordis.patch.yml 中以 id 定向覆盖的形式添加 config(该形式覆盖既有行,无需 insert: 包裹):
- id: usage-dashboard
name: "@skkjkk/dsh-usage-dashboard"
config:
debugCache: true
同一文件内
id重复会导致 DSH 启动失败(duplicate loader entry id)。
默认关闭。
源码位于 src/,DSH 加载的产物位于 lib/。修改 src/ 后需重新构建,不要直接编辑 lib/:
npm install
npm run build # node scripts/regenerate.cjs:把 src/ 适配为 lib/
npm run bench # 引擎正确性与性能基准
npm run smoke # build + host 冒烟测试
npm test # build + bench + host smoke
npm test 覆盖:
foldAppend 与完整 foldSession 的增量等价性(逐字节一致);totalMs 的并行会话去重;cacheRead / cacheObserved / billedInput)的守恒;/dash-api/usage、/dash-api/detail、/dash-api/calendar 三条 host 路由,以及 client bundle 的 slot 注册契约。发布前可验证 npm 包内容:
npm pack
# 将生成的 tgz 解压到 <package-dir> 后执行
node scripts/verify-pack.mjs <package-dir>
验证脚本检查 host / core / client 是否可加载、bundle patch 与 package.files 是否齐全,并扫描包中是否残留个人数据。
scripts/capture-screenshots.mjs 用于生成 README 截图:以真实的 lib/client.js 配合 /dash-api/* 数据在无头 Chromium 中渲染,并按卡片裁剪。
src/core/rollup.js:foldSession 把一次会话折叠为按小时分桶的紧凑 rollup,foldAppend 以单事件增量更新(与全量重算字节级一致),queryUsage / queryDetail / queryCalendar 在内存中回答任意窗口与筛选。persistence.readFrom 读取一次);之后 session/event 事件经 foldAppend 增量写入,刷新时不重新解析完整日志。每 60 秒一次 reconcile 发现新 / 移除的会话。~/.dsh/usage-dashboard-cache/<sessionId>.json,按日志文件 mtime + size 失效):DSH 重启后未变化的会话直接采纳缓存,无需重新解码。缓存格式带版本号,定价或口径变更时整体失效重算。lib/ 与 bundle patch;定价由生成的 lib/core/pricing.js 提供,原始 pricing/ 目录不进包,也不含本机日志或会话文件。delegationDepth > 0 / parentSession)与旧布局裸 <uuid> 目录不计入,因此会话数少于 ~/.dsh/sessions 的目录总数。totalMs 为区间并集:重叠的并行会话只计一次,窗口边缘按事件级精确裁剪,跨桶边界的情形为近似值。当前发布版本:0.3.13(变更记录见 CHANGELOG.md)
本项目鼓励你用 AI 辅助开发来按需增减功能。无论是删掉不关心的 KPI 卡片、增加新的图表维度,还是接入你自己的定价表——直接把需求告诉 AI,让它帮你改代码、跑测试、出构建产物。
几个常见方向:
src/client.js 的 cards2 数组中移除对应项即可src/client.js 中追加一个 section,调用已有的 /dash-api/usage 数据pricing/vibe-usage-model-pricing-extended.csv 后 npm run build 即可生效src/core/rollup.js 是纯聚合引擎,可以 fork 后替换事件源源码结构清晰(src/core/rollup.js 聚合、src/host.js 路由、src/client.js 界面),npm test 覆盖核心逻辑,适合 AI 直接上手改。欢迎提交 PR 分享你的定制版本。
Apache-2.0
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。