dsh-token-use 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -8,15 +8,26 @@ A real-time token usage and cost plugin for DeepSeek Harness: install it, then r
8
8
 
9
9
  ## Features
10
10
 
11
- - **Cost card** — spend estimated live from DeepSeek's published prices × the usage recorded here, with peak/off-peak rates. Every card (totals, trend, by model, by day, by project) carries an amount.
11
+ Four tabs across the top of the panel: **Overview / By model / By project / Configuration**.
12
+
13
+ - **Overview** — the cost and totals cards, the trend chart, and a **usage heatmap** (last 12 months, one cell per day, coloured by total tokens or by cost; hovering shows that day's tokens, cost and calls **instantly**, without the native tooltip's one-second delay). Range and model filters apply here.
14
+ - **By model** — every model's usage and amount, with the same range query (day / month / year / date range / all).
15
+ - **By project** — every project's usage and amount, same range query.
16
+ - **Configuration** — versions (`dsh-service`, `dsh`, `dsh-base` and this plugin: installed vs the newest release **in the channel you run**, rc/alpha/stable), runtime facts (platform version, Node version, PID, port, uptime, `DSH_HOME`), a **health check** and a confirmed **one-click restart**.
17
+ - **Self-check** (the health check button) reports three sections: **endpoint** (latency, version, history scan, price data, buckets, last update), **client bundles** (each plugin probed at the exact revisioned URL from this page's boot manifest, i.e. what the browser really loads) and **harness** (profile integrity — `node_modules`, lockfile, boot graph; plugin package integrity — entry file, `dsh.bundle.patch`, client bundle; dependency resolution; single cordis instance at one version; service bundle vs the running CLI). When a freshly installed plugin refuses to start, this names the package, the missing file and the fix.
18
+ - **Cost card** — spend estimated live from DeepSeek's published prices × the usage recorded here, with peak/off-peak rates. Every card (totals, trend, by model, by project) carries an amount.
12
19
  - **Daily price book** — the official pricing page is fetched once a day at **12:00** and cached locally, so restarts keep it and an offline machine falls back to a built-in snapshot.
13
20
  - **Totals card** — estimated cost, total (input + output + cache), input, output, cache read, cache write, reasoning, calls.
14
21
  - **Per-model pricing** — cache-hit input, cache-miss input and output are priced separately per model; anything that is not a DeepSeek model (claude, gpt, …) is never counted and shows `—`.
15
- - **Range tabs** — by day / by month / all, with a date or month picker; defaults to by day = today.
16
- - **Model filter** — the dropdown beside the range tabs narrows every breakdown to one model (including that model's project and per-day rows); defaults to all models.
17
- - **Trend chart** — drawn with a tree-shaken ECharts bundle that ships inside the plugin (no CDN). Cache read / input / output stack into an **area composition** whose top edge is the total (with a total reference line), each day's amount is drawn as **cost bars** against a ¥ axis, and calls live in the tooltip. The card switches between **7 / 30 / 90 days (7 by default)**. A day without usage is a real zero (stacking needs it), and the tooltip still names it; tick labels keep one unit across an axis and monotone smoothing never overshoots. Rendering is imperative, so moving the mouse never re-renders React.
18
- - **Unit switch** — 亿 / 万 / 千 in Chinese, B / M / K in English; remembered per browser.
19
- - **Detail tables** — by model, by day and by project, each with an amount column (hover a row for its rates) and a total column.
22
+ - **Range dropdown** — by day / by month / by year / date range / all; defaults to by day = today. The date range starts as today → today and keeps its two ends ordered, so a backwards window can never be requested; the year list offers only the years your own logs cover.
23
+ - **Model filter** — the dropdown beside the range selector on the overview narrows every breakdown to one model (including that model's project and per-day rows); defaults to all models.
24
+ - **Trend chart** — drawn with a tree-shaken ECharts bundle that ships inside the plugin (no CDN). Cache read / input / output stack into an **area composition** whose top edge is the total (with a total reference line), each day's amount is drawn as **cost bars** against a ¥ axis, and calls live in the tooltip. A **prominent dashed daily-average reference line** (the visible window's total ÷ its days, labelled with the value) shows at a glance whether today runs above or below your usual day. The card switches between **7 / 30 / 90 days (7 by default)**. A day without usage is a real zero (stacking needs it), and the tooltip still names it; tick labels keep one unit across an axis and monotone smoothing never overshoots. Rendering is imperative, so moving the mouse never re-renders React.
25
+ - **Unit switch** — 亿 / 万 / 千 in Chinese, B / M / K in English; remembered per browser. The tab bar and the unit switch stay pinned at the top, and the tab you were on is remembered.
26
+ - **Detail tables** — by model and by project (the day dimension lives in the heatmap), each with an amount column (hover a row for its rates) and a total column.
27
+
28
+ ### One-click restart
29
+
30
+ The button on the configuration tab restarts the dsh web process serving the page. It replays the current command line (`process.argv` plus the working directory), so custom ports and flags survive; it asks for confirmation first, and the page reconnects and reloads itself about 10-30 seconds later. The script lands in `$DSH_HOME/dsh-token-use/restart.sh` and its output in `restart.log`. When a launch cannot be replayed (no executable entry point), the button is disabled with a reason instead.
20
31
 
21
32
  ## The amounts are estimates
22
33
 
@@ -41,7 +52,39 @@ You are burning tokens, but you cannot say where: which project costs the most,
41
52
 
42
53
  The most expensive cost is the one you cannot see — make it visible.
43
54
 
44
- ![Token usage panel: range and model filters, the cost and totals cards, the 7/30/90-day trend chart (stacked composition + cost bars), and the by-model / by-day / by-project tables with amounts](assets/token-usage.jpg)
55
+ ![Token usage panel, overview: range and model filters, the cost and totals cards, the trend chart with its daily-average line, and the 12-month usage heatmap](assets/tab-overview.jpg)
56
+
57
+ ## Screenshots
58
+
59
+ Four tabs across the top of the panel; the shots below are the real panel on real data (Chinese number units).
60
+
61
+ ### Overview
62
+
63
+ Cost and totals cards, the usage trend (stacked composition + cost bars + **orange daily-average line**) and the heatmap (last 12 months, switchable between total tokens and cost).
64
+
65
+ ![Overview tab](assets/tab-overview.jpg)
66
+
67
+ ### By model
68
+
69
+ Every model's usage and amount, with the range query (day / month / year / date range / all).
70
+
71
+ ![By model tab](assets/tab-models.jpg)
72
+
73
+ ### By project
74
+
75
+ Every project's usage and amount, same range query.
76
+
77
+ ![By project tab](assets/tab-projects.jpg)
78
+
79
+ ### Configuration
80
+
81
+ Versions (compared inside your release channel), runtime facts, the health check and the one-click restart.
82
+
83
+ ![Configuration tab](assets/tab-config.jpg)
84
+
85
+ The **self-check** that the health button unfolds: endpoint, client bundles and the harness walk.
86
+
87
+ ![The self-check results](assets/tab-selfcheck.jpg)
45
88
 
46
89
  ## Install
47
90
 
@@ -61,19 +104,29 @@ dsh plugin --profile web add /path/to/dsh-token-use
61
104
  - The host side **never polls and sets no periodic timer** other than the daily price refresh: it folds usage in O(1) increments from the `session/event` bus (one dictionary addition and one multiplication per `assistant/message`).
62
105
  - History is rebuilt **once** at boot by streaming `$DSH_HOME/sessions/**/session.jsonl.zstd` (native zstd from `node:zlib`), yielding the event loop between files (`scheduler.yield()`) so session handling is never blocked. A per-session sequence watermark de-duplicates the rebuild against live events, whatever order they arrive in.
63
106
  - **Price refresh**: one HTTPS GET per day at 12:00 local time (15 s timeout, retried an hour later on failure), stored atomically in `$DSH_HOME/dsh-token-use/pricing.json` (up to 30 snapshots). A restart reads the cache synchronously and does not re-fetch; a failed fetch falls back to the built-in snapshot, so the panel always shows numbers.
64
- - One read-only JSON endpoint is exposed: `GET /dsh-token-use` (loopback only, in-memory snapshot, `no-store`).
107
+ - Four routes are exposed (loopback only, `no-store`): `GET /dsh-token-use` for the snapshot, `GET /dsh-token-use/config` for versions and runtime facts, `GET /dsh-token-use/health` for the harness self-check, and `POST /dsh-token-use/restart` for the confirmed restart.
108
+ - **How the self-check probes**: client bundles are fetched at the revisioned URL from this page's boot manifest (a plugin URL embeds a build revision, so only the manifest can address it); the harness walk reads the profile directory, resolves each real entry file through `exports["."]` / `exports["./client"]` / `main`, and walks up from every plugin directory to spot duplicate `@deepseek-ai/cordis` copies — all read-only, never loading or executing the plugins it inspects. The report carries structured fields plus paths and versions; the panel renders the wording in your language.
109
+ - **Version checks** read the registry's abbreviated packument (`versions` + `dist-tags`) and compare against the highest release **in the channel you run** (rc / alpha / stable) — `@deepseek-ai/dsh-web-app` keeps a stale `0.0.1-rc.1` on its `latest` tag, so a plain `latest` comparison would report a false upgrade. The answer is cached for 6 hours in `$DSH_HOME/dsh-token-use/versions.json`.
65
110
 
66
111
  ```sh
67
112
  # everything
68
113
  curl http://127.0.0.1:3080/dsh-token-use
69
- # a date / a month
114
+ # a date / a month / a year / a span
70
115
  curl 'http://127.0.0.1:3080/dsh-token-use?month=2026-09'
71
116
  curl 'http://127.0.0.1:3080/dsh-token-use?day=2026-09-10'
72
- # a model (combinable with day/month)
117
+ curl 'http://127.0.0.1:3080/dsh-token-use?year=2026'
118
+ curl 'http://127.0.0.1:3080/dsh-token-use?from=2026-09-01&to=2026-09-15'
119
+ # a model (combinable with day/month/year/from+to)
73
120
  curl 'http://127.0.0.1:3080/dsh-token-use?model=deepseek-v4-flash'
121
+ # versions and runtime facts (the configuration tab)
122
+ curl http://127.0.0.1:3080/dsh-token-use/config
123
+ # harness self-check (the configuration tab's health button)
124
+ curl http://127.0.0.1:3080/dsh-token-use/health
125
+ # restart the service (the configuration tab's button; degrades after 2 s and replays the same command)
126
+ curl -X POST http://127.0.0.1:3080/dsh-token-use/restart
74
127
  ```
75
128
 
76
- Every bucket carries a `cost` (the estimate); `pricing` holds the current price book, when it was fetched and when it refreshes next; `modelPricing` maps each observed model to its rates or to the reason it carries no amount.
129
+ Every bucket carries a `cost` (the estimate); `pricing` holds the current price book, when it was fetched and when it refreshes next; `modelPricing` maps each observed model to its rates or to the reason it carries no amount. `trend` spans the last 366 days — the chart takes the last 7/30/90 of it and the heatmap takes the whole run.
77
130
 
78
131
  ## Development
79
132
 
package/README.md CHANGED
@@ -8,15 +8,27 @@ DeepSeek Harness 实时 Token 用量与消费金额插件:安装后在 **设
8
8
 
9
9
  ## 功能
10
10
 
11
- - **金额卡片**:按 DeepSeek 官方定价 × 本地用量实时估算消费金额(含高峰/空闲时段倍率),每张卡片(总量、趋势、按模型、按日期、按项目)都带金额字段。
11
+ 面板顶部四个 tab:**概览 / 模型统计 / 项目统计 / 配置信息**。
12
+
13
+ - **概览**:金额与总量卡片、用量趋势图、**使用热力图**(近 12 个月,一格一天,可按「总计 / 金额」着色;悬停**即时**弹出当天「总计 / 金额 / 调用次数」,无原生 tooltip 的 1 秒延迟)。支持范围与模型筛选。
14
+ - **模型统计**:所有模型的用量与金额明细表,支持范围查询(按天 / 按月 / 按年 / 时间段 / 全部)。
15
+ - **项目统计**:所有项目的用量与金额明细表,同样支持范围查询。
16
+ - **配置信息**:版本信息(`dsh-service`、`dsh`、`dsh-base`、本插件各自的已安装版本 vs 该版本**通道**(rc/alpha/stable)的最新版)、运行环境(平台版本、Node 版本、进程 PID、监听端口、已运行时长、`DSH_HOME`),以及**健康检查**与**一键重启**(带二次确认)。
17
+ - **健康检查(自检)**:分三段报告——**接口**(响应耗时、接口版本、历史扫描、定价数据、数据桶、数据更新时间)、**客户端 bundle**(逐个插件探测浏览器实际能否加载,用的是当前页面启动清单里带版本号的真实 URL)、**Harness 自检**(profile 完整性:`node_modules` / 锁文件 / 启动图;插件包完整性:入口文件、`dsh.bundle.patch`、前端 bundle 是否齐全;依赖解析;cordis 是否单实例同版本;服务端 bundle 与正在运行的 CLI 版本是否一致)。装完插件起不来时,这里会直接指出是哪个包、缺什么文件、怎么修。
18
+ - **金额卡片**:按 DeepSeek 官方定价 × 本地用量实时估算消费金额(含高峰/空闲时段倍率),每张卡片(总量、趋势、按模型、按项目)都带金额字段。
12
19
  - **官方定价自动更新**:每天 **12:00** 抓取一次官方定价页并缓存到本地,重启不丢、断网可用内置快照兜底。
13
20
  - **总量卡片**:金额(估算)、总计(输入+输出+缓存)、输入、输出、缓存读、缓存写、推理、调用次数。
14
21
  - **按模型区分单价**:输入/输出/缓存命中分别按模型的官方单价计价;非 DeepSeek 模型(claude、gpt 等)一律不计金额,用 `—` 标出。
15
- - **范围筛选**:按天 / 按月 / 全部三个 tab,默认「按天=今天」;可选日期、月份。
16
- - **模型筛选**:时间筛选旁的下拉框按模型过滤(含该模型的项目/按天维度明细),默认全部模型。
17
- - **用量趋势图**:基于 ECharts(按需打包、随插件离线分发,不依赖 CDN)。缓存命中/输入/输出按**堆叠面积**画出构成,上沿即总计(另有一条总计参考线),每天金额用**金额柱**走右轴(¥),调用次数在悬停提示里。卡片右上角可切 **7 / 30 / 90 天(默认 7 天)**。无用量日为真实 0 值(堆叠才准),悬停会写明「当日无用量」;刻度单位整轴统一,单调平滑不过冲。图表用命令式渲染,鼠标移动不触发 React 重渲染。
18
- - **单位切换**:中文(亿 / 万 / 千)与英文(B / M / K)一键切换,记忆选择。
19
- - **明细表**:按模型、按日期、按项目三张表,含金额列(悬停显示该模型单价)与总计列。
22
+ - **范围筛选**:按天 / 按月 / 按年 / 时间段 / 全部,用下拉框选择;默认「按天=今天」。「时间段」自选起止日期(默认今天→今天),起止互相约束、不会出现倒序区间;「按年」的年份列表来自本地已有数据的年份。
23
+ - **模型筛选**:概览页时间筛选旁的下拉框按模型过滤(含该模型的项目/按天维度明细),默认全部模型。
24
+ - **用量趋势图**:基于 ECharts(按需打包、随插件离线分发,不依赖 CDN)。缓存命中/输入/输出按**堆叠面积**画出构成,上沿即总计(另有一条总计参考线),每天金额用**金额柱**走右轴(¥),调用次数在悬停提示里。图里另有一条**显著的日均参考线**(当前可视区间内「总计 / 天数」,虚线上直接标出数值),一眼看清今天高于还是低于平均。卡片右上角可切 **7 / 30 / 90 天(默认 7 天)**。无用量日为真实 0 值(堆叠才准),悬停会写明「当日无用量」;刻度单位整轴统一,单调平滑不过冲。图表用命令式渲染,鼠标移动不触发 React 重渲染。
25
+ - **单位切换**:中文(亿 / 万 / 千)与英文(B / M / K)一键切换,记忆选择;tab 与单位切换栏常驻顶部,每个 tab 记忆上次停留位置。
26
+ - **明细表**:按模型、按项目两张表(按日期维度由热力图承担),含金额列(悬停显示该模型单价)与总计列。
27
+
28
+ ### 一键重启
29
+
30
+ 「配置信息」里的重启按钮会重启正在提供页面的 dsh web 进程:它按当前进程的启动命令(`process.argv` + 工作目录)原样重新拉起,因此自定义端口、参数都能保持;点击后需在弹窗二次确认,页面断开约 10-30 秒后自动重连并刷新。脚本写在 `$DSH_HOME/dsh-token-use/restart.sh`,日志在 `$DSH_HOME/dsh-token-use/restart.log`。若启动方式无法原样重放(拿不到可执行的入口),按钮会禁用并说明原因。
31
+
20
32
 
21
33
  ## 金额是估算值
22
34
 
@@ -41,7 +53,39 @@ DeepSeek Harness 实时 Token 用量与消费金额插件:安装后在 **设
41
53
 
42
54
  看不见的成本最贵——把它变成看得见的。
43
55
 
44
- ![Token 用量面板:范围与模型筛选、金额与总量卡片、7/30/90 天可切的趋势图(堆叠构成 + 金额柱)、以及按模型/按日期/按项目三张带金额的明细表](assets/token-usage.jpg)
56
+ ![Token 用量面板·概览:范围与模型筛选、金额与总量卡片、带日均参考线的用量趋势图、近 12 个月的使用热力图](assets/tab-overview.jpg)
57
+
58
+ ## 界面
59
+
60
+ 面板顶部四个 tab,下面是各 tab 的实拍(真实数据、默认中文单位)。
61
+
62
+ ### 概览
63
+
64
+ 金额与总量卡片、用量趋势图(堆叠构成 + 金额柱 + **橙色日均参考线**)、使用热力图(近 12 个月,可切「总计 / 金额」)。
65
+
66
+ ![概览 tab](assets/tab-overview.jpg)
67
+
68
+ ### 模型统计
69
+
70
+ 所有模型的用量与金额,带范围查询(按天 / 按月 / 按年 / 时间段 / 全部)。
71
+
72
+ ![模型统计 tab](assets/tab-models.jpg)
73
+
74
+ ### 项目统计
75
+
76
+ 所有项目的用量与金额,同样支持范围查询。
77
+
78
+ ![项目统计 tab](assets/tab-projects.jpg)
79
+
80
+ ### 配置信息
81
+
82
+ 版本信息(按通道对比最新版)、运行环境、健康检查与一键重启。
83
+
84
+ ![配置信息 tab](assets/tab-config.jpg)
85
+
86
+ 点「健康检查」后展开的**自检结果**:接口、客户端 bundle、Harness 自检三段报告。
87
+
88
+ ![健康检查的自检结果](assets/tab-selfcheck.jpg)
45
89
 
46
90
  ## 安装
47
91
 
@@ -61,19 +105,29 @@ dsh plugin --profile web add /解压路径/dsh-token-use
61
105
  - 宿主侧 **不轮询、不写盘、不加定时器**(除了每天一次定价刷新):通过 `session/event` 事件总线做 O(1) 增量累加(每条 `assistant/message` 一次字典加法 + 一次金额乘法)。
62
106
  - 启动时做 **一次性**历史重建:流式解压 `$DSH_HOME/sessions/**/session.jsonl.zstd`(`node:zlib` 原生 zstd),每读一个文件主动让出事件循环(`scheduler.yield()`),不阻塞会话处理;重建与实时事件用「会话 seq 水位」去重,任意先后顺序都不会重复计数。
63
107
  - **定价刷新**:每天 12:00 一次 HTTPS GET(15 秒超时,失败 1 小时后重试),结果写入 `$DSH_HOME/dsh-token-use/pricing.json`(原子替换,最多保留 30 份快照);进程重启时同步读缓存,不重复联网;联网失败自动退回内置快照,面板照常显示。
64
- - 只暴露一个只读 JSON 接口 `GET /dsh-token-use`(仅回环可访问,内存快照,`no-store`)。
108
+ - 只暴露四个只读/受控接口(仅回环可访问,内存快照,`no-store`):`GET /dsh-token-use` 数据快照、`GET /dsh-token-use/config` 版本与运行环境、`GET /dsh-token-use/health` Harness 自检、`POST /dsh-token-use/restart` 重启服务(需前端二次确认)。
109
+ - **自检怎么探**:客户端 bundle 用当前页面启动清单里的 `rev` 拉真实 URL(插件 URL 带构建版本号,只有启动清单拼得对);Harness 自检读 profile 目录、按 `exports["."]` / `exports["./client"]` / `main` 找真实入口、从各插件目录向上解析 `@deepseek-ai/cordis` 判断是否重复——全程只读,不加载也不执行被检查的插件。报告里只有结构化字段与路径/版本,文案由前端按语言渲染。
110
+ - **版本检查**:`/config` 读 npm registry 的精简 packument(`versions` + `dist-tags`),按**当前版本所属通道**(rc / alpha / stable)取该通道最高版来对比——`@deepseek-ai/dsh-web-app` 的 `latest` 标签长期停在 `0.0.1-rc.1`,按通道比较才不会误报。结果缓存 6 小时,写在 `$DSH_HOME/dsh-token-use/versions.json`。
65
111
 
66
112
  ```sh
67
113
  # 全部
68
114
  curl http://127.0.0.1:3080/dsh-token-use
69
- # 指定日期 / 月份
115
+ # 指定日期 / 月份 / 年份 / 时间段
70
116
  curl 'http://127.0.0.1:3080/dsh-token-use?month=2026-09'
71
117
  curl 'http://127.0.0.1:3080/dsh-token-use?day=2026-09-10'
72
- # 指定模型(可与 day/month 组合)
118
+ curl 'http://127.0.0.1:3080/dsh-token-use?year=2026'
119
+ curl 'http://127.0.0.1:3080/dsh-token-use?from=2026-09-01&to=2026-09-15'
120
+ # 指定模型(可与 day/month/year/from+to 组合)
73
121
  curl 'http://127.0.0.1:3080/dsh-token-use?model=deepseek-v4-flash'
122
+ # 版本与运行环境(配置信息 tab)
123
+ curl http://127.0.0.1:3080/dsh-token-use/config
124
+ # Harness 自检(配置信息 tab 的「健康检查」)
125
+ curl http://127.0.0.1:3080/dsh-token-use/health
126
+ # 重启服务(配置信息 tab 的按钮;2 秒后断开并原样拉起)
127
+ curl -X POST http://127.0.0.1:3080/dsh-token-use/restart
74
128
  ```
75
129
 
76
- 响应里每个桶都带 `cost`(估算金额),`pricing` 是当前价目表、抓取时间与下次刷新时间,`modelPricing` 是各模型匹配到的单价或未计价原因。
130
+ 响应里每个桶都带 `cost`(估算金额),`pricing` 是当前价目表、抓取时间与下次刷新时间,`modelPricing` 是各模型匹配到的单价或未计价原因;`trend` 覆盖最近 366 天(趋势图取尾部 7/30/90 天,热力图用整段)。
77
131
 
78
132
  ## 开发
79
133
 
Binary file
Binary file
Binary file
Binary file
Binary file