npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lmber/dsh-token-usage-stats

v0.4.5

Published

Token usage statistics plugin for DeepSeek Harness: records per-call token usage and shows it in a settings page

Readme

@lmber/dsh-token-usage-stats

为 DeepSeek Harness 提供 token 用量统计的第三方插件:自动记录每次模型调用的 token 消耗(含速度指标),在设置页提供独立查看界面,并可把账本增量同步到远程聚合服务,实现多设备用量集中统计。

安装不需要改动 DSH 源码,配置持久保存在 $DSH_HOME,重启后继续生效。

功能

  • 每次模型调用自动追加一条记录到 JSONL 账本(schema v2:含 deviceId、事件时间戳、durationMs、firstTokenMs、outputTokensPerSec)
  • 设置页内独立的「Token 使用统计」面板
  • 范围筛选:今日 / 昨天 / 前天 / 本周 / 本月 / 全部,按月直接选择(<input type="month"> + 上/下月快捷按钮),也支持自定义起止日期
  • SVG 柱状图展示消耗趋势:按天(近 30 天) / 按月(近 14 个月)切换;无记录的日子显示为基线,不再跳天;悬停柱子弹出精确数值
  • 各模型每日/每月用量堆叠趋势图,Top 6 模型 + 其余合并,图例着色
  • 自然月历热力图:按真实日历布局显示所选月份的每日消耗,可前后翻月,不再偏移错位
  • 饼图展示模型用量占比 Top 10 + 其余合并,图例与悬停提示带百分比;调色板为柔和低饱和 12 色(无刺眼的大红大黄)
  • 卡片新增输出速度(tok/s)、平均首字延迟、平均单次耗时;汇总卡片含输入 / 输出 / 缓存命中(缓存写入在当前提供商无数据,未展示)
  • 模型输出速度排名面板:按输出速度降序(总输出 tokens ÷ 总解码耗时 聚合,而非各次调用速度的算术平均),附带首字延迟与平均耗时,可直接比较各模型快慢
  • 输出速度趋势面板:按天 / 按月展示每个时间段的输出速度(tok/s,同样按总量比值聚合),用于比较不同日期的速度差异
  • 多设备远程汇总:可在设置面板内直接配置 remoteUrl 与鉴权 token(无需改 cordis 配置);账本增量推送到远程服务(按 deviceId 隔离存储、可跨设备聚合),面板可切换「本机 / 远程汇总」数据源,并展示同步状态(待同步条数、上次同步时间、失败原因)
  • 设备标识自动生成 UUID 并持久化,可用配置覆盖
  • 大数字自动换算单位(k / M / B / T),卡片、表格、图例、悬停提示统一缩写
  • 进入面板与切换筛选时自动拉取最新数据,无需手动刷新

安装

dsh plugin --profile web add @lmber/dsh-token-usage-stats

然后重启 DSH。插件自带自挂载配置(dsh.bundle.patch),装上即生效,不需要手写任何 cordis 配置。

打开设置,左侧应出现「Token 使用统计」一栏。

卸载

dsh plugin --profile web remove @lmber/dsh-token-usage-stats

重启后插件及其设置页消失。账本文件会保留,需要的话手动删除。

账本位置与格式

默认写入 $DSH_HOME/token-usage-ledger.jsonl(DSH_HOME 未设置时为 ~/.dsh)。

每行一条 JSON 记录(schema v2):

{
  "type": "model-call",
  "v": 2,
  "ts": 1787102662243,
  "iso": "2026-08-19T01:24:22.243Z",
  "deviceId": "dev-8f2a…",
  "sessionId": "session-xxx",
  "provider": "deepseek-official",
  "model": "deepseek-chat",
  "inputTokens": 1000,
  "outputTokens": 500,
  "cacheReadTokens": 0,
  "cacheWriteTokens": 0,
  "reasoningTokens": 0,
  "totalTokens": 1500,
  "durationMs": 4210.5,
  "firstTokenMs": 380.2,
  "outputTokensPerSec": 92.4,
  "workspacePath": "D:/work/repo",
  "workspaceTitle": "repo"
}
  • totalTokens 是计费 token 总量:inputTokens + outputTokens + cacheReadTokens + cacheWriteTokens,四项互不重叠,其中 inputTokens 只含未命中缓存的输入;reasoningTokens 已包含在 outputTokens 内,不重复计入。
  • ts 取会话事件自身的 time 字段(精确到每次调用的完成时刻)。计时指标自 v0.4.3 起按当前 DSH 会话格式推导:每次调用的起点锚定在最近的 step/start / request/header(工具循环中会被 tool/result / assistant/attempt 推进),首字时间取自 assistant/message 内嵌流(format v2+,text-chunks / reasoning-chunks / tool-call-chunks 的首个 token 记录)与 assistant/message 完成时间的差值,分别得到 durationMs(请求发出到完成)与 firstTokenMs(首字延迟)、outputTokensPerSec(本次调用的输出速度,outputTokens ÷ (durationMs − firstTokenMs))。旧版本 DSH 的 assistant/chunk 事件流仍受支持。账本行保留每次调用的原始速度;面板与接口展示的速度是聚合值(Σ输出 tokens ÷ Σ解码耗时,与 DSH 原生会话统计一致),单个「首字几乎等于完成时间」的调用不会拉高整体读数。
  • v0.2.0 及更早的记录没有 v 与速度/设备字段,读取时自动兼容;速度类指标只在有新字段的记录上统计。

