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/README.en.md +8 -5
- package/README.md +8 -5
- package/docs/provider-pricing.json +18 -1
- package/lib/backfill.js +12 -5
- package/lib/client.js +5 -6
- package/lib/index.js +31 -5
- package/lib/native-search-billing.js +278 -0
- package/lib/pricing.js +26 -7
- package/lib/session-tree.js +117 -0
- package/lib/store.js +15 -2
- package/lib/typert.host.js +41 -1
- package/package.json +1 -1
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
|
-
|
|
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')
|
package/lib/typert.host.js
CHANGED
|
@@ -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:
|
|
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.
|
|
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",
|