@kenz1117/dsh-ui-usage-billing 1.1.11 → 1.1.12

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/lib/index.js CHANGED
@@ -222,6 +222,31 @@ const PEAK_ERA_START_MS = Date.parse("2026-08-16T16:00:00Z");
222
222
  */
223
223
  const WEEKEND_OFFPEAK_START_MS = Date.parse("2026-08-22T16:00:00Z");
224
224
  /**
225
+ * flash 系调价分界(UTC 2026-09-10T04:00:00Z,即北京时间 2026-09-10 12:00):
226
+ * 官方自此刻起 V4 Flash / V4 Flash Vision (Exp) 调价——谷档 1.5/0.05/4.5 →
227
+ * 1/0.02/4(峰 = 谷 × 2)。目录条目写现行(新)价;分界前的历史事件由
228
+ * {@link computeCostAt} 按 {@link FLASH_REPRICED_OFFPEAK} 回算旧价,与
229
+ * {@link PEAK_ERA_START_MS} 同一「按事件时刻分段适用规则」口径。
230
+ */
231
+ const FLASH_REPRICE_MS = Date.parse("2026-09-10T04:00:00Z");
232
+ /**
233
+ * flash 系调价前的官方谷档价(CNY / 1M tokens):{@link FLASH_REPRICE_MS}
234
+ * 之前的 flash / flash-vision-exp 事件按此回算(峰档 = 谷档 × 2)。
235
+ * 用户价 = 实付价,与 legacy 口径相同地跳过本表。
236
+ */
237
+ const FLASH_REPRICED_OFFPEAK = {
238
+ flash: {
239
+ input: 1.5,
240
+ cacheHit: .05,
241
+ output: 4.5
242
+ },
243
+ "flash-vision-exp": {
244
+ input: 1.5,
245
+ cacheHit: .05,
246
+ output: 4.5
247
+ }
248
+ };
249
+ /**
225
250
  * DeepSeek V4 峰谷时代之前的官方基础价(CNY / 1M tokens):官方中文定价页
226
251
  * 峰谷改版前的基础价档(缓存写沿用历史规则按命中价计)。键为内置目录键,
227
252
  * flash-vision-exp 与 flash 同价。仅当事件时刻早于 {@link PEAK_ERA_START_MS}
@@ -292,13 +317,13 @@ const MODEL_CATALOG = [
292
317
  colorVar: "dsw-static-blue-500",
293
318
  price: {
294
319
  currency: "CNY",
295
- input: 3,
296
- cacheHit: .1,
297
- output: 9,
320
+ input: 2,
321
+ cacheHit: .04,
322
+ output: 8,
298
323
  offPeak: {
299
- input: 1.5,
300
- cacheHit: .05,
301
- output: 4.5
324
+ input: 1,
325
+ cacheHit: .02,
326
+ output: 4
302
327
  }
303
328
  },
304
329
  peakHours: "09:00-12:00 / 14:00-18:00"
@@ -310,13 +335,13 @@ const MODEL_CATALOG = [
310
335
  colorVar: "dsw-static-blue-500",
311
336
  price: {
312
337
  currency: "CNY",
313
- input: 3,
314
- cacheHit: .1,
315
- output: 9,
338
+ input: 2,
339
+ cacheHit: .04,
340
+ output: 8,
316
341
  offPeak: {
317
- input: 1.5,
318
- cacheHit: .05,
319
- output: 4.5
342
+ input: 1,
343
+ cacheHit: .02,
344
+ output: 4
320
345
  }
321
346
  },
322
347
  peakHours: "09:00-12:00 / 14:00-18:00"
@@ -1656,6 +1681,12 @@ function computeCostAt(entry, buckets, timeMs, peakShare = DEFAULT_PEAK_SHARE) {
1656
1681
  const priced = applyPromo(entry, timeMs);
1657
1682
  const legacy = timeMs < PEAK_ERA_START_MS && entry.userPriced !== true ? LEGACY_DEEPSEEK_BANDS[entry.key] : void 0;
1658
1683
  if (legacy !== void 0) return priceBandCost(legacy, buckets, "CNY");
1684
+ const repriced = timeMs < FLASH_REPRICE_MS && entry.userPriced !== true ? FLASH_REPRICED_OFFPEAK[entry.key] : void 0;
1685
+ if (repriced !== void 0) return priceBandCost((timeMs < WEEKEND_OFFPEAK_START_MS ? tariffV1At(timeMs) : tierAt(timeMs)) === "peak" ? {
1686
+ input: repriced.input * 2,
1687
+ cacheHit: repriced.cacheHit * 2,
1688
+ output: repriced.output * 2
1689
+ } : repriced, buckets, "CNY");
1659
1690
  if (priced.price.offPeak === void 0) return priceBandCost(priced.price, buckets, priced.price.currency);
1660
1691
  return priceBandCost((timeMs < WEEKEND_OFFPEAK_START_MS ? tariffV1At(timeMs) : tierAt(timeMs)) === "peak" ? priced.price : priced.price.offPeak, buckets, priced.price.currency);
1661
1692
  }
@@ -2329,7 +2360,7 @@ function createUsageAggregator(persistence, options = {}) {
2329
2360
  id,
2330
2361
  ...cwd === void 0 ? {} : { cwd },
2331
2362
  ...stamp === null ? {} : { stamp },
2332
- foldVersion: 6,
2363
+ foldVersion: 7,
2333
2364
  fold: serializeFold(fold)
2334
2365
  };
2335
2366
  const row = ledger.get(id);
@@ -2419,7 +2450,7 @@ function createUsageAggregator(persistence, options = {}) {
2419
2450
  try {
2420
2451
  const cwd = meta.cwd;
2421
2452
  const ledgerRow = ledger.get(id);
2422
- if (ledgerRow !== void 0 && ledgerRow.stamp !== void 0 && stamp !== null && ledgerRow.stamp === stamp && (ledgerRow.foldVersion ?? 1) === 6) {
2453
+ if (ledgerRow !== void 0 && ledgerRow.stamp !== void 0 && stamp !== null && ledgerRow.stamp === stamp && (ledgerRow.foldVersion ?? 1) === 7) {
2423
2454
  const fold = deserializeFold(ledgerRow.fold);
2424
2455
  folds.push({
2425
2456
  id,
@@ -2502,7 +2533,7 @@ function createUsageAggregator(persistence, options = {}) {
2502
2533
  for (const entry of ledger.values()) {
2503
2534
  if (included.has(entry.id)) continue;
2504
2535
  try {
2505
- const stale = (entry.foldVersion ?? 1) < 6;
2536
+ const stale = (entry.foldVersion ?? 1) < 7;
2506
2537
  folds.push({
2507
2538
  id: entry.id,
2508
2539
  ...entry.cwd === void 0 ? {} : { cwd: entry.cwd },
@@ -428,7 +428,7 @@ export interface UsageLedgerDocument {
428
428
  * 会话费用只剩最近一段,issue #29)。
429
429
  * 持久账本行据此区分新旧算法:日志已删/不可读而只能沿用旧行时,UI 标注置信度提示。
430
430
  */