账本是纯 JSONL,可以直接用其他工具分析:

# 总调用次数
wc -l < ~/.dsh/token-usage-ledger.jsonl

多设备远程同步

配置(两种方式皆可,设置面板优先)

方式一:设置面板(推荐) — 打开「Token 使用统计」,在「远程同步配置」卡片填写服务地址与可选的鉴权 token,点击「保存配置」。配置立即生效并持久化到 $DSH_HOME/token-usage-config.json(token 输入框留空表示保持不变)。

方式二:cordis 配置(部署时预设)— profile 的 cordis.patch.yml:

- id: token-usage-stats
  config:
    remoteUrl: "https://stats.example.com"
    remoteToken: "your-token"        # 可选;与远程服务端 DSH_TS_TOKEN 对应
    # deviceId: "my-laptop"           # 可选;覆盖自动生成的 UUID
    # deviceName: "办公笔记本"        # 可选;默认取主机名
    # syncIntervalMs: 60000           # 可选;推送间隔,默认 60 秒
  • 未配置 remoteUrl 时行为与旧版完全一致:仅本地记账与展示。
  • 配置后,插件每分钟(或按 syncIntervalMs)把未同步的账本行批量 POST 到 {remoteUrl}/api/v1/ledger/upload,并持久化水位(token-usage-sync.json),失败自动留待下次重试,绝不影响本地记账。
  • 设置面板保存的值优先于 cordis 配置,且无需重启即生效;切换 remoteUrl 会重新建立推送水位(新目标从头同步)。
  • 面板顶部的数据来源开关(「本机 / 远程汇总」)仅在启用远程后出现;远程视图通过本机插件代理查询,浏览器不直连远程,避免 CORS 且统一鉴权。
  • 设备 UUID 自动生成并保存在 $DSH_HOME/token-usage-device.json,可用 deviceId 配置覆盖。

参考服务端

本包附带一个零依赖的 Node 聚合服务(server/index.js),存储按设备隔离(<dataDir>/<deviceId>.jsonl),查询时跨设备聚合。可用于任何一台常开的机器:

node server/index.js
# 环境变量:
#   PORT            监听端口(默认 8787)
#   DSH_TS_DATA_DIR 数据目录(默认 ./data)
#   DSH_TS_TOKEN    鉴权 token;设置后所有请求需带 Authorization: Bearer <token>

服务端接口(与插件本机路由同语义):

  • POST /api/v1/ledger/upload — 设备推送账本行 { deviceId, deviceName, rows }
  • GET /api/v1/ledger/summary?range=&from=&to=&devices= — 跨设备汇总(devices=all 或指定 deviceId)
  • GET /api/v1/ledger/series?granularity=&limit=&devices= — 连续窗口时序
  • GET /api/v1/ledger/series-by-model?granularity=&limit=&devices= — 按模型时序
  • GET /api/v1/ledger/devices — 设备列表与各自统计

HTTP 接口

主机端注册了只读路由,浏览器界面通过它取数据,也可以自己调用:

GET /api/token-usage-stats?range=day|yesterday|day-before|week|month|all|YYYY-MM
GET /api/token-usage-stats?from=YYYY-MM-DD&to=YYYY-MM-DD
GET /api/token-usage-stats?source=local|remote
  • range=YYYY-MM 直接选择某个月(如 2026-08),from/to 按本地时区解析,含首尾两天,两者都可省略。day / yesterday / day-before 各覆盖对应那一个本地日;week / month / all 从各自起点到当前时刻。非法参数返回 400。
  • source=remote 时本机插件代理到远程服务做同样的查询(需要已配置 remoteUrl)。

