dsh-cost-meter 1.6.4 → 1.6.5

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.5`** — 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.5/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.5
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.5.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.5+**: 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
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.5`**,建议先下载审阅再运行):
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.5/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.5
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.5.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.5+**:三个运行时依赖(`@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
package/lib/index.js CHANGED
@@ -973,13 +973,22 @@ function createService(ctx, ledger) {
973
973
  if ((ledger.config?.balance?.reconcile ?? true) === true && balanceCache.value.status === 'ok') {
974
974
  const nowMs = Date.now()
975
975
  const usd = v => '$' + Number(v).toFixed(4)
976
- const { ref, event } = reconcileBalanceDelta(ledger.balanceRef, balanceCache.value, ledger.todayOfficialCost(), localDayKey(nowMs), nowMs)
976
+ // 变动金额按余额条目的真实币种显示符号(CNY 余额账号此前被错标成 $),
977
+ // 并附 ≈USD 折算参考与本地账本同币种可比(zh/en 两份模板共用参数,不做字典改动)。
978
+ const nativeDelta = event => {
979
+ const symbol = String(event.spentCurrency ?? '').toUpperCase() === 'CNY' ? '¥' : '$'
980
+ const converted = Number.isFinite(event.spentUsd) && Math.abs(event.spentUsd - event.spent) > 0.005
981
+ ? '(≈' + usd(event.spentUsd) + ')'
982
+ : ''
983
+ return symbol + Number(event.spent).toFixed(4) + converted
984
+ }
985
+ const { ref, event } = reconcileBalanceDelta(ledger.balanceRef, balanceCache.value, ledger.todayOfficialCost(), localDayKey(nowMs), nowMs, { exchangeRate: ledger.config.exchangeRate })
977
986
  if (ref !== ledger.balanceRef) {
978
987
  ledger.balanceRef = ref
979
988
  ledger.scheduleWrite()
980
989
  }
981
990
  reconcileNotice = event !== null && event.kind === 'drift'
982
- ? { ok: false, message: tmsg(localeOf(ledger.config), 'reconcileWarn', { cost: usd(event.todayCost), delta: usd(event.spent) }) }
991
+ ? { ok: false, message: tmsg(localeOf(ledger.config), 'reconcileWarn', { cost: usd(event.todayCost), delta: nativeDelta(event) }) }
983
992
  : { ok: true, message: '' }
984
993
  }
985
994
  }, error => {
package/lib/store.js CHANGED
@@ -182,8 +182,10 @@ export function zeroDay(date) {
182
182
 
183
183
  /**
184
184
  * 聚合某日账本中归属 DeepSeek 官方渠道的费用(USD;issue #36)。
185
- * 只累加 byProviderModel 里 provider 前缀为 deepseek 的条目(账本记账时未标注
186
- * provider 的调用同样归入 deepseek);Coding Plan / 自定义 Provider 等渠道不计入。
185
+ * 只累加 byProviderModel 里 provider 前缀为官方渠道的条目:'deepseek'(账本记账时
186
+ * 未标注 provider 的调用归入此键)与 'deepseek-official'(profile 内置官方路由的
187
+ * 实际 provider id,实测账本键形如 deepseek-official:deepseek-v4-flash);Coding
188
+ * Plan / 自定义 Provider / go、zen 等第三方网关不计入。
187
189
  * 无按渠道拆分的旧数据(byProviderModel 缺失/为空)退回全量 cost,保持升级前行为。
188
190
  * @param day - 单日账本记录(可能为 undefined)。
189
191
  */
@@ -194,7 +196,8 @@ export function officialCostOfDay(day) {
194
196
  let sum = 0
195
197
  for (const [key, value] of Object.entries(by)) {
196
198
  const idx = key.indexOf(':')
197
- if ((idx >= 0 ? key.slice(0, idx) : key) !== 'deepseek') continue
199
+ const provider = idx >= 0 ? key.slice(0, idx) : key
200
+ if (provider !== 'deepseek' && provider !== 'deepseek-official') continue
198
201
  sum += Number(value?.cost) || 0
199
202
  }
200
203
  return sum
@@ -1590,14 +1593,18 @@ export class Ledger {
1590
1593
  * 仅当余额确实减少时才对账——订阅/Coding Plan 消费不动官方余额,若强行用余额差
1591
1594
  * 替代今日费用会把订阅用户全天消费归零;充值/额度结构变动时重置参考点防误判;
1592
1595
  * 参考点与本次拉取的币种不一致时(多币种条目挑选切换/旧账本无币种标记)同样重置。
1596
+ * 币种折算(用户实测:CNY 余额账号恒报 drift):余额差按 snap.currency 计价(开放平台
1597
+ * 主币种为 ¥),而账本金额恒为 USD——直接相减/比阈值是跨币种错配。折算入 USD 后再比;
1598
+ * CNY 折算率取 options.exchangeRate(非法回落 7.2 默认展示汇率),非 CNY 按 1:1。
1593
1599
  * @param prevRef - 上一参考点({ date, total, granted, topped, currency, at })或 null。
1594
1600
  * @param balance - 本次拉取结果({ currency, totalBalance, grantedBalance, toppedUpBalance })。
1595
- * @param todayCost - 本地账本今日合计费用。
1601
+ * @param todayCost - 本地账本今日合计费用(USD)。
1596
1602
  * @param dayKey - 本地日期键(YYYY-MM-DD)。
1597
1603
  * @param nowMs - 当前时刻。
1598
- * @returns {{ ref, event }} event.kind ∈ baseline | structure-reset | flat | ok | drift(drift 携带 spent/todayCost)。
1604
+ * @param [options] - { exchangeRate }:CNY→USD 折算率(1 USD X CNY)。
1605
+ * @returns {{ ref, event }} event.kind ∈ baseline | structure-reset | flat | ok | drift(drift 携带 spent/spentCurrency/spentUsd/todayCost)。
1599
1606
  */
1600
- export function reconcileBalanceDelta(prevRef, balance, todayCost, dayKey, nowMs) {
1607
+ export function reconcileBalanceDelta(prevRef, balance, todayCost, dayKey, nowMs, options) {
1601
1608
  if (balance === null || typeof balance !== 'object' || !Number.isFinite(balance.totalBalance)) {
1602
1609
  return { ref: prevRef ?? null, event: null }
1603
1610
  }
@@ -1622,14 +1629,19 @@ export function reconcileBalanceDelta(prevRef, balance, todayCost, dayKey, nowMs
1622
1629
  if (snap.granted > prevRef.granted + 0.009 || snap.topped > prevRef.topped + 0.009) {
1623
1630
  return { ref: snap, event: { kind: 'structure-reset' } }
1624
1631
  }
1632
+ const isCny = snap.currency.toUpperCase() === 'CNY'
1633
+ const fallbackRate = isCny ? 7.2 : 1
1634
+ const configuredRate = Number(options?.exchangeRate)
1635
+ const exchangeRate = Number.isFinite(configuredRate) && configuredRate > 0 ? configuredRate : fallbackRate
1625
1636
  const spent = prevRef.total - snap.total
1637
+ const spentUsd = isCny ? spent / exchangeRate : spent
1626
1638
  // 余额未减少:无法对账(可能整天走订阅扣费),静默。
1627
1639
  if (spent <= 0.009) return { ref: prevRef, event: { kind: 'flat' } }
1628
- const dev = Math.abs(spent - todayCost)
1629
- const threshold = Math.max(0.3, 0.15 * Math.max(spent, todayCost))
1630
- if (dev > threshold) return { ref: prevRef, event: { kind: 'drift', spent, todayCost } }
1640
+ const dev = Math.abs(spentUsd - todayCost)
1641
+ const threshold = Math.max(0.3, 0.15 * Math.max(spentUsd, todayCost))
1642
+ if (dev > threshold) return { ref: prevRef, event: { kind: 'drift', spent, spentCurrency: snap.currency, spentUsd, todayCost } }
1631
1643
  // ok/drift 都保留当日首次基准,后续拉取继续与早间基线比对。
1632
- return { ref: prevRef, event: { kind: 'ok', spent, todayCost } }
1644
+ return { ref: prevRef, event: { kind: 'ok', spent, spentCurrency: snap.currency, spentUsd, todayCost } }
1633
1645
  }
1634
1646
 
1635
1647
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-cost-meter",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "DeepSeek Harness 会话费用统计插件:本会话成本、当日费用、历史记录与官方价格同步,支持多厂商多模型价格计费(内置 90+ 模型价格目录与自动匹配)、主流 Coding Plan 订阅额度查询与显示(9 家,含 SCNet Token Plan 本地 Credits 计量与火山方舟 Volcano Ark Coding Plan AK/SK 签名查询)、自定义 Provider 余额查询(可配任意 HTTP 端点)与余额进度条、峰谷计价时段显示与切换前弹窗/系统通知提醒(位置/提前量/类型可配),界面中英双语。Session cost tracking plugin for DeepSeek Harness: per-conversation cost, daily totals, history and official price sync, with multi-vendor model pricing (built-in 90+ model catalog with auto-matching), Coding Plan quota queries & display for 9 vendors (incl. local credits metering for the SCNet Token Plan and Volcano Ark Coding Plan via AK/SK signature), plan/API dual-track billing with per-1% & full-window Token Plan usage estimates, custom provider balance lookup (configurable HTTP endpoint) and balance progress bar, plus peak/off-peak pricing display with pre-switch popup & system-notification alerts (position / lead time / type configurable), in a bilingual (Chinese/English) UI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",