431
- export declare const FOLD_VERSION = 6;
431
+ export declare const FOLD_VERSION = 7;
432
432
  /**
433
433
  * 一次性账本迁移:id 唯一,apply 在加载边界对原始文档执行,已应用过的跳过。
434
434
  * 未来账本/schema 字段变更(重命名、拆桶、语义调整)时,在此追加一条迁移并
@@ -126,6 +126,10 @@ interface SessionBillingRow {
126
126
  calls: number;
127
127
  cost: number;
128
128
  lastActive: number;
129
+ /** 展示层合并标记(issue #42):同标题会话归并后的段数(>1 时行尾显示 ×N)。 */
130
+ mergedCount?: number;
131
+ /** 合并组的段明细(展示层专用):一级行默认收起,展开后逐段显示。合并函数需 push,故非 readonly。 */
132
+ children?: SessionBillingRow[];
129
133
  }
130
134
  /** Usage stats structure from `.dsh-usage-stats.json`. */
131
135
  export interface UsageStats {
@@ -1,5 +1,5 @@
1
1
  /** Locale dictionaries for the usage billing surface. */
2
- export type UsageBillingKey = 'title' | 'subtitle' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'liveTurn' | 'liveSession' | 'totalCost' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'trendEmpty' | 'budget' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'project' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'estimated' | 'actual' | 'pricing' | 'showPricing' | 'hidePricing' | 'pricePerM' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'peakHours' | 'band' | 'openDashboard' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptions' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'triggerMonthTokens' | 'floatPrev' | 'floatNext' | 'subscriptionsStale' | 'staleLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemove' | 'sessionStaleBadge' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'workspaces' | 'workspacesHint' | 'plan' | 'remaining' | 'unknownModel' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'currentRound' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabDetails' | 'tabPricing' | 'tabSettings' | 'settingsHead' | 'settingsHint' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionIncluded' | 'free' | 'official' | 'thirdParty' | 'officialCost' | 'thirdPartyCost' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'heatmapYear' | 'heatmapMonth' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginInfo' | 'pluginName' | 'pluginDescription' | 'pluginVersion' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenCacheHitRate' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popQuotaAlert' | 'popRiskNone' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'popBalanceNormal' | 'popBalanceLow' | 'popQuotaNormal' | 'popQuotaLow' | 'alertBalanceLow' | 'alertQuotaLow' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'exportCsvSite' | 'panelRelay' | 'relaySite' | 'relayDirect' | 'relayUnknown' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'relayCalls';
2
+ export type UsageBillingKey = 'title' | 'subtitle' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'liveTurn' | 'liveSession' | 'totalCost' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'trendEmpty' | 'budget' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'project' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'estimated' | 'actual' | 'pricing' | 'showPricing' | 'hidePricing' | 'pricePerM' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'peakHours' | 'band' | 'openDashboard' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptions' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'triggerMonthTokens' | 'floatPrev' | 'floatNext' | 'subscriptionsStale' | 'staleLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemove' | 'sessionStaleBadge' | 'sessionUntitled' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'workspaces' | 'workspacesHint' | 'plan' | 'remaining' | 'unknownModel' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'currentRound' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabDetails' | 'tabPricing' | 'tabSettings' | 'settingsHead' | 'settingsHint' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionIncluded' | 'free' | 'official' | 'thirdParty' | 'officialCost' | 'thirdPartyCost' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'heatmapYear' | 'heatmapMonth' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginInfo' | 'pluginName' | 'pluginDescription' | 'pluginVersion' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenCacheHitRate' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popQuotaAlert' | 'popRiskNone' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'popBalanceNormal' | 'popBalanceLow' | 'popQuotaNormal' | 'popQuotaLow' | 'alertBalanceLow' | 'alertQuotaLow' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'exportCsvSite' | 'panelRelay' | 'relaySite' | 'relayDirect' | 'relayUnknown' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'relayCalls';
3
3
  export declare const NS = "usageBilling";
4
4
  export declare const zh: Record<UsageBillingKey, string>;
5
5
  export declare const en: Record<UsageBillingKey, string>;
@@ -111,6 +111,14 @@ export declare const PEAK_ERA_START_MS: number;
111
111
  * 档位判定按事件所在时段适用各自的规则,不得统一套现行规则重算历史。
112
112
  */
113
113
  export declare const WEEKEND_OFFPEAK_START_MS: number;
114
+ /**
115
+ * flash 系调价分界(UTC 2026-09-10T04:00:00Z,即北京时间 2026-09-10 12:00):
116
+ * 官方自此刻起 V4 Flash / V4 Flash Vision (Exp) 调价——谷档 1.5/0.05/4.5 →
117
+ * 1/0.02/4(峰 = 谷 × 2)。目录条目写现行(新)价;分界前的历史事件由
118
+ * {@link computeCostAt} 按 {@link FLASH_REPRICED_OFFPEAK} 回算旧价,与
119
+ * {@link PEAK_ERA_START_MS} 同一「按事件时刻分段适用规则」口径。
120
+ */
121
+ export declare const FLASH_REPRICE_MS: number;
114
122
  /** 计费时段档位:高峰 / 空闲(官方 DeepSeek 刊例价:高峰 = 空闲 × 2)。 */
115
123
  export type PriceTierId = 'peak' | 'offPeak';
116
124
  /** 成本显示币种:人民币(国内模型直价)/ 美元(国外模型直价或换算显示)。 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kenz1117/dsh-ui-usage-billing",
3
3
  "description": "Usage billing dashboard for DeepSeek Harness: sidebar cost metrics plus a full dashboard modal, priced from a current multi-provider catalog with real usage aggregated from session logs.",
4
- "version": "1.1.11",
4
+ "version": "1.1.12",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },