@rayadesu/dsh-billing 0.3.10 → 0.3.11

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/AGENTS.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # AGENTS.md
2
2
 
3
3
  DeepSeek-Harness-chat-billing 是 DeepSeek Harness 的计费插件仓库:在 Web 会话头部显示
4
- DeepSeek 账户余额、本轮对话花费与今日共花费。本仓库是插件的**唯一分发来源**——
4
+ DeepSeek 账户余额、本轮对话花费与今日花费。本仓库是插件的**唯一分发来源**——
5
5
  deepseek-harness 官方仓库([deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness))
6
6
  不含计费插件;插件曾短暂集成于本用户的 fork,现已回退到官方提交版本(`141eb6fef8`),
7
7
  本仓库不再依赖任何 fork。
@@ -47,7 +47,10 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
47
47
  - **密钥不进仓库**:`DEEPSEEK_API_KEY` 等一律由用户环境或凭据 seam 提供,仓库不含真实值。
48
48
  - **README 双语**:每个 README 遵循 DSH 结构 `README.md`(EN) + `README.zh.md`(ZH) +
49
49
  `README.i18n.yaml`(记录两文件 git blob hash,改动后需更新)。
50
- - **版本对齐**:根 bundle 与两个包统一版本号(当前 0.3.10),`pnpm-lock.yaml` 随依赖变更更新。
50
+ - **版本对齐**:根 bundle 与两个包统一版本号(当前 0.3.11),`pnpm-lock.yaml` 随依赖变更更新。
51
+ - **提交与发布流程**:见 `.agents/skills/dsh-release/SKILL.md` —— 阶段 A(改代码 → test/build →
52
+ 本地 pack 安装 → 交用户验证)**不提交**,改动留在工作区;用户说「发布」进入阶段 B 才 bump 版本、
53
+ **按类型分别提交**、推送、发 npm 与 GitHub Release。
51
54
  - **文本规范**:LF 换行、文件末尾一个换行(`.editorconfig`/`.gitattributes` 已声明)。
52
55
 
53
56
  ## 常用命令
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record both hashes with:
4
4
  # git hash-object README.md README.zh.md
5
- README.md: c83e7559af62aba5c8ceb4dfffc18de50138f333
6
- README.zh.md: 01127599e394e374adcb77a4109ad4b70c123801
5
+ README.md: b81cf813b4cb4a430c6939a9304d63a395c3b1bd
6
+ README.zh.md: 181497f82a029ebcd6f8fada89c4aea3407fa130
package/README.md CHANGED
@@ -9,13 +9,13 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
9
9
  ## What it shows
10
10
 
11
11
  - **Session-header badge** — two lines: remaining balance (`剩余额度:¥X`) and this conversation's billed spend (`本轮对话花费:¥X`).
12
- - **Detail panel** — the remaining amount, this session's spend (`本会话花费`) with today's all-session spend beside it (`今日共花费`), one priced row per model (`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`), plus a manual refresh action and a spend disclaimer. The panel ends with a **today session-spend ranking**: sessions sorted by today's spend, highest first (names come from the log's Chinese titles and follow renames automatically; at most the top 10 rows, with a "…N more sessions" hint).
12
+ - **Detail panel** — the remaining amount, this session's spend (`本会话花费`, with this session's own share of today as a bare parenthesized amount `(¥X)` right after it) with today's all-session spend beside it (`今日`), one priced row per model (`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`), plus a manual refresh action and a spend disclaimer on the `?` button (whose next line carries the running plugin version, e.g. `v0.3.11`). The panel ends with a **today session-spend ranking**: sessions sorted by today's spend, highest first (names come from the log's Chinese titles and follow renames automatically; at most the top 10 rows, with a "…N more sessions" hint).
13
13
  - **Turn cost amount** — each completed turn's closing message shows a plain static `¥X` at the **end** of the actions row, after the clock: non-interactive (no icon, no "cost" word, no card), its typography replicates the clock text (13px secondary tier, tertiary tone, nowrap), and it is **always visible** (not hover-revealed like the clock text — the row's own hover reveal shows both together); turns without DeepSeek usage (zero cost) or failed loads stay hidden.
