DSH Plugins Marketplace

DSH Plugins

Plugins

/

Tools & Capabilities

/

dsh-token-bi

d

dsh-token-bi

Manifest valid

Cross-session token dashboard for DSH: daily stacked columns, hourly rhythm, model and workspace splits, call tree, and detailed per-turn/search timeline.

UI (client)hasBundlePatch

dsh-token-bi

DeepSeek Harness 的 token 消耗看板 —— 把散落在各个会话里的用量汇总成一张表:每天烧了多少、哪个模型最贵、哪些工作目录在消耗、父子会话各占几成、每一轮具体花在哪。

DSH 自带单会话的 token 统计,但没有跨会话的视图。这个插件补上这一层,并对齐 Host 自己的计量口径,不会出现"插件显示的数字和会话里对不上"。

中文 | English

看板总览


目录


它解决什么问题

用 DSH 一段时间后,几个问题会冒出来:

  • 这个月一共花了多少 token?散在 20 多个会话里,没有一个地方能看总量。
  • 哪天突然变多了?是哪次任务把用量拉高的?
  • 缓存命中率怎么样?—— 这一项容易被忽略但影响最大:cacheRead 通常是总量的绝大部分,因为每轮都要把整个上下文重新读一遍。
  • 让子代理并行干活时,父会话和子会话各占多少?

这个插件把会话日志里 provider 上报的用量折叠成上述维度。


安装

前置条件

  • DSH Desktop 或 dsh CLI(Web 界面)
  • Node.js ≥ 22.15(会话日志是 zstd 压缩的,需要 zlib 的 zstd 支持)

从本地目录安装(当前可用方式)

git clone https://github.com/361533652/dsh-token-bi.git
dsh plugin --profile desktop add "link:/绝对路径/dsh-token-bi"

Windows 路径示例:

dsh plugin --profile desktop add "link:E:\gitbub-project\dsh-token-bi"

link: 表示软链安装,改动仓库里的代码无需重装。安装完成后完全退出并重启 DSH Desktop(不是刷新页面)——客户端 bundle 的路径表在进程启动时构建一次。

验证

重启后左侧栏面板列表里会出现「Token 账单」,位置紧挨着「插件」。

如果没出现,按顺序检查:

  1. 设置 → 插件 → 已安装插件 里是否有 Token 账单 且开关为开
  2. dsh --profile desktop --dump-config 输出里是否有 id: token-bi 这一行
  3. Host 日志(%APPDATA%\DSH Desktop\logs\host\)里搜 token-bi,看有无激活失败

插件在加载时会把 [token-bi] factory、[token-bi] apply、[token-bi] slot:xxx 写到浏览器控制台(用 console.error,因此会进 Host 日志)。这些标记能区分"代码没下载"、"下载了没激活"、"激活了没注册成功"。


界面说明

入口是左侧栏的全局面板(和「插件」「自动化任务」同级),不绑定某个会话——汇总数据天生属于全局层。

顶部数字

指标含义
累计 token当前时间窗口内的四类 token 总和
今日消耗本地时区下今天的总和
会话窗口内的会话数,副标题是其中正在运行的个数
轮次去重后的 turn 数
缓存命中占比cacheRead / 总量。这个数通常很高(80%+),说明上下文复用得多

图表

  • 每日消耗 —— 三种视图可切换:
    • 柱状图(默认):按日堆叠,四段分别是输入、缓存读、缓存写、输出。
    • 趋势图:每日消耗的折线与填充面积,看波峰波谷。
    • 累积图:周期内累计花销的攀升曲线,看哪几天坡度最陡。 三种视图都悬停看明细,点击某一天即按日联动筛选。图表覆盖当前窗口的全部日期,不受 30 天上限约束。
  • 年度活跃日历 —— GitHub 风格的贡献格子图,固定展示最近 365 天的每日消耗强度(5 档绿色),不受时间窗口影响;点击格子同样按日联动筛选。
  • 模型分布 —— 按 provider/model 拆分,附带占比,按消耗排序。
  • 工作区分布 —— 按会话的 cwd 分组,超过 8 个时折叠并显示被折叠部分的合计(避免让人误以为数据缺失)。
  • 会话明细 —— 主表。点任意一行展开该会话的逐轮时间线(每轮一条三段式条形);子代理的行会按其层级缩进。
  • 调用树 —— 父会话下挂子会话,用深浅两种颜色区分"这个会话自己花的"和"它派生的子会话花的";点击任意节点会平滑滚动到会话明细并展开它。

