dsh-tokenlens 1.6.2 → 1.6.4

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/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  **版本记录约定**:同一发布日只保留一个章节,标题取当日**最后一个**已发布版本号;当日多次发布的改动合并到该章节,并在标题下注明当日实际发布过的版本号(npm 上仍可安装这些独立版本)。若当日已有发布,后续小改动不再单独增加版本号,而是并入下一篇日志。这样日志按天规整、不出现同日多个小版本。
6
6
 
7
+ ## 1.6.4 — 2026-11-04
8
+
9
+ (当日已发布版本:v1.6.2 / v1.6.4。v1.6.1 的混合模型修复未单独发版,已并入本节)
10
+
11
+ - **fix(open-design): 「本期 Design Plan 累计」改为只统计 Design Plan 额度消耗,排除钱包余额付费**——钱包扣费不消耗 credits(只扣 `balanceUsd`),所以改由**服务端 credits 反推**金额:`usedCredits ÷ creditsPerUsd ÷ 倍率`。实测 150,005 credits ÷ 10,000 ÷ 0.5 = **$30.00**,与「周额度 $30 × 已用比例」交叉验证一致($30 × 100% = $30.00)。此前按本机 Token × 单价计价,会把钱包付费的调用也算进去,导致两个口径混淆
12
+ - feat(open-design): 新增 `localPricedUsd`(含钱包付费的本机估算)单独保留;当它高于 Design Plan 金额时,弹窗追加「另有 $X 由账户余额支付,未计入」,两个口径都清楚可查
13
+ - **fix(ui): 图表模式日期标签对不齐柱子**——原来把第一个标签钉在左边缘、最后一个钉在右边缘,而柱子是等分 flex 单元格居中的:只有 3 天数据时第一个标签在 0% 而柱子中心在 16.7%,标签整体漂移。改为每个标签居中于**自己那根柱子**的正下方(`(i+0.5)/n`),并放开 x 轴 `overflow` 让边缘标签不被裁掉
14
+ - 测试:332 → 335(Design Plan 金额来自 credits 且低于含钱包的本机估算、无倍率时回退到 credits 面值、3 根柱时标签中心为 16.7%/50%/83.3% 且不贴边)
15
+
7
16
  ## 1.6.2 — 2026-11-04
8
17
 
9
18
  (当日已发布版本:v1.6.2。v1.6.1 的混合模型修复未单独发版,已并入本节)
