dsh-cost-meter 1.6.4 → 1.6.6

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
@@ -231,22 +231,22 @@ Real captures from an actual DSH sidebar of the period strip and collapsed verti
231
231
  dsh plugin --profile web add dsh-cost-meter
232
232
  ```
233
233
 
234
- **PowerShell one-click script** (copy the whole line, paste, press Enter; pnpm is provisioned automatically, git is auto-detected — no clone needed; the install chain is **pinned to the release tag `v1.6.4`** — review the script before running):
234
+ **PowerShell one-click script** (copy the whole line, paste, press Enter; pnpm is provisioned automatically, git is auto-detected — no clone needed; the install chain is **pinned to the release tag `v1.6.6`** — review the script before running):
235
235
 
236
236
  ```powershell
237
- irm https://raw.githubusercontent.com/Han-1413141/dsh-cost-meter/v1.6.4/install.ps1 | iex
237
+ irm https://raw.githubusercontent.com/Han-1413141/dsh-cost-meter/v1.6.6/install.ps1 | iex
238
238
  ```
239
239
 
240
240
  **Or a plain command line** (the machine must already have pnpm and git; also pinned to the tag):
241
241
 
242
242
  ```sh
243
- dsh plugin --profile web add github:Han-1413141/dsh-cost-meter#v1.6.4
243
+ dsh plugin --profile web add github:Han-1413141/dsh-cost-meter#v1.6.6
244
244
  ```
245
245
 
246
246
  Without git, use the GitHub tag archive:
247
247
 
248
248
  ```sh
249
- dsh plugin --profile web add https://github.com/Han-1413141/dsh-cost-meter/archive/refs/tags/v1.6.4.tar.gz
249
+ dsh plugin --profile web add https://github.com/Han-1413141/dsh-cost-meter/archive/refs/tags/v1.6.6.tar.gz
250
250
  ```
251
251
 
252
252
  After installing, **restart** `dsh web` (plugin rows, the Typert manifest and the client bundle are all scanned at startup):
@@ -263,7 +263,7 @@ Cause: your environment (pnpm config or a policy bundled into the invoking insta
263
263
 
264
264
  Fix:
265
265
 
266
- 1. **Upgrade to v1.6.4+**: all three runtime dependencies (`@deepseek-ai/dsh-credentials`, `@deepseek-ai/dsh-home-paths`, `zod`) are now exact-pinned — a pinned version's publish date never changes, so it satisfies any age threshold and this plugin can no longer trigger the error;
266
+ 1. **Upgrade to v1.6.6+**: all three runtime dependencies (`@deepseek-ai/dsh-credentials`, `@deepseek-ai/dsh-home-paths`, `zod`) are now exact-pinned — a pinned version's publish date never changes, so it satisfies any age threshold and this plugin can no longer trigger the error;
267
267
  2. If the error is triggered by **another plugin's** dependencies instead, append an exclusion for the offending `name@version` printed in the error to the profile's `pnpm-workspace.yaml` (default `$DSH_HOME/profiles/web/pnpm-workspace.yaml`) and retry:
268
268
 
269
269
  ```yaml
@@ -298,6 +298,8 @@ dsh plugin --profile web add link:./dsh-cost-meter # symlink; edit lib/client.j
298
298
  - The ledger always stores amounts in **USD**; currency and FX rate only affect display (default 1 USD = 7.2 CNY, configurable);
299
299
  - The session badge is **billed exactly** at the moment each call is made (host-exported per-call cost), just like daily/monthly/cumulative totals and the budget;
300
300
  - Billing sources are the `usage` block of every model call (including sub-agents, compression, title generation and other auxiliary calls), matching the billable view;