交叉筛选

四个维度互相联动:日期、模型、工作区、会话状态(进行中 / 历史)。

点一下某天的柱子、某个模型条、某个工作区条,其余卡片与会话列表会立刻按这个条件重算——比如选中某个模型后,工作区列表只剩用过它的那些,会话表的数字也只剩该模型的部分。

会话明细上方的筛选条会列出当前生效的条件,每一项都能单独取消,也可以一键「清除全部筛选」。

从调用树点进会话明细时,如果目标被当前筛选隐藏了,插件会自动清掉冲突的条件再定位过去。

时间窗口

右上角三档:7 天 / 30 天 / 全部。

切换会向 Host 重新取数并按日重算总量,不是只过滤已有数据——所以数字、图表、会话列表会一起变。窗口内没有消耗的日子也会保留在时间轴上(7 天就是 7 天,30 天就是 30 天),不会因为几天没用量就把跨度缩掉。

导出

右上角「导出 CSV」,导出当前窗口内的会话列表,带 UTF-8 BOM,Excel 直接打开不乱码。


数据从哪来、怎么算

数据源

两个来源,按会话 id 合并,活跃会话优先:

来源读什么作用
ctx.sessions内存中的会话事件当前打开的会话,永远最新
ctx.sessionQuery冷启动的持久日志历史会话,让没打开的会话也能统计

不需要读原始 .jsonl.zstd 文件——都走 DSH 的公开服务。

计量口径

这是本插件最需要讲清楚的部分。规则直接对齐 Host 的 tokenUsage 投影(@deepseek-ai/dsh-token-meter):

  1. 只看 provider 上报的用量,不估算。来源是 assistant/message 事件的 usage 字段,或 stream 里最后一个 type: 'usage' 的 chunk。
  2. 同一 (turn, step) 后到的样本替换先到的。一次重试会产生多个样本,这条规则保证重试的用量只计一次,不会重复累加。
  3. 四个桶分开记:inputTokens / outputTokens / cacheReadTokens / cacheWriteTokens,总量是四者之和。

第 2 条是关键。如果不做替换,失败重试的会话数字会虚高。校验方式:拿一个会话跑一遍折叠,四个桶的数字应当和会话界面里显示的完全一致。

时间归属

按事件时间戳落到本地时区的日期。浏览器把 getTimezoneOffset() 传给 Host,Host 用它给每条记录分日——所以跨时区使用、或跨零点运行的长任务,日期归属都是对的。

缓存

  • 单会话结果按 (会话 id, revision) 缓存,revision 是活跃会话的 seq 或持久会话的元数据;没变就复用。
  • 整个报告缓存 10 秒,refresh=1 强制重建。
  • 缓存键包含时间窗口,切换档位不会串数据。

HTTP 接口

插件在 Host 上注册一个前缀路由,浏览器用同源请求读数据。

GET /api/dsh-token-bi/report?offset=<分钟>&days=<窗口>&refresh=1
GET /api/dsh-token-bi/session?id=<会话 id>&offset=<分钟>
参数说明
offset浏览器时区偏移(分钟),默认取 Host 时区
days窗口天数;0 或 all 表示全部
refresh1 时跳过 10 秒缓存

report 返回:

{
  "generatedAt": 1792500000000,
  "offsetMinutes": 480,
  "rangeDays": 30,
  "cutoffDay": "2026-09-22",   // 窗口起点;全部时为省略
  "totals": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0, "total": 0,
              "sessions": 0, "live": 0, "turns": 0, "steps": 0 },
  "sessions": [ /* 每会话:id/title/cwd/parentSession/totals/models/days/... */ ],
  "models":   [ /* provider/model 汇总 */ ],
  "days":     [ /* 按日,含缺失日补零 */ ],
  "hours":    [ /* 最近 7 天按小时 */ ],
  "cwds":     [ /* 按工作目录 */ ],
  "cells":    [ /* day × model × cwd 交叉表,供前端交叉筛选 */ ],
  "errors":   [ /* 读失败的会话,不阻断整体 */ ]
}

session 返回单个会话的逐轮 rows(turn/step/time/input/output/cacheRead/cacheWrite/total),供展开行按需拉取——所以首屏不会因为历史很长而变慢。

这个路由沿用 DSH 插件惯用的 webServer 前缀注册。注意:路由在进程级只注册一次,重载时替换 handler 而非重复注册——重复注册会让 webServer 抛错并使整个插件激活失败(这是开发过程中踩过的真实坑,见 test/reload.mjs)。


配置

没有配置项。 所有参数(时间窗口、筛选)都在界面上切换,不需要改 profile 配置。

插件在 profile 里只有一行:

- insert:
    - id: token-bi
      name: dsh-token-bi

设计取舍

几个刻意的决定,写下来免得后来的人以为可以随手改:

汇总放在全局面板,不放在会话里。 跨会话的数据放进单会话的界面是位置错误,用户会以为那是"这个会话的统计"。

只读日志,不写任何东西。 插件不追加会话事件、不落自己的数据库。DSH 的会话日志是唯一事实来源,任何派生数据都应该是可重建的缓存。

对齐 Host 口径而非自创公式。 用户会拿插件数字和会话界面比对;两边不一致比数字不准更糟。

不做成本估算。 不同 provider、不同模型、不同缓存策略的单价差异极大,硬编码一张价格表会给出误导性的确定性。想知道钱花了多少,看 provider 的账单。

没有设置页。 没有任何可配置项,加一个设置页会多出一个什么都不做的入口。


已知限制

  • 只统计上报了用量的步。 如果某个 provider 不返回 usage,那一步对统计不可见。这不是漏算,是无从算起。
  • 压缩掉的历史仍然计入。 统计是"日志口径"而非"当前可见上下文口径"——被压缩的消息仍然算在会话总量里,这符合"这轮对话花了多少"的直觉,但和"当前上下文多大"是两件事。
  • 子会话独立计费、独立统计。 父会话的数字不包含子会话;调用树里两者分层显示,叠加才是整棵子树的花费。
  • 极长的会话会截断逐轮列表。 展开行最多显示最近 60 轮,避免长会话拖慢渲染;总量不受影响。
  • 数据只覆盖本机。 读的是本机 DSH 的会话存储;多机部署需要分别查看。
  • 需要 Web 界面。 依赖 webServer 服务,纯 TUI profile 下不会激活。

开发

目录结构

index.js              Host 半:注册 HTTP 路由
lib/collector.mjs     聚合:合并活跃/持久会话,产出报告
lib/usage.mjs         口径:把一份会话日志折叠成用量记录(纯函数,无 IO)
lib/client.js         浏览器半:面板注册 + 页面与图表
cordis.patch.yml      bundle patch:插入 Host 行
locale/{zh,en}.json   插件元信息(标题、描述、图标)
test/                 离线测试,见下

lib/usage.mjs 是纯函数模块,不碰文件系统和 Cordis,可以直接拿任意事件数组调用——口径逻辑都在这里,改动应当先补测试。

测试