14
14
  - **Failures and empty states** — a session or day without priced usage shows "no usage recorded" instead of a fabricated figure; a missing key, rejected credential, or transport error renders a muted "Balance unavailable" whose tooltip carries the Remote's own error message.
15
15
 
16
16
  ## Data update mechanics
17
17
 
18
- - **Session spend follows the conversation** — the host prices every committed event into a per-session projection (`billingTodaySpend`) and pushes it to the browser, so **this session's spend** updates live with no Remote call; the Remote read remains the fallback when the projection registry is absent. **Today's spend** is recomputed on turn settle (one shared scan serves both the aggregate and the ranking), and each turn's cost comes from **one batch fetch per session** instead of one call per rendered message.
18
+ - **Session spend follows the conversation** — the host prices every committed event into a per-session projection (`billingTodaySpend`) and pushes it to the browser, so **this session's spend** updates live with no Remote call; the Remote read remains the fallback when the projection registry is absent. **Today's spend** is recomputed on turn settle (one shared scan serves both the aggregate and the ranking), and the parenthesized today share on that same session row reads that same ranking fetch (no extra request, at the cost of moving with it); each turn's cost comes from **one batch fetch per session** instead of one call per rendered message.
19
19
  - **Balance is cached, not polled** — the host reuses one `/user/balance` snapshot for 15 seconds (manual refresh forces a fresh one) and caps each request at 5 seconds; the browser keeps the last settled value so a session switch renders the amount immediately and revalidates in the background. There is still no polling.
20
20
  - **Old values survive refreshes** — a failed refresh keeps the last good value instead of blanking it.
21
21
 