package/client.js CHANGED
@@ -343,6 +343,7 @@ window.__ModuleLoader__.load({
343
343
  designPlanHint:
344
344
  '按官方定价表的模型单价换算本机实际消耗的 Token(不是 usedCredits ÷ 汇率)。Open Design 没有月度用量接口,此值由插件在本机累计观测到的 7 天窗口得出,仅供参考',
345
345
  designPlanMultiplier: '按 {multiplier}× 倍率模型计价',
346
+ designPlanWalletShare: '另有 {amount} 由账户余额支付,未计入',
346
347
  designPlanPartialPricing: '含未收录价格的模型,金额为下限',
347
348
  designPlanComplete: '已覆盖本账期全部窗口',
348
349
  designPlanPartial: '仅统计已观测的 {count} 个窗口',
@@ -606,6 +607,7 @@ window.__ModuleLoader__.load({
606
607
  designPlanHint:
607
608
  'Priced from the official per-model rates over the tokens this machine actually consumed (not usedCredits ÷ rate). Open Design serves no period-usage endpoint, so the window total is accumulated locally; treat it as an estimate.',
608
609
  designPlanMultiplier: 'priced at the {multiplier}× model rate',
610
+ designPlanWalletShare: 'a further {amount} was paid from the balance and is not counted',
609
611
  designPlanPartialPricing: 'includes models with no documented price; the amount is a lower bound',
610
612
  designPlanComplete: 'covers every window of this period',
611
613
  designPlanPartial: 'only {count} observed window(s)',
@@ -1109,6 +1111,9 @@ window.__ModuleLoader__.load({
1109
1111
  monthlyCapUsd: monthlyCapUsd !== null && monthlyCapUsd > 0 ? monthlyCapUsd : null,
1110
1112
  capPercent,
1111
1113
  multiplier: multiplier !== null && multiplier > 0 ? multiplier : null,
1114
+ // v1.6.4: the wallet-inclusive local token estimate, shown only as context
1115
+ // next to the Design-Plan-only figure (they differ by wallet-paid calls).
1116
+ localPricedUsd: numberOrNull(raw.localPricedUsd),
1112
1117
  // v1.6.2: some consumed model had no documented price, so the dollar
1113
1118
  // figure is a lower bound and must not read as complete.
1114
1119
  partial: raw.partial === true,
@@ -3456,7 +3461,7 @@ window.__ModuleLoader__.load({
3456
3461
  .dsh-tokenlens-chart-bar-wrap[data-chart-hover=true] .dsh-tokenlens-chart-bar{background:#40c877;filter:brightness(1.12);box-shadow:0 0 0 1px rgba(64,200,119,.55)}
3457
3462
  .dsh-tokenlens-chart-crosshair{position:absolute;top:2px;height:160px;z-index:2;pointer-events:none;border-left:1px dashed #d98a1f;opacity:.7}
3458
3463
  .dsh-tokenlens-chart-readout{position:absolute;top:4px;z-index:3;pointer-events:none;max-width:calc(100% - 8px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:1px solid var(--dsw-alias-border-subtle,rgba(127,127,127,.3));border-radius:6px;background:var(--dsw-alias-bg-elevated,#202124);color:var(--dsw-alias-label-primary);font-size:11px;line-height:1.4;padding:2px 6px;box-shadow:0 2px 8px rgba(0,0,0,.25);font-variant-numeric:tabular-nums}
3459
- .dsh-tokenlens-chart-xaxis{position:relative;flex:none;height:14px;min-width:0;max-width:100%;overflow:hidden}
3464
+ .dsh-tokenlens-chart-xaxis{position:relative;flex:none;height:14px;min-width:0;max-width:100%;overflow:visible}
3460
3465
  .dsh-tokenlens-chart-x-label{position:absolute;top:2px;color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:1.2;white-space:nowrap;font-variant-numeric:tabular-nums}
3461
3466
  .dsh-tokenlens-chart-summary{display:flex;flex-wrap:wrap;gap:4px 12px;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.4;min-width:0}
3462
3467
  .dsh-tokenlens-chart-summary>span{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
@@ -4078,6 +4083,15 @@ window.__ModuleLoader__.load({
4078
4083
  if (designPlan.multiplier !== null) {
4079
4084
  notes.push(t('designPlanMultiplier', { multiplier: designPlan.multiplier }))
4080
4085
  }
4086
+ // v1.6.4: when the wallet-inclusive local estimate is HIGHER than the
4087
+ // Design-Plan figure, the difference was paid from the account balance and
4088
+ // must not be presented as Design Plan consumption.
4089
+ if (designPlan.localPricedUsd !== null && designPlan.estimatedUsd !== null) {
4090
+ const walletShare = designPlan.localPricedUsd - designPlan.estimatedUsd
4091
+ if (walletShare > 0.005) {
4092
+ notes.push(t('designPlanWalletShare', { amount: formatMoney(walletShare, 'USD') }))
4093
+ }
4094
+ }
4081
4095
  // v1.6.2: a model without a documented price makes the figure a lower bound.
4082
4096
  // Say it rather than letting the number read as complete.
4083
4097
  if (designPlan.partial === true) notes.push(t('designPlanPartialPricing'))
@@ -4576,16 +4590,17 @@ window.__ModuleLoader__.load({
4576
4590
  ),
4577
4591
  )
4578
4592
  const bars = points.map((point, index) => spec.bar(point, index, { max, hovered: index === hoverIndex }))
4593
+ // v1.6.3: centre every label under ITS OWN bar. The bars are a flex row of
4594
+ // equal cells, so bar i is centred at (i + 0.5) / count of the plot width.
4595
+ // The old code pinned the first label to the left edge and the last to the
4596
+ // right edge, which only lines up when the bars fill the whole width: with
4597
+ // 3 bars the first label sat at 0% while its bar was centred at 16.7%, and
4598
+ // the last sat at 100% while its bar was at 83.3% — the dates drifted off
4599
+ // their columns (reported for a 3-day series).
4579
4600
  const xLabels = chartXLabelIndices(points.length).map((index) => {
4580
4601
  const point = points[index]
4581
4602
  const label = spec.xLabel(point, index)
4582
- const first = index === 0
4583
- const last = index === points.length - 1
4584
- const style = first
4585
- ? { left: '0%' }
4586
- : last
4587
- ? { right: '0%' }
4588
- : { left: `${((index + 0.5) / points.length) * 100}%`, transform: 'translateX(-50%)' }
4603
+ const style = { left: `${((index + 0.5) / points.length) * 100}%`, transform: 'translateX(-50%)' }
4589
4604
  return h(
4590
4605
  'span',
4591
4606
  {
package/index.js CHANGED
@@ -84,7 +84,7 @@ export const inject = []
84
84
  export const PLUGIN_NAME = 'dsh-tokenlens'
85
85
 
86
86
  /** Plugin version; mirrors package.json (kept here so diagnostics need no fs read). */
87
- export const PLUGIN_VERSION = '1.6.2'
87
+ export const PLUGIN_VERSION = '1.6.4'
88
88
 
89
89
  /** Documented defaults; every field of the raw row config is optional. */
90
90
  const DEFAULTS = {
@@ -266,18 +266,34 @@ export function summarizeDesignPlan(ledger, periodStart, input = null) {
266
266
  windows += 1
267
267
  }
268
268
  const creditsPerUsd = period.creditsPerUsd
269
- // v1.6.0: `creditsPerUsd` conversion is kept ONLY as a fallback. It assumes the
270
- // account burns credits at 1x, but the documented multipliers range 0.25x–4x,
271
- // so it is wrong for any non-1x model (2x too low for DeepSeek V4.1 Flash).
272
- // The caller passes the documented list-price cost instead.
273
269
  const creditsUsd =
274
270
  Number.isSafeInteger(creditsPerUsd) && creditsPerUsd > 0 ? usedCredits / creditsPerUsd : null
275
- const estimatedUsd = Number.isFinite(input?.listPriceUsd) ? input.listPriceUsd : creditsUsd
271
+ const multiplier = Number.isFinite(input?.multiplier) && input.multiplier > 0 ? input.multiplier : null
272
+ // v1.6.4: the Design Plan figure is derived FROM THE SERVER'S credits, not from
273
+ // locally-priced tokens. This is what makes it a Design-Plan-only number:
274
+ // credits are deducted for Design Plan allowance ONLY.
275
+ // Wallet-funded usage never touches them — it debits `balanceUsd` instead.
276
+ //
277
+ // `usedCredits / creditsPerUsd` yields the *credit* value; the documented list
278
+ // price is that divided by the model multiplier, because a 0.5x model burns
279
+ // half a credit per list-price dollar. Verified against the account's own caps:
280
+ // 149,932 credits / 10,000 / 0.5 = $29.99
281
+ // 30 * (149,932 / 150,000) = $29.99 (the 7-day cap is $30)
282
+ // Both agree, which is the cross-check that the formula is right.
283
+ //
284
+ // The locally-priced token total (input.listPriceUsd) is kept as `walletUsd`
285
+ // context: it includes wallet-funded calls, so it can EXCEED this figure. It is
286
+ // reported separately and never mixed into `estimatedUsd`.
287
+ const designPlanUsd =
288
+ creditsUsd === null ? null : multiplier === null ? creditsUsd : creditsUsd / multiplier
289
+ const estimatedUsd = designPlanUsd !== null ? designPlanUsd : Number.isFinite(input?.listPriceUsd) ? input.listPriceUsd : null
276
290
  const since = entries[0][0]
277
291
  const limitPerWindow = entries[entries.length - 1][1].limitCredits
278
292
  const usableWindowLimit = Number.isSafeInteger(limitPerWindow) && limitPerWindow > 0 ? limitPerWindow : null
279
293
  const periodLimitCredits = usableWindowLimit === null ? null : usableWindowLimit * WEEKS_PER_PERIOD
280
294
  const percent = periodLimitCredits === null ? null : (usedCredits / periodLimitCredits) * 100
295
+ // The cap is a list-price cap for the model mix, so compare it against the
296
+ // list-price figure derived from credits.
281
297
  const monthlyCapUsd = Number.isFinite(input?.monthlyCapUsd) ? input.monthlyCapUsd : null
282
298
  const capPercent =
283
299
  estimatedUsd !== null && monthlyCapUsd !== null && monthlyCapUsd > 0
@@ -287,10 +303,13 @@ export function summarizeDesignPlan(ledger, periodStart, input = null) {
287
303
  periodStart: key,
288
304
  periodEnd: period.periodEnd || '',
289
305
  usedCredits,
306
+ // Design-Plan-only dollars (from server credits). Comparable with the caps.
290
307
  estimatedUsd,
308
+ // The wallet-inclusive local estimate, kept for transparency/contrast only.
309
+ localPricedUsd: Number.isFinite(input?.listPriceUsd) ? input.listPriceUsd : null,
291
310
  creditsUsd,
292
311
  monthlyCapUsd,
293
- multiplier: Number.isFinite(input?.multiplier) ? input.multiplier : null,
312
+ multiplier,
294
313
  capPercent,
295
314
  // v1.6.2: true when some consumed model has no documented price, so
296
315
  // `estimatedUsd` is a lower bound and the UI must say so.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-tokenlens",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "type": "module",
5
5
  "description": "dsh-TokenLens (词元透镜) — provider-aware plan capacity plus local token statistics (today/7d/30d/all-time, by harness/provider/model/workspace) for DSH.",
6
6
  "license": "MIT",