npm test              # locale 一致性、重载竞态、槽位注册、页面渲染
npm run test:store    # 用本机会话存储跑一遍聚合(只读)
npm run test:route    # 用桩 context 驱动 Host 路由
测试覆盖什么需要什么
locale-check.cjs中英文字典键集一致、t() 用到的键都有定义无
reload.mjs热重载时不重复注册路由(回归:曾经导致插件消失)无
slots.mjs对真实 SlotCore 跑注册,且不再注册设置页DSH_APP_DIR
render.mjs用最小 hooks 运行时把页面真渲染一遍,含展开行交互本机会话存储
harness.mjs聚合结果的人眼核对输出本机会话存储
route.mjs路由的 200/400/404 与 JSON 契约本机会话存储

测试默认读 $DSH_HOME/sessions(默认 ~/.dsh/sessions),可用 DSH_SESSIONS 或命令行参数指向别处;没有历史数据时会建空报告而不是报错。

slots.mjs 需要 DSH 自带的 @deepseek-ai/dsh-client-ui-slots:

DSH_APP_DIR="E:\dsh\DSH Desktop\resources\app" npm test

找不到时该测试会打印 SKIP 并以 0 退出,不会假装通过。

改动时的注意事项

  • lib/client.js 不能 require DSH 的客户端包(如 ui-primitives)。样式和控件要么自己写,要么照抄 Host 的实现后改成自己的前缀类名,只引用 --dsw-alias-* 主题变量。
  • 样式必须走主题 token,否则深色模式下会瞎。
  • dsh.client.inject 填的是包名(如 @deepseek-ai/dsh-client-ui-renderer),不是运行时服务名(slots)——写错会导致模块一直停在 loading 并把整个页面拖成 "Failed to load plugins"。
  • 客户端入口放在 lib/client.js,与生态里其他插件一致。

许可

MIT

Comments

Loading…

Similar plugins

dsh-token-usage-stats

by jkStars

DeepSeek-styled cross-session token usage, request count, and tiered cost analytics dashboard.

Tools & CapabilitiesModels & ProvidersManifest valid

★ 3

↓ 1.2k/wk

MIT

TypeScript

Oct 6, 2026

dsh plugin --profile web add dsh-token-usage-stats

by phungthien269

Token usage dashboard for the DSH web GUI — today/week/month totals, per-model breakdown and a stacked 30-day chart, with a 4-language UI.

Tools & CapabilitiesDevelopment & InfrastructureModels & ProvidersManifest valid

★ 0

↓ 89/wk

MIT

JavaScript

Sep 3, 2026

dsh plugin --profile web add dsh-token-stats

by iuuuuuuuu

DSH plugin: per-day token usage and time-to-first-token statistics, broken down by workspace and session. Reads local session logs only.

Manifest valid

★ 0

MIT

JavaScript

Sep 16, 2026

dsh plugin --profile web add dsh-usage-stats

by zoahdev

Turn-based time tracking from dsh session logs: totals, per-day/project/provider/source rollups, tool-call counts, failure rates, and time-to-first-token — CLI plus an agent-callable timesheet tool, d

Development & InfrastructureManifest valid

★ 1

↓ 47/wk

MIT

TypeScript

Aug 18, 2026

dsh plugin --profile web add dsh-timesheet

by zhujiuyi

Token usage dashboard in the DeepSeek Harness sidebar: daily totals from session logs with a 12-month heatmap, per-provider breakdown over today/7d/30d/all (hourly for today), and a per-session rankin

Tools & CapabilitiesDevelopment & InfrastructureManifest valid

★ 1

MIT

JavaScript

Oct 23, 2026

dsh plugin --profile web add @zhujiuyi/dsh-token-dashboard

by cute-baobao

DeepSeek Harness usage recorder plugin: per-model hourly token usage (input/output/cache hits) with a stacked bar chart dashboard in the Web GUI.

Manifest valid

★ 3

↓ 124/wk

MIT

TypeScript

Aug 14, 2026

dsh plugin --profile web add @dsh-usage-meter/usage