@kenz1117/dsh-ui-usage-billing 1.4.20 → 1.4.22
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
|
@@ -2720,6 +2720,7 @@ function serializeFold(fold) {
|
|
|
2720
2720
|
bySite: Object.fromEntries(fold.bySite),
|
|
2721
2721
|
unpricedModels: [...fold.unpricedModels],
|
|
2722
2722
|
planCalls: Object.fromEntries(fold.planCalls),
|
|
2723
|
+
planSiteCalls: Object.fromEntries(fold.planSiteCalls),
|
|
2723
2724
|
turns: fold.turns,
|
|
2724
2725
|
perfDigest,
|
|
2725
2726
|
perfHourDigest,
|
|
@@ -2741,6 +2742,7 @@ function deserializeFold(fold) {
|
|
|
2741
2742
|
bySite: new Map(Object.entries(fold.bySite)),
|
|
2742
2743
|
unpricedModels: new Set(fold.unpricedModels),
|
|
2743
2744
|
planCalls: new Map(Object.entries(fold.planCalls)),
|
|
2745
|
+
planSiteCalls: new Map(Object.entries(fold.planSiteCalls ?? {})),
|
|
2744
2746
|
turns: fold.turns,
|
|
2745
2747
|
perf: [],
|
|
2746
2748
|
perfDigest: new Map(Object.entries(fold.perfDigest)),
|
|
@@ -2796,6 +2798,14 @@ function modelDayCell(map, day, modelKey) {
|
|
|
2796
2798
|
}
|
|
2797
2799
|
return usageCell(models, modelKey);
|
|
2798
2800
|
}
|
|
2801
|
+
/** 订阅计数的三维键:日期×模型×站点三元组的 JSON 形态(免分隔符转义歧义)。 */
|
|
2802
|
+
function planSiteKey(day, modelKey, siteKey) {
|
|
2803
|
+
return JSON.stringify([
|
|
2804
|
+
day,
|
|
2805
|
+
modelKey,
|
|
2806
|
+
siteKey
|
|
2807
|
+
]);
|
|
2808
|
+
}
|
|
2799
2809
|
/** Get-or-create one day×model×site cell inside the three-dimensional map. */
|
|
2800
2810
|
function modelDaySiteCell(map, day, modelKey, siteKey) {
|
|
2801
2811
|
let models = map.get(day);
|
|
@@ -2853,6 +2863,7 @@ function freshFold() {
|
|
|
2853
2863
|
bySite: /* @__PURE__ */ new Map(),
|
|
2854
2864
|
unpricedModels: /* @__PURE__ */ new Set(),
|
|
2855
2865
|
planCalls: /* @__PURE__ */ new Map(),
|
|
2866
|
+
planSiteCalls: /* @__PURE__ */ new Map(),
|
|
2856
2867
|
turns: [],
|
|
2857
2868
|
perf: [],
|
|
2858
2869
|
perfDigest: /* @__PURE__ */ new Map(),
|
|
@@ -3014,6 +3025,10 @@ function foldInto(fold, machine, events, subscriptionProviders, officialProvider
|
|
|
3014
3025
|
foldUsage(usageCell(fold.bySite, siteBucket), usage, modelKey, subscription, event.time, official, thisCost, unverifiedChannel);
|
|
3015
3026
|
foldUsage(usageCell(fold.byTier, tierAt(event.time)), usage, modelKey, subscription, event.time, official, thisCost, unverifiedChannel);
|
|
3016
3027
|
if (subscription) fold.planCalls.set(modelKey, (fold.planCalls.get(modelKey) ?? 0) + 1);
|
|
3028
|
+
if (subscription) {
|
|
3029
|
+
const sitePlanKey = planSiteKey(day, modelKey, siteBucket);
|
|
3030
|
+
fold.planSiteCalls.set(sitePlanKey, (fold.planSiteCalls.get(sitePlanKey) ?? 0) + 1);
|
|
3031
|
+
}
|
|
3017
3032
|
const turn = event.data.turn ?? -1;
|
|
3018
3033
|
const state = turnState(turns, turn);
|
|
3019
3034
|
state.model = modelKey;
|
|
@@ -3177,6 +3192,13 @@ function configFingerprint(subscriptionMatcher, officialProviderIds, routeAliase
|
|
|
3177
3192
|
String(searchEstimate)
|
|
3178
3193
|
].join("|");
|
|
3179
3194
|
}
|
|
3195
|
+
/** 会话格式拒读(宿主 SessionFormatUnsupportedError):日志完好,仅本构建读不了。
|
|
3196
|
+
* 宿主错误类显式落 error.name;经包装/重建的路径只在 message 里保留类名,两处都认。
|
|
3197
|
+
* 据此把「格式不受支持」与「损坏/其他读取失败」分开计数,供面板按原因归因(issue #84)。 */
|
|
3198
|
+
function isFormatUnsupportedError(error) {
|
|
3199
|
+
if (!(error instanceof Error)) return false;
|
|
3200
|
+
return error.name === "SessionFormatUnsupportedError" || error.message.includes("SessionFormatUnsupportedError");
|
|
3201
|
+
}
|
|
3180
3202
|
/**
|
|
3181
3203
|
* Create the incremental usage aggregator.
|
|
3182
3204
|
* @param persistence - the session persistence service.
|
|
@@ -3210,7 +3232,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3210
3232
|
id,
|
|
3211
3233
|
...cwd === void 0 ? {} : { cwd },
|
|
3212
3234
|
...stamp === null ? {} : { stamp },
|
|
3213
|
-
foldVersion:
|
|
3235
|
+
foldVersion: 18,
|
|
3214
3236
|
fingerprint: foldFingerprint,
|
|
3215
3237
|
fold: serializeFold(fold)
|
|
3216
3238
|
};
|
|
@@ -3286,12 +3308,22 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3286
3308
|
const included = /* @__PURE__ */ new Set();
|
|
3287
3309
|
const folds = [];
|
|
3288
3310
|
const skipped = [];
|
|
3311
|
+
let carriedUnreadable = 0;
|
|
3312
|
+
let carriedFormatUnreadable = 0;
|
|
3313
|
+
let formatUnreadable = 0;
|
|
3314
|
+
let noLedgerUnreadable = 0;
|
|
3289
3315
|
let staleLedgerSessions = 0;
|
|
3290
3316
|
for (const meta of metas) {
|
|
3291
3317
|
const id = String(meta.id);
|
|
3292
3318
|
seen.add(id);
|
|
3293
3319
|
const stamp = await stampOf(meta);
|
|
3294
|
-
|
|
3320
|
+
const mark = unreadable.get(id);
|
|
3321
|
+
if (stamp !== null && mark !== void 0 && mark.stamp === stamp) {
|
|
3322
|
+
carriedUnreadable += 1;
|
|
3323
|
+
if (mark.format) carriedFormatUnreadable += 1;
|
|
3324
|
+
if (!ledger.has(id)) noLedgerUnreadable += 1;
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
3295
3327
|
const hit = cache.get(id);
|
|
3296
3328
|
if (hit !== void 0 && stamp !== null && hit.stamp === stamp) {
|
|
3297
3329
|
cache.delete(id);
|
|
@@ -3307,7 +3339,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3307
3339
|
try {
|
|
3308
3340
|
const cwd = meta.cwd;
|
|
3309
3341
|
const ledgerRow = ledger.get(id);
|
|
3310
|
-
if (ledgerRow !== void 0 && ledgerRow.stamp !== void 0 && stamp !== null && ledgerRow.stamp === stamp && (ledgerRow.foldVersion ?? 1) ===
|
|
3342
|
+
if (ledgerRow !== void 0 && ledgerRow.stamp !== void 0 && stamp !== null && ledgerRow.stamp === stamp && (ledgerRow.foldVersion ?? 1) === 18 && ledgerRow.fingerprint === foldFingerprint) {
|
|
3311
3343
|
const fold = deserializeFold(ledgerRow.fold);
|
|
3312
3344
|
folds.push({
|
|
3313
3345
|
id,
|
|
@@ -3374,7 +3406,13 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3374
3406
|
recordLedger(id, cwd, stamp, fold);
|
|
3375
3407
|
} catch (error) {
|
|
3376
3408
|
skipped.push(id);
|
|
3377
|
-
|
|
3409
|
+
const format = isFormatUnsupportedError(error);
|
|
3410
|
+
if (format) formatUnreadable += 1;
|
|
3411
|
+
if (!ledger.has(id)) noLedgerUnreadable += 1;
|
|
3412
|
+
if (stamp !== null) unreadable.set(id, {
|
|
3413
|
+
stamp,
|
|
3414
|
+
format
|
|
3415
|
+
});
|
|
3378
3416
|
console.warn("[usage-billing] skip unreadable session", id, error);
|
|
3379
3417
|
}
|
|
3380
3418
|
}
|
|
@@ -3389,7 +3427,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3389
3427
|
for (const entry of ledger.values()) {
|
|
3390
3428
|
if (included.has(entry.id)) continue;
|
|
3391
3429
|
try {
|
|
3392
|
-
const stale = (entry.foldVersion ?? 1) <
|
|
3430
|
+
const stale = (entry.foldVersion ?? 1) < 18 || entry.fingerprint !== foldFingerprint;
|
|
3393
3431
|
folds.push({
|
|
3394
3432
|
id: entry.id,
|
|
3395
3433
|
...entry.cwd === void 0 ? {} : { cwd: entry.cwd },
|
|
@@ -3415,6 +3453,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3415
3453
|
const bySite = /* @__PURE__ */ new Map();
|
|
3416
3454
|
const unpricedModels = /* @__PURE__ */ new Set();
|
|
3417
3455
|
const planCalls = /* @__PURE__ */ new Map();
|
|
3456
|
+
const planSiteCalls = /* @__PURE__ */ new Map();
|
|
3418
3457
|
const sessionRows = [];
|
|
3419
3458
|
const turnRows = [];
|
|
3420
3459
|
const workspaceMap = /* @__PURE__ */ new Map();
|
|
@@ -3443,6 +3482,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3443
3482
|
for (const [toolName, count] of fold.byTool) byTool.set(toolName, (byTool.get(toolName) ?? 0) + count);
|
|
3444
3483
|
for (const id of fold.unpricedModels) unpricedModels.add(id);
|
|
3445
3484
|
for (const [modelKey, count] of fold.planCalls) planCalls.set(modelKey, (planCalls.get(modelKey) ?? 0) + count);
|
|
3485
|
+
for (const [key, count] of fold.planSiteCalls) planSiteCalls.set(key, (planSiteCalls.get(key) ?? 0) + count);
|
|
3446
3486
|
for (const sample of fold.perf) {
|
|
3447
3487
|
let modelAccum = perfModel.get(sample.model);
|
|
3448
3488
|
if (modelAccum === void 0) {
|
|
@@ -3525,7 +3565,12 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3525
3565
|
return record;
|
|
3526
3566
|
};
|
|
3527
3567
|
const toModelDayRecord = (map) => Object.fromEntries([...map].map(([day, models]) => [day, Object.fromEntries(models)]));
|
|
3528
|
-
const toModelDaySiteRecord = (map) => Object.fromEntries([...map].map(([day, models]) => [day, Object.fromEntries([...models].map(([model, sites]) => [model, Object.fromEntries(sites
|
|
3568
|
+
const toModelDaySiteRecord = (map) => Object.fromEntries([...map].map(([day, models]) => [day, Object.fromEntries([...models].map(([model, sites]) => [model, Object.fromEntries([...sites].map(([site, cell]) => {
|
|
3569
|
+
return [site, (planSiteCalls.get(planSiteKey(day, model, site)) ?? 0) === cell.calls && cell.calls > 0 ? {
|
|
3570
|
+
...cell,
|
|
3571
|
+
plan: true
|
|
3572
|
+
} : cell];
|
|
3573
|
+
}))]))]));
|
|
3529
3574
|
const modelKeys = /* @__PURE__ */ new Set([...perfModel.keys(), ...perfModelDigest.keys()]);
|
|
3530
3575
|
const hourKeys = /* @__PURE__ */ new Set([...perfHourModel.keys(), ...perfHourDigest.keys()]);
|
|
3531
3576
|
const perf = modelKeys.size === 0 && hourKeys.size === 0 ? void 0 : {
|
|
@@ -3547,6 +3592,8 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3547
3592
|
}).filter((entry) => entry !== null))];
|
|
3548
3593
|
}))
|
|
3549
3594
|
};
|
|
3595
|
+
const unreadableTotal = skipped.length + carriedUnreadable;
|
|
3596
|
+
const formatUnreadableTotal = formatUnreadable + carriedFormatUnreadable;
|
|
3550
3597
|
lastDoc = {
|
|
3551
3598
|
version: 4,
|
|
3552
3599
|
updatedAt: now,
|
|
@@ -3570,7 +3617,9 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
3570
3617
|
...searchEstimate > 0 ? { searchCallEstimateCny: searchEstimate } : {},
|
|
3571
3618
|
...perf === void 0 ? {} : { perf },
|
|
3572
3619
|
...staleLedgerSessions > 0 ? { staleLedgerSessions } : {},
|
|
3573
|
-
...
|
|
3620
|
+
...unreadableTotal > 0 ? { unreadableSessions: unreadableTotal } : {},
|
|
3621
|
+
...formatUnreadableTotal > 0 ? { unreadableFormatSessions: formatUnreadableTotal } : {},
|
|
3622
|
+
...noLedgerUnreadable > 0 ? { unreadableNoLedgerSessions: noLedgerUnreadable } : {},
|
|
3574
3623
|
byRole: (() => {
|
|
3575
3624
|
const chars = roles.userChars + roles.toolChars;
|
|
3576
3625
|
const userShare = chars > 0 ? roles.userChars / chars : .5;
|
package/lib/types/aggregate.d.ts
CHANGED
|
@@ -295,8 +295,12 @@ export interface UsageStatsDocument {
|
|
|
295
295
|
perf?: PerfStats;
|
|
296
296
|
/** 只存在于账本、且缺 foldVersion 的旧会话数;无旧行时省略。 */
|
|
297
297
|
staleLedgerSessions?: number;
|
|
298
|
-
/**
|
|
298
|
+
/** 本轮未完整计入的会话数(新失败 + 负缓存命中,跨轮次稳定;有账本旧行的按存档计入最近可用点);无失败时省略。 */
|
|
299
299
|
unreadableSessions?: number;
|
|
300
|
+
/** 未统计中因会话格式拒读(SessionFormatUnsupportedError)的子集;无格式拒读时省略。 */
|
|
301
|
+
unreadableFormatSessions?: number;
|
|
302
|
+
/** 未统计中无任何账本存档、完全未计入的子集(区别于有存档按最近可用点计入的);无存档缺失时省略。 */
|
|
303
|
+
unreadableNoLedgerSessions?: number;
|
|
300
304
|
}
|
|
301
305
|
/** 按角色费用归因:user / tool 为输入成本的启发式摊分,assistant 为输出成本实测。 */
|
|
302
306
|
export interface RoleCost {
|
|
@@ -464,6 +468,10 @@ export interface SessionFold {
|
|
|
464
468
|
unpricedModels: Set<string>;
|
|
465
469
|
/** 每个模型 key 在本会话内走订阅通道的调用数(合并时跨会话累加判定 plan)。 */
|
|
466
470
|
planCalls: Map<string, number>;
|
|
471
|
+
/** 三维格(日期×模型×站点)各自的订阅调用数,键 = {@link planSiteKey}:
|
|
472
|
+
* provider 视图的行 plan 按本格判定,不再借模型全局口径(混通道模型会把
|
|
473
|
+
* 本格全订阅的行判成无标记)。 */
|
|
474
|
+
planSiteCalls: Map<string, number>;
|
|
467
475
|
/** 每轮费用明细(按轮次号升序,不含 sessionId);sessionId 在合并时补齐。 */
|
|
468
476
|
turns: SessionTurnRow[];
|
|
469
477
|
/** 性能样本(有可测 TTFT 的调用,按事件次序折叠);仅进程内折叠产生,
|
|
@@ -505,6 +513,8 @@ export interface SerializedSessionFold {
|
|
|
505
513
|
bySite: Record<string, ModelUsage>;
|
|
506
514
|
unpricedModels: string[];
|
|
507
515
|
planCalls: Record<string, number>;
|
|
516
|
+
/** 三维格订阅计数;旧账本行缺失(合并按空处理,格级 plan 保守不置位)。 */
|
|
517
|
+
planSiteCalls?: Record<string, number>;
|
|
508
518
|
turns: SessionTurnRow[];
|
|
509
519
|
/** v16 起以摘要持久化性能(体积 O(模型数) 而非 O(样本数));旧行的
|
|
510
520
|
* `perf` 逐样本数组由加载边界迁移转换为摘要。 */
|
|
@@ -554,7 +564,7 @@ export interface UsageLedgerDocument {
|
|
|
554
564
|
* 会话费用只剩最近一段,issue #29)。
|
|
555
565
|
* 持久账本行据此区分新旧算法:日志已删/不可读而只能沿用旧行时,UI 标注置信度提示。
|
|
556
566
|
*/
|
|
557
|
-
export declare const FOLD_VERSION =
|
|
567
|
+
export declare const FOLD_VERSION = 18;
|
|
558
568
|
/**
|
|
559
569
|
* 一次性账本迁移:id 唯一,apply 在加载边界对原始文档执行,已应用过的跳过。
|
|
560
570
|
* 未来账本/schema 字段变更(重命名、拆桶、语义调整)时,在此追加一条迁移并
|
|
@@ -26,7 +26,7 @@ export interface TrendPoint {
|
|
|
26
26
|
cost: number;
|
|
27
27
|
/** API calls that day (total across models). */
|
|
28
28
|
calls: number;
|
|
29
|
-
/** Total tokens that day (input+output
|
|
29
|
+
/** Total tokens that day (input+output — stats.input already includes cache hit/miss); used by the `tokens` metric. */
|
|
30
30
|
tokens?: number;
|
|
31
31
|
/** Per-model cost that day (stats key → CNY); absent entries plot zero. */
|
|
32
32
|
byModel?: Readonly<Record<string, number>>;
|
|
@@ -110,6 +110,15 @@ export declare function activeDaysOf(byDay: Record<string, {
|
|
|
110
110
|
export declare function streakDaysOf(byDay: Record<string, {
|
|
111
111
|
cost: number;
|
|
112
112
|
}>, now?: number): number;
|
|
113
|
+
/** 按日 Token 口径:输入 + 输出。stats.input 本身已含缓存命中与未命中
|
|
114
|
+
* (aggregate foldUsage:input = cacheHit + cacheMiss),再叠加缓存字段即重复
|
|
115
|
+
* 计数——趋势图/热力图/触发卡/峰值日的按日 Token 一律走本函数(issue #85);
|
|
116
|
+
* 跨日合计在各行之上累加(KPI 见 kpiAgg,触发卡见 month/weekTokens)。
|
|
117
|
+
* 导出供测试:纯函数。 */
|
|
118
|
+
export declare function dayTokensOf(day: {
|
|
119
|
+
input: number;
|
|
120
|
+
output: number;
|
|
121
|
+
}): number;
|
|
113
122
|
/**
|
|
114
123
|
* 近 7 天费用序列(含今天,缺日补 0):触发卡 hover 速览的迷你柱数据源。
|
|
115
124
|
* 导出供测试:纯函数(日期取本地时区)。
|
|
@@ -250,6 +259,8 @@ export interface UsageStats {
|
|
|
250
259
|
cacheHit: number;
|
|
251
260
|
cacheMiss: number;
|
|
252
261
|
cost: number;
|
|
262
|
+
/** 该格全部调用都走订阅通道(聚合侧按三维格置位);旧快照缺失,回退全局口径。 */
|
|
263
|
+
plan?: boolean;
|
|
253
264
|
}>>>;
|
|
254
265
|
/**
|
|
255
266
|
* 峰谷分桶(全量逐调用真实判档):1.0.8 起服务端按调用时刻精确归桶,
|
|
@@ -313,8 +324,12 @@ export interface UsageStats {
|
|
|
313
324
|
perf?: ClientPerf;
|
|
314
325
|
/** 旧版算法账本行兜底的会话数(模型归属可能失真);0 或缺省 = 全部数据可信。 */
|
|
315
326
|
staleLedgerSessions?: number;
|
|
316
|
-
/**
|
|
327
|
+
/** 本轮未完整计入的会话数(跨轮次稳定);0 或缺省 = 全部会话已统计。 */
|
|
317
328
|
unreadableSessions?: number;
|
|
329
|
+
/** 未统计中因会话格式拒读的子集(过新待宿主升级、过旧需迁移);0 或缺省 = 无格式拒读。 */
|
|
330
|
+
unreadableFormatSessions?: number;
|
|
331
|
+
/** 未统计中无账本存档、完全未计入的子集;0 或缺省 = 拒读会话均有存档兜底。 */
|
|
332
|
+
unreadableNoLedgerSessions?: number;
|
|
318
333
|
/** 插件版本号(服务端读自包 package.json;旧快照缺失)。 */
|
|
319
334
|
pluginVersion?: string;
|
|
320
335
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'liveTurn' | 'liveSession' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'kpiRange' | 'avgRangeToday' | 'avgRange7d' | 'avgRangeWeek' | 'avgRangeMonth' | 'avgRangeAll' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'pricingSearch' | 'bandPinHint' | 'trendEmpty' | 'trendTotal' | 'roundsUnit' | 'healthModelsLive' | 'healthVendorsDown' | 'healthVendorsUnavailable' | 'budget' | 'budgetRemain' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'channelUnknown' | 'directTag' | 'relayTag' | 'unknownTag' | 'unknownChannelHint' | 'planCountUnit' | 'actual' | 'pricing' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'band' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'pricingSyncedAt' | 'pricingSyncNow' | 'pricingSyncing' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'recharge' | 'rechargeHint' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatPrimaryToday' | 'floatPrimaryWeek' | 'floatPrimaryMonth' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'cardSpan' | 'cardSpanDay' | 'cardSpanWeek' | 'cardSpanMonth' | 'triggerMonthTokens' | 'triggerTodayTokens' | 'triggerWeekTokens' | 'subscriptionsStale' | 'staleLedgerNotice' | 'unreadableNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceOffPeak' | 'userPriceNormal' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemoveSelected' | 'userPriceSelect' | 'sessionStaleBadge' | 'sessionUntitled' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'currencyEur' | 'language' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabPricing' | 'tabSettings' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'peakAlertDescPeakZhipu' | 'peakAlertDescOffZhipu' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'tierAlertEnterPeakZhipu' | 'tierAlertEnterOffZhipu' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionTag' | 'free' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'perfAll' | 'perfChartEmpty' | 'heatmapYear' | 'heatmapHalf' | 'heatmapMonth' | 'metricCost' | 'metricTokens' | 'heatmapTotal' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenViewStructure' | 'tokenViewModel' | 'tokenHitShort' | 'tokenMissShort' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'liveCostBar' | 'liveCostBarHint' | 'liveCostBarPosition' | 'liveCostBarPosBelow' | 'liveCostBarPosAbove' | 'liveCostBarPosToolbar' | 'exportCsvSite' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'expandAll' | 'collapseAll' | 'todayOnly' | 'todayNoConsumption';
|
|
2
|
+
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'liveTurn' | 'liveSession' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'kpiRange' | 'avgRangeToday' | 'avgRange7d' | 'avgRangeWeek' | 'avgRangeMonth' | 'avgRangeAll' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'pricingSearch' | 'bandPinHint' | 'trendEmpty' | 'trendTotal' | 'roundsUnit' | 'healthModelsLive' | 'healthVendorsDown' | 'healthVendorsUnavailable' | 'budget' | 'budgetRemain' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'channelUnknown' | 'directTag' | 'relayTag' | 'unknownTag' | 'unknownChannelHint' | 'planCountUnit' | 'actual' | 'pricing' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'band' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'pricingSyncedAt' | 'pricingSyncNow' | 'pricingSyncing' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'recharge' | 'rechargeHint' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatPrimaryToday' | 'floatPrimaryWeek' | 'floatPrimaryMonth' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'cardSpan' | 'cardSpanDay' | 'cardSpanWeek' | 'cardSpanMonth' | 'triggerMonthTokens' | 'triggerTodayTokens' | 'triggerWeekTokens' | 'subscriptionsStale' | 'staleLedgerNotice' | 'unreadableNotice' | 'unreadableFormatNotice' | 'unreadableNoLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceOffPeak' | 'userPriceNormal' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemoveSelected' | 'userPriceSelect' | 'sessionStaleBadge' | 'sessionUntitled' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'currencyEur' | 'language' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabPricing' | 'tabSettings' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'peakAlertDescPeakZhipu' | 'peakAlertDescOffZhipu' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'tierAlertEnterPeakZhipu' | 'tierAlertEnterOffZhipu' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionTag' | 'cellEstimateHint' | 'free' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'perfAll' | 'perfChartEmpty' | 'heatmapYear' | 'heatmapHalf' | 'heatmapMonth' | 'metricCost' | 'metricTokens' | 'heatmapTotal' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenViewStructure' | 'tokenViewModel' | 'tokenHitShort' | 'tokenMissShort' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'liveCostBar' | 'liveCostBarHint' | 'liveCostBarPosition' | 'liveCostBarPosBelow' | 'liveCostBarPosAbove' | 'liveCostBarPosToolbar' | 'exportCsvSite' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'expandAll' | 'collapseAll' | 'todayOnly' | 'todayNoConsumption';
|
|
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>;
|
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.4.
|
|
4
|
+
"version": "1.4.22",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
7
7
|
"deepseek",
|