@@ -25,7 +25,7 @@ A real session: the session-header badge, the detail panel (remaining amount, th
25
25
 
26
26
  <img width="1200" alt="Billing plugin overview: session header badge, detail panel with per-model rows and today's session ranking, and the turn-cost row" src="preview-overview.png" />
27
27
 
28
- Close-up of the detail panel — the `API 剩余金额` figure, `本会话花费` next to `今日共花费`, the per-model breakdown (`缓存命中 · 未命中输入 · 输出`), and the today session-spend ranking:
28
+ Close-up of the detail panel — the `API 剩余金额` figure, `本会话花费` (with its parenthesized today share) next to `今日`, the per-model breakdown (`缓存命中 · 未命中输入 · 输出`), and the today session-spend ranking:
29
29
 
30
30
  <img width="640" alt="Detail panel close-up: API remaining amount, this session's spend next to today's all-session spend, per-model rows and today's session ranking" src="preview-detail.png" />
31
31
 
@@ -252,7 +252,7 @@ Both packages ship sane defaults; everything below is optional.
252
252
  ## Known limitations
253
253
 
254
254
  - **Priced rows only** — the session, turn, and today spends only price models that have a `billing.models` row.
255
- - **On-demand aggregation** — today's spend and the session ranking are computed on the host behind a 60-second cache and share ONE scan; a miss resolves live sessions from their eager projection cells and cold sessions from the zero-I/O projection-cache row when that row's own day is not the queried one, reading a log only for sessions whose persisted revision changed (or whose cached row covers the queried day). A failed resolution is remembered by revision instead of being retried every scan.
255
+ - **On-demand aggregation** — today's spend and the session ranking are computed on the host behind a 60-second cache and share ONE scan; a miss resolves live sessions from their eager projection cells and cold sessions from the zero-I/O projection-cache row when that row's own day is not the queried one, reading a log only for sessions whose persisted revision changed (or whose cached row covers the queried day). A failed resolution is remembered by revision instead of being retried every scan. The ranking is also fetched only on demand — see the next bullet — and the parenthesized today share on the 本会话花费 row rides that same fetch, so it costs no extra request ((—) until the first one settles, and up to 60 seconds behind afterwards).
256
256
  - **Ranking is fetched on demand** — the panel loads the ranking when it is opened (and on refresh), so a badge that stays closed never pays for the all-session scan.
257
257
  - **Ranking capped at 10** — the panel shows at most the top 10 sessions, with a "…N more sessions" hint.
258
258
  - **Turn cost needs a finalized closing message** — interrupted turns have no actions row, so no turn cost; cold sessions served straight from the projection cache may rank with an "Untitled" name until their log is read again.
package/README.zh.md CHANGED
@@ -4,30 +4,30 @@
4
4
 
5
5
  一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,在 Web 会话头部直接显示你的 **DeepSeek 账户余额**、**当前会话(本轮对话)的花费**,以及**今日所有会话的共花费**;每条已完成的回合还会在消息操作行**行尾**以静态金额显示**本轮花费**,详情面板底部带**今日各会话花费排行**。
6
6
 
7
- > 余额是 `GET /user/balance` 的真实数字;会话花费、本轮花费与今日共花费是按官方峰/谷单价对每条消息的计费 token 逐条计价的结果,不是计费承诺。
7
+ > 余额是 `GET /user/balance` 的真实数字;会话花费、本轮花费与今日花费是按官方峰/谷单价对每条消息的计费 token 逐条计价的结果,不是计费承诺。
8
8
 
9
9
  ## 显示什么
10
10
 
11
11
  - **会话头部徽标** —— 两行:剩余余额(`剩余额度:¥X`)+ 本轮对话的计费花费(`本轮对话花费:¥X`)。
12
- - **详情面板** —— 剩余金额、本会话花费(`本会话花费`)与其右侧的今日所有会话共花费(`今日共花费`),以及每个模型一行的花费分项(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),外加手动刷新按钮与花费说明;面板底部是**今日会话花费排行**:按今日花费从高到低排列的会话列表(会话名取日志中的中文标题,重命名后自动同步;最多显示前 10 条,其余以「…还有 N 个会话」提示)。
12
+ - **详情面板** —— 剩余金额、本会话花费(`本会话花费`,金额后紧跟括号括起来的**本会话今日份**金额 `(¥X)`)与其右侧的今日所有会话共花费(`今日`),以及每个模型一行的花费分项(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),外加手动刷新按钮与「?」上的花费说明(下一行顶格是当前插件版本号,如 `v0.3.11`);面板底部是**今日会话花费排行**:按今日花费从高到低排列的会话列表(会话名取日志中的中文标题,重命名后自动同步;最多显示前 10 条,其余以「…还有 N 个会话」提示)。
13
13
  - **本轮花费金额** —— 每条已完成回合的收尾消息操作行**行尾**(时钟之后)显示纯静态的 `¥X`:不可点击、无图标、无「花费」字样、不弹卡片,字体样式逐项复刻时钟文本(13px 次级字号、tertiary 色、nowrap),并且**始终显示**(不随悬停隐藏,与时钟文本一致——整行的悬停显隐规则让两者同进退);回合没有 DeepSeek 用量(花费为 0)或加载失败时不显示。
14
14
  - **失败与空态** —— 会话或今日没有可计价消耗时显示「暂无消耗记录」而不是编造数字;未配置 key、凭据被拒或传输错误时显示弱化的「额度不可用」,其提示携带 Remote 自己的错误信息。
15
15
 
16
16
  ## 数据更新机制
17
17
 
18
- - **会话花费自动跟随** —— 主机端把每条已提交事件计价进每会话投影(`billingTodaySpend`)并推送给浏览器,**本会话花费**因此零 Remote 调用、实时更新;投影注册表不存在时回退到 Remote 读取。**今日共花费**在回合结束时重算(聚合与排行共用同一次扫描),每条消息的行尾金额来自**每会话一次批量拉取**,不再逐条消息各发一次请求。
18
+ - **会话花费自动跟随** —— 主机端把每条已提交事件计价进每会话投影(`billingTodaySpend`)并推送给浏览器,**本会话花费**因此零 Remote 调用、实时更新;投影注册表不存在时回退到 Remote 读取。**今日**在回合结束时重算(聚合与排行共用同一次扫描),本会话花费括号里的今日份金额也来自这次排行读取(不额外发请求,代价是与排行同进同退);每条消息的行尾金额来自**每会话一次批量拉取**,不再逐条消息各发一次请求。
19
19
  - **额度有缓存、但不轮询** —— 主机端 15 秒内复用同一份 `/user/balance` 快照(手动刷新强制取新),单次请求 5 秒超时;浏览器保留最后一次结果,切会话时立即渲染旧值并在后台校验。仍然**没有轮询**。
20
20
  - **刷新期间旧值保留** —— 刷新失败保留上一次有效值,不会清空。
21
21
 
22
22
  ## 显示样式
23
23
 
24
- 真实会话中的会话头部徽标与详情面板(剩余金额、本会话花费与今日共花费、按模型分项、今日会话花费排行),以及消息操作行行尾的本轮花费金额:
24
+ 真实会话中的会话头部徽标与详情面板(剩余金额、本会话花费与今日、按模型分项、今日会话花费排行),以及消息操作行行尾的本轮花费金额:
25
25
 
26
26
  <img width="1200" alt="计费插件总览:会话头部徽标、详情面板(按模型分项与今日会话花费排行)、消息操作行里的本轮花费行" src="preview-overview.png" />
27
27
 
28
- 详情面板特写 —— `API 剩余金额`、`本会话花费` 与 `今日共花费`、按模型分项(`缓存命中 · 未命中输入 · 输出`)与今日会话花费排行:
28
+ 详情面板特写 —— `API 剩余金额`、`本会话花费`(含括号内的今日份金额)与 `今日`、按模型分项(`缓存命中 · 未命中输入 · 输出`)与今日会话花费排行:
29
29
 
30
- <img width="640" alt="详情面板特写:API 剩余金额、本会话花费与今日共花费、按模型分项与今日会话花费排行" src="preview-detail.png" />
30
+ <img width="640" alt="详情面板特写:API 剩余金额、本会话花费(含括号内的今日份金额)与今日、按模型分项与今日会话花费排行" src="preview-detail.png" />
31
31
 
32
32
  本轮花费金额特写 —— 操作行行尾(时钟之后)的静态 `¥` 金额:
33
33
 
@@ -220,16 +220,16 @@ npm publish # @rayadesu/dsh-billing bundle(仓库根)
220
220
 
221
221
  - 每条 `assistant/message` 事件报告三个计费 token 桶:**缓存命中输入**、**未命中输入**(未缓存输入 + 缓存写入)、**输出**(含推理)。失败或重试的 `assistant/attempt` 只在自身内嵌 stream 里报告用量,这份样本同样计价(模型取最近一条 `request/header`);同一 `(turn, step)` 的后一份样本**替换**前一份,`llm/retry-started` 之后重试的那次**累加** —— 与 DSH 自己的回合用量口径一致。
222
222
  - 每份样本按其**发生时刻**(北京时间)所在的峰/谷时段单价——以及该时刻生效的费率版本——计价,三个桶分别计费(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),再按模型汇总。高峰窗口仅周一至周五适用;周末全天按低谷价计费。
223
- - **今日共花费**按同一个计价规则汇总当天(北京时间自然日)所有会话的事件;事件归属的日期同样按北京时间计算。
223
+ - **今日**按同一个计价规则汇总当天(北京时间自然日)所有会话的事件;事件归属的日期同样按北京时间计算。
224
224
  - **本轮花费**按同一规则计价该回合 `turn/start`..`turn/end` 区间内的事件(定位到收尾消息的会话 id + 消息 id),整会话一趟折出 `messageId → 金额` 映射后下发。
225
225
  - **今日会话花费排行**按同一规则按会话汇总今日花费(跨天会话只统计今天的部分),从高到低排序;会话名取日志中最后一条 `session/title` 事件(自动生成的中文标题或用户重命名的新标题)。
226
226
  - 没有费率行的模型不计入(内置价目表覆盖 DSH `llm-deepseek` 目录——V4.1 Flash `deepseek-flash`、V4 Flash、V4 Pro、V4 Flash Vision Exp——外加已退役的 `deepseek-v4.1-flash-expires-on-0910` 预览 id 与 MiMo-V2.5 系列;flash 系列各路由同价)。每份样本取**自身时刻生效的费率版本**:基础价目为 DeepSeek **8 月 17 日实行**的费率;**flash 系列**(V4.1 Flash、V4 Flash、V4 Flash Vision Exp 及退役 id)自 **9 月 10 日 12:00(北京时间)** 起降为谷时 0.02 / 1.0 / 4.0 元每百万 token、峰时为其两倍——该时刻之前的样本(含 V4.1 Flash 路由自身的早先用量的)沿用被取代的旧价;**V4 Pro** 路由公告于 **9 月 14 日 12:00(北京时间)** 改由 V4.1 Flash 服务并按其实施费率计费;MiMo-V2.5 系列不受影响。**周末按低谷价计费**的规则按 **8 月 23 日**生效的调整执行。
227
227
 
228
228
  ## 已知限制
229
229
 
230
- - **有费率行才计价** —— 会话花费、本轮花费与今日共花费只统计价目表(`billing.models`)里有的模型。
231
- - **按需聚合** —— 今日共花费与今日会话排行在主机端 60 秒缓存之后计算,且共用同一次扫描;未命中时,活跃会话直接读投影单元,冷会话若缓存行自身的日期不是查询日则零 I/O 直接作答,只有持久化修订变化(或缓存行覆盖查询日)的会话才读日志。读取失败的会话按修订号记住,不再每轮重试。
232
- - **排行按需拉取** —— 详情面板打开(或手动刷新)时才拉取排行,徽标一直关着就不会为全量会话扫描买单。
230
+ - **有费率行才计价** —— 会话花费、本轮花费与今日花费只统计价目表(`billing.models`)里有的模型。
231
+ - **按需聚合** —— **今日**与今日会话排行在主机端 60 秒缓存之后计算,且共用同一次扫描;未命中时,活跃会话直接读投影单元,冷会话若缓存行自身的日期不是查询日则零 I/O 直接作答,只有持久化修订变化(或缓存行覆盖查询日)的会话才读日志。读取失败的会话按修订号记住,不再每轮重试。
232
+ - **排行按需拉取** —— 详情面板打开(或手动刷新)时才拉取排行,徽标一直关着就不会为全量会话扫描买单;「本会话花费」括号里的今日份金额也来自这次读取,所以它不额外发请求(代价是面板刚打开、排行未落定时先显示 `(—)`,且最多滞后 60 秒)。
233
233
  - **排行只显示前 10** —— 详情面板最多展示前 10 个会话,其余以「…还有 N 个会话」提示。
234
234
  - **本轮花费只出现在已定稿的收尾消息** —— 中断的回合没有操作行,不显示本轮花费;冷会话(投影缓存直接命中)排行标题可能显示「未命名」,待其日志被重新读取后恢复。
235
235
  - **额度带 TTL 缓存** —— 主机端最多复用 15 秒内的同一份快照,单次请求 5 秒超时;账户在其他客户端产生消耗时,界面值要等 TTL 过期、手动刷新或刷新浏览器才变(仍无轮询)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayadesu/dsh-billing",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "description": "DeepSeek Harness billing plugin: account balance and this session's billed spend with a session-header badge.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,8 +40,8 @@
40
40
  "access": "public"
41
41
  },
42
42
  "peerDependencies": {
43
- "@rayadesu/dsh-client-ui-billing": "^0.3.10",
44
- "@rayadesu/dsh-llm-billing": "^0.3.10"
43
+ "@rayadesu/dsh-client-ui-billing": "^0.3.11",
44
+ "@rayadesu/dsh-llm-billing": "^0.3.11"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@deepseek-ai/cordis": "^4.0.1",