301
+ - **Peak/off-peak tiers follow the request-initiation moment** (v1.6.6): a streaming call can span the tier boundary hour; attributing by completion time would put a request started minutes earlier into the wrong tier;
302
+ - **Aligning with official bills**: ① minute-level lag vs live official numbers is expected — the ledger flushes on a 2s debounce, and streams still in flight at shutdown are billed server-side while their usage block is never received (the gap concentrates in cache-hit columns); ② reasoning tokens are reported separately by the API and are **not billed** — the token columns sum five buckets and will never line up with the official three columns, so **reconcile by amount**; ③ with pricing currency set to CNY, entries are recorded directly on the official CNY price list (recommended for CNY-billed accounts); with USD, displayed amounts go through a fixed FX rate and carry a small structural difference (the two lists' per-column ratios are not uniform);
301
303
  - Budget and over-budget warnings **only warn — they never block calls**.
302
304
  - **Plan/API dual-track billing** (issue #64): calls on subscription-style channels (MiniMax, manually-marked Codex, etc.) are recorded as catalog-price equivalents only; budget/today-cost/overview cards count the pay-as-you-go (API) channel exclusively.
303
305
  - **Full-repo security audit fixes**: resolved 3 high-risk findings — ledger writes lost on exit (close/flush ordering), command injection in the release script, panel null-pointer crash on null Go monthly window — plus 30+ medium/low issues including missing hour-bucket entries for routed calls, dead balance-reconciliation warnings, failed custom-balance extraction silently showing $0, and leaked upstream streams on consumer abort; ledger corruption auto-backup, write-failure retry, config-patch atomicity and prototype-chain hardening included. Itemized list: [CHANGELOG.md](CHANGELOG.md).
package/README.md CHANGED
@@ -233,22 +233,22 @@
233
233
  dsh plugin --profile web add dsh-cost-meter
234
234
  ```
235
235
 
236
- **PowerShell 一键脚本**(复制整行粘贴回车;自动补齐 pnpm、自动探测 git,无需克隆仓库;安装链**固定到发布 tag `v1.6.4`**,建议先下载审阅再运行):
236
+ **PowerShell 一键脚本**(复制整行粘贴回车;自动补齐 pnpm、自动探测 git,无需克隆仓库;安装链**固定到发布 tag `v1.6.6`**,建议先下载审阅再运行):
237
237
 
238
238
  ```powershell
239
- irm https://raw.githubusercontent.com/Han-1413141/dsh-cost-meter/v1.6.4/install.ps1 | iex
239
+ irm https://raw.githubusercontent.com/Han-1413141/dsh-cost-meter/v1.6.6/install.ps1 | iex
240
240
  ```
241
241
 
242
242
  **或直接命令行**(机器上需已有 pnpm 与 git;同样固定到 tag):
243
243
 
244
244
  ```sh
245
- dsh plugin --profile web add github:Han-1413141/dsh-cost-meter#v1.6.4
245
+ dsh plugin --profile web add github:Han-1413141/dsh-cost-meter#v1.6.6
246
246
  ```
247
247
 
248
248
  没有 git 时可用 GitHub tag 打包直链:
249
249
 
250
250
  ```sh
251
- dsh plugin --profile web add https://github.com/Han-1413141/dsh-cost-meter/archive/refs/tags/v1.6.4.tar.gz
251
+ dsh plugin --profile web add https://github.com/Han-1413141/dsh-cost-meter/archive/refs/tags/v1.6.6.tar.gz
252
252
  ```
253
253
 
254
254
  安装后**重启** `dsh web`(插件行、Typert 清单与客户端 bundle 均在启动时扫描):
@@ -265,7 +265,7 @@ dsh web
265
265
 
266
266
  处理:
267
267
 
268
- 1. **升级到 v1.6.4+**:三个运行时依赖(`@deepseek-ai/dsh-credentials`、`@deepseek-ai/dsh-home-paths`、`zod`)已全部精确锁版——锁定版本的发布时间固定不变,对任意年龄阈值永远满足,本插件不再可能触发该错误;
268
+ 1. **升级到 v1.6.6+**:三个运行时依赖(`@deepseek-ai/dsh-credentials`、`@deepseek-ai/dsh-home-paths`、`zod`)已全部精确锁版——锁定版本的发布时间固定不变,对任意年龄阈值永远满足,本插件不再可能触发该错误;
269
269
  2. 若报错由**其他插件**的依赖触发,可在 profile 目录的 `pnpm-workspace.yaml`(默认 `$DSH_HOME/profiles/web/pnpm-workspace.yaml`)按报错列出的条目追加排除后重试:
270
270
 
271
271
  ```yaml
@@ -300,6 +300,8 @@ dsh plugin --profile web add link:./dsh-cost-meter # 符号链接,改 lib/clien
300
300
  - 账本金额恒以**美元**存储,币种/汇率仅影响显示(默认 1 USD = 7.2 CNY,可改);
301
301
  - 会话徽章与当日/月度/累计、预算一样,按每次调用的**实际时刻精确计费**(宿主导出的逐次成本);
302
302
  - 计费来源为每次模型调用的 usage 块(含子代理、压缩、标题等辅助调用),与账单口径一致;
303
+ - **峰谷档位按请求发起时刻判定**(v1.6.6):流式调用可能跨峰谷边界整点,以完成时刻归档会把数分钟前发起的请求算进另一个峰位;
304
+ - **官方账单对齐口径**:① 与官方实时数字存在**分钟级时差**属预期——账本 2 秒防抖落盘,关停瞬间仍在途的流会被服务端照常扣费而 usage 块无人接收(缺口集中在缓存命中列);② reasoning tokens 由 API 单独上报且**不计费**,token 列为五桶合计,与官方「三列」天然对不齐,**对账请以金额为准**;③ 「价格币种」设为人民币时按官方 CNY 价目直计入账,与人民币账单币种一致(CNY 计价账号推荐);设为 USD 时显示金额经固定汇率折算,与 CNY 直计存在结构性细差(两套价目比值非均匀);
303
305
  - 预算与超支提示**仅提醒,不阻止调用**。
304
306
  - **Plan/API 双轨计费**(issue #64):订阅制渠道(MiniMax / Codex 手动标记等)的调用金额只记「等值」,预算/今日费用/概览卡片等金额展示仅统计按量计费(API)部分;
305
307
  - **「含 Plan 总额」开关**:概览页汇总卡片下的快捷开关切换全部金额展示口径——关闭时仅计真金白银(API 渠道),开启后显示含 Plan 等值的总金额;网关路由(provider 缺失)调用的第三方目录模型自动归入对应订阅归类,无模型明细的历史残差计入 API 口径;设置 → 用量 的 Token Plan 统计面板提供每 1% 额度与满窗的 token/等值金额估算与日/周/月曲线;分类可在配置中按厂商或 provider:model 级覆盖。
@@ -33,15 +33,20 @@ const llmStreamDepth = new AsyncLocalStorage()
33
33
  * @param {object} deps
34
34
  * @param {(usage: object, model: string, sessionId: string, atMs: number, provider: string) => void} deps.account
35
35
  * 计费回调:流结束时以捕获的 usage 块调用(五参签名与 ledger.account 对齐,
36
- * 由 index.js 负责把 usage 五桶映射过去)。
36
+ * 由 index.js 负责把 usage 五桶映射过去;atMs 为请求发起时刻,见下)。
37
+ * @param {() => number} [deps.now] - 时钟源(默认 Date.now),测试注入用。
37
38
  * @returns {(options: object, next: () => AsyncIterable) => AsyncIterable} 宿主监听器。
38
39
  */
39
- export function createLlmStreamBilling({ account }) {
40
+ export function createLlmStreamBilling({ account, now = Date.now }) {
40
41
  return (options, next) => {
41
42
  const downstream = next()
42
43
  // 嵌套内层(包装路由在上层计费流的消费上下文中再发起的 llm/stream):
43
44
  // 外层已记账,透传下游流,不再包裹。
44
45
  if (llmStreamDepth.getStore() !== undefined) return downstream
46
+ // 峰谷档位按「请求发起」时刻判定:一次流式调用可能跨峰谷边界整点,
47
+ // 按完成时刻归档会把数分钟前发起的请求算进另一个峰位(官方口径为
48
+ // 请求侧计时;实测跨点分歧可达分毛级)。瀑布分发即请求发起时刻。
49
+ const startedAtMs = now()
45
50
  return (async function* costMeterStream() {
46
51
  let usage = null
47
52
  const iterator = downstream[Symbol.asyncIterator]()
@@ -70,7 +75,7 @@ export function createLlmStreamBilling({ account }) {
70
75
  }
71
76
  if (usage !== null) {
72
77
  try {
73
- account(usage, options?.model, options?.sessionId, Date.now(), options?.provider)
78
+ account(usage, options?.model, options?.sessionId, startedAtMs, options?.provider)
74
79
  } catch (error) {
75
80
  console.warn(`[dsh-cost-meter] 计费失败: ${String(error)}`)
76
81
  }