柱状图与模型趋势的数据来自分桶时间序列接口:

GET /api/token-usage-stats/series?granularity=day|hour|month&limit=N&source=
GET /api/token-usage-stats/series-by-model?granularity=day|hour|month&limit=N&source=
  • 返回连续窗口:窗口内无记录的桶为 { tokens: 0, calls: 0 },柱状图因此不跳天。day 窗口止于今天,month 止于本月,limit 只返回最新 N 桶(默认按最早记录起算)。每个桶额外携带 avgTokensPerSec(该窗口内所有调用的输出速度,按 Σ输出 tokens ÷ Σ解码耗时 聚合;无速度数据时为 null)。
  • series-by-model 返回 { granularity, buckets, series },所有模型共享同一窗口便于对齐。
  • 汇总接口的 byProvider / byModel 每行额外携带 avgOutputTokensPerSec、avgFirstTokenMs、avgDurationMs(仅统计有对应数据的行)。avgOutputTokensPerSec 与 DSH 原生会话统计同义:Σ输出 tokens ÷ Σ(durationMs − firstTokenMs),首字延迟与完成时间几乎重合的调用(如纯工具调用响应)不会像"各调用速度算术平均"那样把读数拉高。

设备与同步状态:

GET /api/token-usage-stats/meta

返回 deviceId、deviceName、entryCount 与 sync 状态(enabled、pendingCount、lastSyncAt、lastError)。

远程同步配置(设置面板读写):

GET /api/token-usage-stats/config
PUT /api/token-usage-stats/config   # body: { "remoteUrl": "...", "remoteToken": "..." }
  • GET 返回 remoteUrl、remoteUrlSet、remoteTokenSet(不含 token 明文)。
  • PUT 应用并持久化配置;remoteUrl 传空字符串停用远程;不传 remoteToken 字段表示保持原值。切换 remoteUrl 会重置推送水位并立即重启同步。

该路由绑定在 DSH web 服务器上,跟随其监听地址(默认仅本机 127.0.0.1)。它没有独立鉴权,与 DSH web 界面本身共享同一信任范围 —— 如果把 DSH 暴露到非本机地址,这份用量数据同样会被暴露。

本地开发

node tests/smoke.mjs          # 聚合逻辑冒烟测试(真实账本,无账本时用合成数据)
node tests/integration.mjs    # cordis 集成测试:真实运行时内验证记账/路由/远程同步全链路
node server/index.js          # 启动参考聚合服务

tests/integration.mjs 在隔离的 cordis Context 中加载插件的 apply(),驱动模拟的 session/event 事件流(既含 format v2+ 的 step/start → request/header → 内嵌流 assistant/message → tool/result 工具循环,也覆盖旧版 assistant/chunk 事件流),断言账本行的时间/速度/路由/工作区字段、HTTP 路由响应,并起一个临时参考服务验证增量推送、水位持久化与远程代理查询。需要本机存在 DSH profile 安装(用于定位 @deepseek-ai/cordis),否则自动跳过。

兼容性

依赖 DSH 的 session/event 事件流、webServer 服务和 settings.section 插槽。DSH 尚未正式发版,这些接口仍可能变动;插件在这些接口变更后可能需要同步更新。

webServer 服务缺失时(例如 headless profile)只记录账本,不注册 HTTP 路由;远程推送在 webServer 缺失时仍然工作(记账与推送不依赖 webServer)。

已知限制

  • 统计基于插件安装后产生的记录,装之前的历史调用无法追溯;速度类指标自 v0.4.0 起才有(旧记录显示「—」)。
  • 展示的速度是聚合值(Σ输出 tokens ÷ Σ解码耗时);账本行保留每次调用原始速度(outputTokensPerSec),需要逐次分析时直接读账本。
  • 单次调用若「首字时间」记录的流式片段极少(如纯工具调用响应被提供商缓冲到结尾才吐出),其 durationMs − firstTokenMs 会非常小、单次 outputTokensPerSec 会异常高——这是记录本身的真实时序,聚合展示已消除其影响;若需要单次速度请以账本行为准并结合 firstTokenMs/durationMs 判断。
  • 账本只追加不轮转,长期使用会持续增长,需要时自行归档。
  • 面板在进入或切换筛选时自动拉取数据(连接打开期间不轮询,需要最新数字可重新进入面板)。
  • 远程汇总视图反映的是「已成功推送到服务端」的数据,未推送行在「待同步」计数中可见。
  • 热力图默认显示当前月;翻到数据窗口(约 62 天)之外的月份会显示空月。

License

MIT