dsh-cost-meter 1.7.19 → 1.7.21

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/store.js CHANGED
@@ -136,6 +136,8 @@ export function defaultConfig() {
136
136
  hideOfficialBalance: false, // 隐藏官方账户余额(issue #45):开启后侧边栏/会话页/设置页的官方余额 UI 整体不渲染
137
137
  hideTodayCost: false, // 隐藏今日消耗金额(issue #46):开启后侧栏今日费用行/预算明细今日行/概览今日卡片不渲染
138
138
  showTotalWithPlan: false, // 「含 Plan 总额」全局开关(v1.6.0):开启后全部金额展示按总等值(cost)计;默认按真金白银(apiCost)
139
+ includeSubagentCost: false, // 本会话展示可合并连续子代理后代;不重复写入每日账本。
140
+ codexQuotaEnabled: false, // Codex 额度按需开启,避免未使用 Codex 时显示卡片或查询。
139
141
  sidebarSimple: false,
140
142
  sidebarSimplePromptSeen: false,
141
143
  sidebarStyle: 'standard', // 侧边栏进度条样式:standard(标准,纵向单列) | compact(紧凑,额度卡两列网格)
@@ -406,7 +408,9 @@ export function repairLedgerPricing(ledger) {
406
408
  const resolved = providerPriceEntryFor(provider, model, ledger.config.prices, priceOpts)
407
409
  if (!resolved.priced || resolved.entry === null) continue
408
410
  // 仅修复 flat 模型的误配,deepseek-peak 依赖峰时判定,近似 noon 易误伤
409
- if (resolved.billingMode === 'deepseek-peak') continue
411
+ // 按单次请求上下文分档的模型不能用日聚合 token 猜档位;保留已记成本,
412
+ // 只允许完整请求日志回放重算,否则多次短请求合计会误套长上下文价格。
413
+ if (resolved.billingMode === 'deepseek-peak' || resolved.entry.longContext) continue
410
414
  const priced = costOf(tokens, resolved.entry, atMsSafe, { enabled: false })
411
415
  const newCost = usdFromCost(priced, 'USD', ledger.config.exchangeRate)
412
416
  const oldCost = Number(bucket.cost) || 0
@@ -446,7 +450,7 @@ export function repairLedgerPricing(ledger) {
446
450
  if ((tokens.input + tokens.output + tokens.cacheRead + tokens.cacheWrite + tokens.reasoning) === 0) continue
447
451
  const resolved = providerPriceEntryFor(provider, model, ledger.config.prices, priceOpts)
448
452
  if (!resolved.priced || resolved.entry === null) continue
449
- if (resolved.billingMode === 'deepseek-peak') continue
453
+ if (resolved.billingMode === 'deepseek-peak' || resolved.entry.longContext) continue
450
454
  const priced = costOf(tokens, resolved.entry, sessAtMs, { enabled: false })
451
455
  const newCost = usdFromCost(priced, 'USD', ledger.config.exchangeRate)
452
456
  const oldCost = Number(bucket.cost) || 0
@@ -727,6 +731,8 @@ const VALIDATION_MESSAGES = {
727
731
  hideOfficialBalance: 'hideOfficialBalance 必须是布尔值',
728
732
  hideTodayCost: 'hideTodayCost 必须是布尔值',
729
733
  showTotalWithPlan: 'showTotalWithPlan 必须是布尔值',
734
+ includeSubagentCost: 'includeSubagentCost 必须是布尔值',
735
+ codexQuotaEnabled: 'codexQuotaEnabled 必须是布尔值',
730
736
  sidebarSimple: '简化显示设置必须是布尔值',
731
737
  sidebarStyle: 'sidebarStyle 必须是 standard / compact',
732
738
  peakStyle: 'peakStyle 必须是 compact / classic',
@@ -826,6 +832,8 @@ const VALIDATION_MESSAGES = {
826
832
  hideOfficialBalance: 'hideOfficialBalance must be a boolean',
827
833
  hideTodayCost: 'hideTodayCost must be a boolean',
828
834
  showTotalWithPlan: 'showTotalWithPlan must be a boolean',
835
+ includeSubagentCost: 'includeSubagentCost must be a boolean',
836
+ codexQuotaEnabled: 'codexQuotaEnabled must be a boolean',
829
837
  sidebarSimple: 'Simple display settings must be boolean',
830
838
  sidebarStyle: 'sidebarStyle must be standard / compact',
831
839
  peakStyle: 'peakStyle must be compact / classic',
@@ -1114,6 +1122,9 @@ export function applyConfigPatch(current, rawPatch) {
1114
1122
  if (candidate.hideTodayCost !== undefined && typeof candidate.hideTodayCost !== 'boolean') errors.push(vmsg(locale, 'hideTodayCost'))
1115
1123
  // 「含 Plan 总额」全局开关(v1.6.0):布尔,可缺省(默认关)。
1116
1124
  if (candidate.showTotalWithPlan !== undefined && typeof candidate.showTotalWithPlan !== 'boolean') errors.push(vmsg(locale, 'showTotalWithPlan'))
1125
+ for (const field of ['includeSubagentCost', 'codexQuotaEnabled']) {
1126
+ if (candidate[field] !== undefined && typeof candidate[field] !== 'boolean') errors.push(vmsg(locale, field))
1127
+ }
1117
1128
  // 侧边栏进度条样式:standard(默认,纵向单列) | compact(额度卡两列网格)。
1118
1129
  for (const field of ['sidebarSimple', 'sidebarSimplePromptSeen']) {
1119
1130
  if (candidate[field] !== undefined && typeof candidate[field] !== 'boolean') errors.push(vmsg(locale, 'sidebarSimple'))
@@ -1440,6 +1451,8 @@ export function sanitizeConfig(raw) {
1440
1451
  out.hideOfficialBalance = out.hideOfficialBalance === true
1441
1452
  out.hideTodayCost = out.hideTodayCost === true
1442
1453
  out.showTotalWithPlan = out.showTotalWithPlan === true
1454
+ out.includeSubagentCost = out.includeSubagentCost === true
1455
+ out.codexQuotaEnabled = out.codexQuotaEnabled === true
1443
1456
  out.sidebarSimple = out.sidebarSimple === true
1444
1457
  out.sidebarSimplePromptSeen = out.sidebarSimplePromptSeen === true
1445
1458
  out.sidebarStyle = oneOf(out.sidebarStyle, ['standard', 'compact'], 'standard')
@@ -45,9 +45,26 @@ const topSessionsSchema = z.object({
45
45
  sessions: z.array(datedSessionSchema),
46
46
  })
47
47
 
48
+ export const sessionCostSchema = z.object({
49
+ own: sessionSchema,
50
+ subagents: sessionSchema,
51
+ subagentCount: num,
52
+ found: z.boolean(),
53
+ })
54
+
55
+ const longContextSchema = z.object({
56
+ aboveInputTokens: z.number().positive(),
57
+ cacheHit: z.number().nonnegative(),
58
+ cacheMiss: z.number().nonnegative(),
59
+ cacheWrite: z.number().nonnegative().optional(),
60
+ output: z.number().nonnegative(),
61
+ reasoning: z.number().nonnegative().optional(),
62
+ })
63
+
48
64
  const priceTierSchema = z.object({
49
65
  cacheHit: num,
50
66
  cacheMiss: num,
67
+ cacheWrite: z.number().nonnegative().optional(),
51
68
  output: num,
52
69
  reasoning: num.optional(),
53
70
  })
@@ -62,7 +79,8 @@ const providerPriceSchema = z.object({
62
79
  input: num.optional(),
63
80
  cachedInput: num.optional(),
64
81
  cacheRead: num.optional(),
65
- cacheWrite: num.optional(),
82
+ cacheWrite: z.number().nonnegative().optional(),
83
+ longContext: longContextSchema.optional(),
66
84
  cacheCreation5m: num.optional(),
67
85
  cacheCreation1h: num.optional(),
68
86
  output: num.optional(),
@@ -88,6 +106,8 @@ const catalogEntrySchema = providerPriceSchema.extend({
88
106
  const priceSchema = z.object({
89
107
  cacheHit: num,
90
108
  cacheMiss: num,
109
+ cacheWrite: z.number().nonnegative().optional(),
110
+ longContext: longContextSchema.optional(),
91
111
  output: num,
92
112
  reasoning: num.optional(),
93
113
  billingMode: z.enum(['flat', 'deepseek-peak', 'batch']).optional(),
@@ -127,6 +147,8 @@ const configSchema = z.object({
127
147
  hideTodayCost: z.boolean().optional(),
128
148
  // 「含 Plan 总额」全局开关(v1.6.0):开启后全部金额展示按总等值(cost)计。
129
149
  showTotalWithPlan: z.boolean().optional(),
150
+ includeSubagentCost: z.boolean().optional(),
151
+ codexQuotaEnabled: z.boolean().optional(),
130
152
  sidebarSimple: z.boolean().optional(),
131
153
  sidebarSimplePromptSeen: z.boolean().optional(),
132
154
  sidebarStyle: z.enum(['standard', 'compact']).optional(),
@@ -475,6 +497,8 @@ const _topSessions$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#TopSess
475
497
  const _limit$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#SessionLimit', schema: num }
476
498
  const _sort$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#SessionSort', schema: z.string() }
477
499
  const _dir$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#SessionSortDir', schema: z.string() }
500
+ const _sessionId$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#SessionId', schema: z.string().min(1).max(512) }
501
+ const _sessionCost$codec = { mode: 'strict', typeSymbol: 'dsh-cost-meter#SessionCost', schema: sessionCostSchema }
478
502
 
479
503
  export const TYPERT = {
480
504
  package: 'dsh-cost-meter',
@@ -616,6 +640,15 @@ export const TYPERT = {
616
640
  ],
617
641
  result: _topSessions$codec,
618
642
  },
643
+ {
644
+ id: 'dsh-cost-meter#costMeter/getSessionCost',
645
+ service: 'costMeter',
646
+ namespace: 'costMeter',
647
+ method: 'getSessionCost',
648
+ invocation: { kind: 'direct' },
649
+ parameters: [{ name: 'sessionId', wire: 'sessionId', source: 'json', codec: _sessionId$codec }],
650
+ result: _sessionCost$codec,
651
+ },
619
652
  {
620
653
  // 写入一枚密钥到 DSH 凭据库(v1.6.8):密钥不再经 updateConfig 传递,值只进凭据库。
621
654
  id: 'dsh-cost-meter#costMeter/setCredential',
@@ -729,6 +762,13 @@ export const TYPERT = {
729
762
  summary: '跨全部日期按指定排序返回前 N 个会话(不分日期视角)。Return the top N sessions across all days with the given sort.',
730
763
  jsDoc: '/**\n * 跨全部日期返回前 N 个会话(每条带所属日期/标题/创建时刻)。\n * @param limit - 返回条数上限(服务端限制 1-500)。\n * @param sort - cost(费用) | time(创建时间) | recent(实时顺序)。\n * @param dir - asc | desc(默认 desc)。\n * @returns 会话列表(含 date/title/at 字段)。\n * Return the top N sessions across all days (each tagged with date/title/createdAt).\n * @param limit - Max rows to return (server clamps to 1-500).\n * @param sort - cost | time | recent (ledger/sidebar order).\n * @param dir - asc | desc (defaults to desc).\n * @returns Session list with date/title/at fields.\n */',
731
764
  },
765
+ {
766
+ kind: 'method',
767
+ name: 'getSessionCost',
768
+ signature: 'getSessionCost(sessionId: string): SessionCost',
769
+ summary: '读取本会话跨日期账本及可选的子代理费用汇总。Read a session ledger and optional descendant costs.',
770
+ jsDoc: '/** 只读会话费用;后代合计不改变每日账本。Read-only cost summary; descendant costs never rewrite daily totals. */',
771
+ },
732
772
  {
733
773
  kind: 'method',
734
774
  name: 'setCredential',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-cost-meter",
3
- "version": "1.7.19",
3
+ "version": "1.7.21",
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",