@kenz1117/dsh-ui-usage-billing 1.0.6 → 1.0.7
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/client.js +2 -2
- package/lib/index.js +41 -10
- package/lib/types/aggregate.d.ts +23 -5
- package/lib/types/client/UsageBilling.d.ts +4 -0
- package/lib/types/client/locales.d.ts +1 -1
- package/package.json +4 -2
package/lib/index.js
CHANGED
|
@@ -1638,8 +1638,9 @@ function formatTokens(value) {
|
|
|
1638
1638
|
* Real-usage aggregation: folds every persisted session log into the
|
|
1639
1639
|
* usage-stats document the dashboard renders.
|
|
1640
1640
|
*
|
|
1641
|
-
* Each LLM call is attributed to the
|
|
1642
|
-
*
|
|
1641
|
+
* Each LLM call is attributed to the `message.source` carried by its own
|
|
1642
|
+
* `assistant/message` event (copied from the request at write time); the
|
|
1643
|
+
* sparse `request/header` is only a fallback. Costs are estimated with the
|
|
1643
1644
|
* shared billing catalog (`pricing.ts`, in CNY), so only models the catalog
|
|
1644
1645
|
* prices incur a cost — subscription-plan routes and unknown models price
|
|
1645
1646
|
* zero while their tokens still count. Pure functions only: the persistence
|
|
@@ -1797,10 +1798,20 @@ function workspaceNameOf(cwd) {
|
|
|
1797
1798
|
return cwd.split(/[\\/]/).filter(Boolean).at(-1) ?? "—";
|
|
1798
1799
|
}
|
|
1799
1800
|
/**
|
|
1800
|
-
*
|
|
1801
|
-
*
|
|
1801
|
+
* 账本迁移注册表。首条迁移给 1.0.6 及更早的行回填 foldVersion = 1(它们全部出自
|
|
1802
|
+
* header 归因算法);此后新写入的行总带当前 {@link FOLD_VERSION}。
|
|
1802
1803
|
*/
|
|
1803
|
-
const LEDGER_MIGRATIONS = [
|
|
1804
|
+
const LEDGER_MIGRATIONS = [{
|
|
1805
|
+
id: "fold-version-backfill",
|
|
1806
|
+
apply(document) {
|
|
1807
|
+
let changed = false;
|
|
1808
|
+
for (const session of document.sessions) if (session.foldVersion === void 0) {
|
|
1809
|
+
session.foldVersion = 1;
|
|
1810
|
+
changed = true;
|
|
1811
|
+
}
|
|
1812
|
+
return changed;
|
|
1813
|
+
}
|
|
1814
|
+
}];
|
|
1804
1815
|
/**
|
|
1805
1816
|
* 在加载边界对账本文档应用未执行的迁移,并记录已应用 id 供写回。
|
|
1806
1817
|
* @param document - 从持久化读出的原始账本文档。
|
|
@@ -1918,7 +1929,9 @@ function turnState(turns, turn) {
|
|
|
1918
1929
|
}
|
|
1919
1930
|
/**
|
|
1920
1931
|
* Fold one session's events into a {@link SessionFold}. 每个 LLM 调用归属到
|
|
1921
|
-
*
|
|
1932
|
+
* 其 `assistant/message` 自带 `message.source` 记录的模型(agent-loop 落盘时从
|
|
1933
|
+
* 当次请求复制,每个调用一条,不依赖稀疏的 request/header);source 缺失时
|
|
1934
|
+
* 兜底到最近一次 request/header 的状态。同时提取最新会话标题、最后活跃时间,
|
|
1922
1935
|
* 并按轮次折叠每轮费用明细(turn/start → turn/end;调用按 (turn) 归组)。
|
|
1923
1936
|
* @param events - the session's persisted events in log order.
|
|
1924
1937
|
* @param subscriptionProviders - provider ids billed through subscription plans.
|
|
@@ -2023,6 +2036,13 @@ function foldSession(events, subscriptionProviders, officialProviderIds, routes
|
|
|
2023
2036
|
if (event.type !== "assistant/message") continue;
|
|
2024
2037
|
const usage = event.data.usage;
|
|
2025
2038
|
if (usage === void 0) continue;
|
|
2039
|
+
const source = event.data.message?.source;
|
|
2040
|
+
if (source?.kind === "model" && typeof source.provider === "string" && typeof source.model === "string") {
|
|
2041
|
+
key = resolveCatalogKey(source.model);
|
|
2042
|
+
subscription = subscriptionProviders.has(source.provider);
|
|
2043
|
+
official = officialProviderIds === void 0 ? isOfficialProvider(source.provider) : officialProviderIds.has(source.provider);
|
|
2044
|
+
siteBucket = siteBucketKey(siteRefOf(source.provider, routes));
|
|
2045
|
+
}
|
|
2026
2046
|
const modelKey = key;
|
|
2027
2047
|
const day = dayStamp(event.time);
|
|
2028
2048
|
if (!subscription && !isPriced(modelKey)) fold.unpricedModels.add(modelKey);
|
|
@@ -2151,6 +2171,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2151
2171
|
const ledger = /* @__PURE__ */ new Map();
|
|
2152
2172
|
let ledgerLoaded = false;
|
|
2153
2173
|
let ledgerNeedsSave = false;
|
|
2174
|
+
let ledgerAppliedMigrations;
|
|
2154
2175
|
let lastDoc;
|
|
2155
2176
|
let lastAt = 0;
|
|
2156
2177
|
/** 每次聚合取最新的 provider 路由视图(中转站零配置发现);缺省按空处理(全部未知路由)。 */
|
|
@@ -2161,7 +2182,9 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2161
2182
|
try {
|
|
2162
2183
|
const stored = await options.ledger.load();
|
|
2163
2184
|
if (stored !== null && typeof stored === "object" && stored.sessions !== void 0) {
|
|
2164
|
-
|
|
2185
|
+
const document = stored;
|
|
2186
|
+
if (runLedgerMigrations(document)) ledgerNeedsSave = true;
|
|
2187
|
+
ledgerAppliedMigrations = document.appliedMigrations;
|
|
2165
2188
|
}
|
|
2166
2189
|
for (const entry of ledgerSessionsOf(stored)) ledger.set(entry.id, entry);
|
|
2167
2190
|
} catch (error) {
|
|
@@ -2196,6 +2219,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2196
2219
|
const included = /* @__PURE__ */ new Set();
|
|
2197
2220
|
const folds = [];
|
|
2198
2221
|
const skipped = [];
|
|
2222
|
+
let staleLedgerSessions = 0;
|
|
2199
2223
|
for (const meta of metas) {
|
|
2200
2224
|
const id = String(meta.id);
|
|
2201
2225
|
seen.add(id);
|
|
@@ -2232,10 +2256,11 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2232
2256
|
id,
|
|
2233
2257
|
...meta.cwd === void 0 ? {} : { cwd: meta.cwd },
|
|
2234
2258
|
...stamp === null ? {} : { stamp },
|
|
2259
|
+
foldVersion: 2,
|
|
2235
2260
|
fold: serializeFold(fold)
|
|
2236
2261
|
};
|
|
2237
2262
|
const previous = ledger.get(id);
|
|
2238
|
-
if (previous === void 0 || previous.stamp !== entry.stamp || previous.cwd !== entry.cwd || stamp === null && JSON.stringify(previous.fold) !== JSON.stringify(entry.fold)) {
|
|
2263
|
+
if (previous === void 0 || previous.stamp !== entry.stamp || previous.cwd !== entry.cwd || previous.foldVersion !== entry.foldVersion || stamp === null && JSON.stringify(previous.fold) !== JSON.stringify(entry.fold)) {
|
|
2239
2264
|
ledger.set(id, entry);
|
|
2240
2265
|
ledgerNeedsSave = true;
|
|
2241
2266
|
}
|
|
@@ -2255,12 +2280,15 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2255
2280
|
for (const entry of ledger.values()) {
|
|
2256
2281
|
if (included.has(entry.id)) continue;
|
|
2257
2282
|
try {
|
|
2283
|
+
const stale = (entry.foldVersion ?? 1) < 2;
|
|
2258
2284
|
folds.push({
|
|
2259
2285
|
id: entry.id,
|
|
2260
2286
|
...entry.cwd === void 0 ? {} : { cwd: entry.cwd },
|
|
2287
|
+
...stale ? { staleLedger: true } : {},
|
|
2261
2288
|
fold: deserializeFold(entry.fold)
|
|
2262
2289
|
});
|
|
2263
2290
|
included.add(entry.id);
|
|
2291
|
+
if (stale) staleLedgerSessions += 1;
|
|
2264
2292
|
} catch (error) {
|
|
2265
2293
|
console.warn("[usage-billing] skip invalid durable ledger session", entry.id, error);
|
|
2266
2294
|
}
|
|
@@ -2269,7 +2297,8 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2269
2297
|
await options.ledger.save({
|
|
2270
2298
|
version: 1,
|
|
2271
2299
|
updatedAt: now,
|
|
2272
|
-
sessions: [...ledger.values()]
|
|
2300
|
+
sessions: [...ledger.values()],
|
|
2301
|
+
...ledgerAppliedMigrations === void 0 ? {} : { appliedMigrations: ledgerAppliedMigrations }
|
|
2273
2302
|
});
|
|
2274
2303
|
ledgerNeedsSave = false;
|
|
2275
2304
|
} catch (error) {
|
|
@@ -2295,7 +2324,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2295
2324
|
};
|
|
2296
2325
|
const perfModel = /* @__PURE__ */ new Map();
|
|
2297
2326
|
const perfHour = /* @__PURE__ */ new Map();
|
|
2298
|
-
for (const { id: sessionId, cwd, fold } of folds) {
|
|
2327
|
+
for (const { id: sessionId, cwd, fold, staleLedger } of folds) {
|
|
2299
2328
|
mergeUsageInto(total, fold.total);
|
|
2300
2329
|
roles.userChars += fold.roles.userChars;
|
|
2301
2330
|
roles.toolChars += fold.roles.toolChars;
|
|
@@ -2356,6 +2385,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2356
2385
|
id: sessionId,
|
|
2357
2386
|
...fold.title !== void 0 ? { title: fold.title } : {},
|
|
2358
2387
|
...cwd !== void 0 ? { cwd } : {},
|
|
2388
|
+
...staleLedger === true ? { stale: true } : {},
|
|
2359
2389
|
calls: fold.total.calls,
|
|
2360
2390
|
cost: fold.total.cost,
|
|
2361
2391
|
lastActive: fold.lastActive
|
|
@@ -2405,6 +2435,7 @@ function createUsageAggregator(persistence, options = {}) {
|
|
|
2405
2435
|
...bySite.size === 0 ? {} : { bySite: toRecord(bySite) },
|
|
2406
2436
|
...unpricedModels.size === 0 ? {} : { unpricedModels: [...unpricedModels].sort() },
|
|
2407
2437
|
...perf === void 0 ? {} : { perf },
|
|
2438
|
+
...staleLedgerSessions > 0 ? { staleLedgerSessions } : {},
|
|
2408
2439
|
byRole: (() => {
|
|
2409
2440
|
const chars = roles.userChars + roles.toolChars;
|
|
2410
2441
|
const userShare = chars > 0 ? roles.userChars / chars : .5;
|
package/lib/types/aggregate.d.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Real-usage aggregation: folds every persisted session log into the
|
|
3
3
|
* usage-stats document the dashboard renders.
|
|
4
4
|
*
|
|
5
|
-
* Each LLM call is attributed to the
|
|
6
|
-
*
|
|
5
|
+
* Each LLM call is attributed to the `message.source` carried by its own
|
|
6
|
+
* `assistant/message` event (copied from the request at write time); the
|
|
7
|
+
* sparse `request/header` is only a fallback. Costs are estimated with the
|
|
7
8
|
* shared billing catalog (`pricing.ts`, in CNY), so only models the catalog
|
|
8
9
|
* prices incur a cost — subscription-plan routes and unknown models price
|
|
9
10
|
* zero while their tokens still count. Pure functions only: the persistence
|
|
@@ -226,6 +227,8 @@ export interface SessionUsageRow {
|
|
|
226
227
|
cost: number;
|
|
227
228
|
/** 最后一个事件的时间戳(毫秒)。 */
|
|
228
229
|
lastActive: number;
|
|
230
|
+
/** 数据来自旧算法折叠的持久账本行(日志已删/不可读,无法重算);UI 据此标注置信度。 */
|
|
231
|
+
stale?: boolean;
|
|
229
232
|
}
|
|
230
233
|
/** 每轮费用明细行:仪表盘「每轮费用」图的数据源。 */
|
|
231
234
|
export interface TurnUsageRow {
|
|
@@ -332,6 +335,11 @@ export interface UsageLedgerSession {
|
|
|
332
335
|
cwd?: string;
|
|
333
336
|
/** Stable log stamp (mtime + size) when the persistence backend exposes it. */
|
|
334
337
|
stamp?: string;
|
|
338
|
+
/**
|
|
339
|
+
* 折叠该行时的算法版本({@link FOLD_VERSION})。缺失 = 1.0.6 及更早写入的
|
|
340
|
+
* 旧算法行(加载边界由迁移统一回填为 1)。
|
|
341
|
+
*/
|
|
342
|
+
foldVersion?: number;
|
|
335
343
|
fold: SerializedSessionFold;
|
|
336
344
|
}
|
|
337
345
|
/** On-disk durable usage ledger. Versioned independently from the dashboard document. */
|
|
@@ -342,10 +350,18 @@ export interface UsageLedgerDocument {
|
|
|
342
350
|
/** 已应用的一次性配置迁移 id 列表(随文档落盘;缺省 = 尚未跑过任何迁移)。 */
|
|
343
351
|
appliedMigrations?: string[];
|
|
344
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* 折叠算法版本:归账语义变化时递增。v1 = 按 request/header 归账(稀疏 header 把
|
|
355
|
+
* 两次 header 之间的用量串到上一个模型,订阅模型首当其冲,issue #14);v2 =
|
|
356
|
+
* `assistant/message` 自带 source 归账(1.0.7 起)。持久账本行据此区分新旧算法:
|
|
357
|
+
* 日志已删/不可读而只能沿用旧行时,UI 标注置信度提示。
|
|
358
|
+
*/
|
|
359
|
+
export declare const FOLD_VERSION = 2;
|
|
345
360
|
/**
|
|
346
361
|
* 一次性账本迁移:id 唯一,apply 在加载边界对原始文档执行,已应用过的跳过。
|
|
347
362
|
* 未来账本/schema 字段变更(重命名、拆桶、语义调整)时,在此追加一条迁移并
|
|
348
363
|
* bump {@link UsageLedgerDocument.version};引擎保证幂等,重启不会重复执行。
|
|
364
|
+
* 可选字段的向后兼容回填(如 foldVersion)不 bump version:旧版本插件仍能读新文件。
|
|
349
365
|
*/
|
|
350
366
|
export interface LedgerMigration {
|
|
351
367
|
id: string;
|
|
@@ -353,8 +369,8 @@ export interface LedgerMigration {
|
|
|
353
369
|
apply(document: UsageLedgerDocument): boolean;
|
|
354
370
|
}
|
|
355
371
|
/**
|
|
356
|
-
*
|
|
357
|
-
*
|
|
372
|
+
* 账本迁移注册表。首条迁移给 1.0.6 及更早的行回填 foldVersion = 1(它们全部出自
|
|
373
|
+
* header 归因算法);此后新写入的行总带当前 {@link FOLD_VERSION}。
|
|
358
374
|
*/
|
|
359
375
|
export declare const LEDGER_MIGRATIONS: readonly LedgerMigration[];
|
|
360
376
|
/**
|
|
@@ -376,7 +392,9 @@ export interface UsageLedgerStore {
|
|
|
376
392
|
export declare function messageTextLength(message: unknown): number;
|
|
377
393
|
/**
|
|
378
394
|
* Fold one session's events into a {@link SessionFold}. 每个 LLM 调用归属到
|
|
379
|
-
*
|
|
395
|
+
* 其 `assistant/message` 自带 `message.source` 记录的模型(agent-loop 落盘时从
|
|
396
|
+
* 当次请求复制,每个调用一条,不依赖稀疏的 request/header);source 缺失时
|
|
397
|
+
* 兜底到最近一次 request/header 的状态。同时提取最新会话标题、最后活跃时间,
|
|
380
398
|
* 并按轮次折叠每轮费用明细(turn/start → turn/end;调用按 (turn) 归组)。
|
|
381
399
|
* @param events - the session's persisted events in log order.
|
|
382
400
|
* @param subscriptionProviders - provider ids billed through subscription plans.
|
|
@@ -114,6 +114,8 @@ interface SessionBillingRow {
|
|
|
114
114
|
id: string;
|
|
115
115
|
title?: string;
|
|
116
116
|
cwd?: string;
|
|
117
|
+
/** 数据来自旧算法折叠的持久账本行(原始日志已删,无法重算)。 */
|
|
118
|
+
stale?: boolean;
|
|
117
119
|
calls: number;
|
|
118
120
|
cost: number;
|
|
119
121
|
lastActive: number;
|
|
@@ -218,6 +220,8 @@ export interface UsageStats {
|
|
|
218
220
|
};
|
|
219
221
|
/** 性能指标(TTFT/生成速度/总延迟)按模型与按小时;旧快照可能缺失。 */
|
|
220
222
|
perf?: ClientPerf;
|
|
223
|
+
/** 旧版算法账本行兜底的会话数(模型归属可能失真);0 或缺省 = 全部数据可信。 */
|
|
224
|
+
staleLedgerSessions?: number;
|
|
221
225
|
/** 插件版本号(服务端读自包 package.json;旧快照缺失)。 */
|
|
222
226
|
pluginVersion?: string;
|
|
223
227
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'billing.title' | 'billing.subtitle' | 'billing.cost' | 'billing.todayCost' | 'billing.monthCost' | 'billing.yearCost' | 'billing.monthProjected' | 'billing.liveTurn' | 'billing.liveSession' | 'billing.totalCost' | 'billing.calls' | 'billing.cacheHitRate' | 'billing.tokens' | 'billing.inputTokens' | 'billing.outputTokens' | 'billing.avgCost' | 'billing.trend' | 'billing.trend7d' | 'billing.trend30d' | 'billing.trendMetric' | 'billing.trendMetricCost' | 'billing.trendMetricTokens' | 'billing.trendEmpty' | 'billing.budget' | 'billing.budgetAmount' | 'billing.budgetSummary' | 'billing.sessions' | 'billing.sessionTitle' | 'billing.project' | 'billing.lastActive' | 'billing.sessionOverflow' | 'billing.budgetTierBody' | 'billing.models' | 'billing.providerBilling' | 'billing.estimated' | 'billing.actual' | 'billing.pricing' | 'billing.showPricing' | 'billing.hidePricing' | 'billing.pricePerM' | 'billing.input' | 'billing.output' | 'billing.cacheHit' | 'billing.peak' | 'billing.offPeak' | 'billing.flat' | 'billing.peakHours' | 'billing.band' | 'billing.openDashboard' | 'billing.close' | 'billing.footer' | 'billing.footerCredit' | 'billing.lastUpdated' | 'billing.noData' | 'billing.todayRate' | 'billing.rateLive' | 'billing.rateBuiltin' | 'billing.promoBadge' | 'billing.promoUntil' | 'billing.promoOpenEnded' | 'billing.pricingTip' | 'billing.pricingUnit' | 'billing.pricingNotes' | 'billing.ubPeak' | 'billing.ubOff' | 'billing.peakBand' | 'billing.pricingSource' | 'billing.noteCache' | 'billing.noteBand' | 'billing.noteSource' | 'billing.balance' | 'billing.balanceUnconfigured' | 'billing.balanceUnauthorized' | 'billing.balanceUnreachable' | 'billing.uncatalogued' | 'billing.estimatedPricing' | 'billing.balanceDays' | 'billing.balanceLowBody' | 'billing.reconcileDrift' | 'billing.reconcileDismiss' | 'billing.subscriptions' | 'billing.subscriptionNotConfigured' | 'billing.subscriptionUnauthorized' | 'billing.subscriptionUnavailable' | 'billing.subscriptionInvalid' | 'billing.subscriptionRateLimited' | 'billing.subscriptionSession' | 'billing.subscriptionWeekly' | 'billing.subscriptionMonthly' | 'billing.subscriptionBilling' | 'billing.subscriptionRemaining' | 'billing.subscriptionExhausted' | 'billing.subscriptionReset' | 'billing.subscriptionNoApi' | 'billing.floatWindow' | 'billing.floatModeCombined' | 'billing.floatModeSubscription' | 'billing.floatMode' | 'billing.floatTargets' | 'billing.floatWindowHint' | 'billing.floatNoTargets' | 'billing.floatNoTargetsHint' | 'billing.cardDisplay' | 'billing.cardDisplayHint' | 'billing.cardMetric' | 'billing.cardMetricMoney' | 'billing.cardMetricTokens' | 'billing.triggerMonthTokens' | 'billing.floatPrev' | 'billing.floatNext' | 'billing.subscriptionsStale' | 'billing.heatmapLess' | 'billing.heatmapMore' | 'billing.currency' | 'billing.currencyCny' | 'billing.currencyUsd' | 'billing.heatmap' | 'billing.rounds' | 'billing.roundsHint' | 'billing.anomaly' | 'billing.workspaces' | 'billing.workspacesHint' | 'billing.plan' | 'billing.remaining' | 'billing.unknownModel' | 'billing.model' | 'billing.thModel' | 'billing.thInputMiss' | 'billing.thInputHit' | 'billing.currentRound' | 'billing.costAbbr' | 'billing.tabOverview' | 'billing.tabTrends' | 'billing.tabProviders' | 'billing.tabDetails' | 'billing.tabPricing' | 'billing.tabSettings' | 'billing.settingsHead' | 'billing.settingsHint' | 'billing.budgetHint' | 'billing.peakAlertHint' | 'billing.peakAlertDescPeak' | 'billing.peakAlertDescOff' | 'billing.export' | 'billing.exportCsvDay' | 'billing.exportCsvSession' | 'billing.exportJson' | 'billing.peakShare' | 'billing.peakShareHint' | 'billing.weekCost' | 'billing.roleCost' | 'billing.roleUser' | 'billing.roleAssistant' | 'billing.roleTool' | 'billing.roleHint' | 'billing.tierPeak' | 'billing.tierOff' | 'billing.tierToPeak' | 'billing.tierToOff' | 'billing.tierAlertEnterPeak' | 'billing.tierAlertEnterOff' | 'billing.peakAlertTitlePeak' | 'billing.peakAlertTitleOff' | 'billing.peakAlert' | 'billing.peakAlertLeadMin' | 'billing.peakAlertPos' | 'billing.peakAlertMode' | 'billing.peakAlertPosCorner' | 'billing.peakAlertPosCenter' | 'billing.peakAlertModePeak' | 'billing.peakAlertModeOff' | 'billing.peakAlertModeBoth' | 'billing.peakAlertWebNotify' | 'billing.peakAlertPreview' | 'billing.planTypeCode' | 'billing.planTypeToken' | 'billing.subscriptionFeePerMonth' | 'billing.triggerToday' | 'billing.triggerMonth' | 'billing.subscriptionIncluded' | 'billing.free' | 'billing.official' | 'billing.thirdParty' | 'billing.officialCost' | 'billing.thirdPartyCost' | 'billing.perfSamples' | 'billing.perfTtft' | 'billing.perfP50' | 'billing.perfP90' | 'billing.perfTps' | 'billing.perfLatency' | 'billing.perfEstimated' | 'billing.perfEmpty' | 'billing.perfTpsUnit' | 'billing.perfTitle' | 'billing.perfHint' | 'billing.heatmapYear' | 'billing.heatmapMonth' | 'billing.activeDays' | 'billing.streakDays' | 'billing.subscriptionAutoDetect' | 'billing.pluginInfo' | 'billing.pluginName' | 'billing.pluginDescription' | 'billing.pluginVersion' | 'billing.pluginAuthor' | 'billing.pluginRepository' | 'billing.pluginNpm' | 'billing.pluginLicense' | 'billing.tabToken' | 'billing.tokenExport' | 'billing.tokenExportCsv' | 'billing.tokenCacheHitRate' | 'billing.tokenReasoningShare' | 'billing.tokenReasoningShort' | 'billing.tokenIo' | 'billing.tokenPeak' | 'billing.tokenDaily' | 'billing.tokenByModel' | 'billing.tokenMiss' | 'billing.tokenHit' | 'billing.tokenOutput' | 'billing.tokenTotal' | 'billing.tokenShare' | 'billing.usageStatsTool' | 'billing.usageStatsToolHint' | 'billing.balanceGranted' | 'billing.balanceTopped' | 'billing.balanceDaily' | 'billing.balanceDaysLong' | 'billing.balanceDaysUnit' | 'billing.popTodayModel' | 'billing.popNoConsumption' | 'billing.popQuotaAlert' | 'billing.popRiskNone' | 'billing.popTitle' | 'billing.popDirectLead' | 'billing.popSubLead' | 'billing.popBalanceNormal' | 'billing.popBalanceLow' | 'billing.popQuotaNormal' | 'billing.popQuotaLow' | 'billing.alertBalanceLow' | 'billing.alertQuotaLow' | 'billing.unpricedHint' | 'billing.exportCsvSite' | 'billing.panelRelay' | 'billing.relaySite' | 'billing.relayDirect' | 'billing.relayUnknown' | 'billing.panelRelayQuota' | 'billing.relayBalance' | 'billing.relayNoQuota' | 'billing.relayWindowUsed' | 'billing.relayKindNewApi' | 'billing.relayKindSub2Api' | 'billing.relayKindUnknown' | 'billing.relayCalls';
|
|
2
|
+
export type UsageBillingKey = 'billing.title' | 'billing.subtitle' | 'billing.cost' | 'billing.todayCost' | 'billing.monthCost' | 'billing.yearCost' | 'billing.monthProjected' | 'billing.liveTurn' | 'billing.liveSession' | 'billing.totalCost' | 'billing.calls' | 'billing.cacheHitRate' | 'billing.tokens' | 'billing.inputTokens' | 'billing.outputTokens' | 'billing.avgCost' | 'billing.trend' | 'billing.trend7d' | 'billing.trend30d' | 'billing.trendMetric' | 'billing.trendMetricCost' | 'billing.trendMetricTokens' | 'billing.trendEmpty' | 'billing.budget' | 'billing.budgetAmount' | 'billing.budgetSummary' | 'billing.sessions' | 'billing.sessionTitle' | 'billing.project' | 'billing.lastActive' | 'billing.sessionOverflow' | 'billing.budgetTierBody' | 'billing.models' | 'billing.providerBilling' | 'billing.estimated' | 'billing.actual' | 'billing.pricing' | 'billing.showPricing' | 'billing.hidePricing' | 'billing.pricePerM' | 'billing.input' | 'billing.output' | 'billing.cacheHit' | 'billing.peak' | 'billing.offPeak' | 'billing.flat' | 'billing.peakHours' | 'billing.band' | 'billing.openDashboard' | 'billing.close' | 'billing.footer' | 'billing.footerCredit' | 'billing.lastUpdated' | 'billing.noData' | 'billing.todayRate' | 'billing.rateLive' | 'billing.rateBuiltin' | 'billing.promoBadge' | 'billing.promoUntil' | 'billing.promoOpenEnded' | 'billing.pricingTip' | 'billing.pricingUnit' | 'billing.pricingNotes' | 'billing.ubPeak' | 'billing.ubOff' | 'billing.peakBand' | 'billing.pricingSource' | 'billing.noteCache' | 'billing.noteBand' | 'billing.noteSource' | 'billing.balance' | 'billing.balanceUnconfigured' | 'billing.balanceUnauthorized' | 'billing.balanceUnreachable' | 'billing.uncatalogued' | 'billing.estimatedPricing' | 'billing.balanceDays' | 'billing.balanceLowBody' | 'billing.reconcileDrift' | 'billing.reconcileDismiss' | 'billing.subscriptions' | 'billing.subscriptionNotConfigured' | 'billing.subscriptionUnauthorized' | 'billing.subscriptionUnavailable' | 'billing.subscriptionInvalid' | 'billing.subscriptionRateLimited' | 'billing.subscriptionSession' | 'billing.subscriptionWeekly' | 'billing.subscriptionMonthly' | 'billing.subscriptionBilling' | 'billing.subscriptionRemaining' | 'billing.subscriptionExhausted' | 'billing.subscriptionReset' | 'billing.subscriptionNoApi' | 'billing.floatWindow' | 'billing.floatModeCombined' | 'billing.floatModeSubscription' | 'billing.floatMode' | 'billing.floatTargets' | 'billing.floatWindowHint' | 'billing.floatNoTargets' | 'billing.floatNoTargetsHint' | 'billing.cardDisplay' | 'billing.cardDisplayHint' | 'billing.cardMetric' | 'billing.cardMetricMoney' | 'billing.cardMetricTokens' | 'billing.triggerMonthTokens' | 'billing.floatPrev' | 'billing.floatNext' | 'billing.subscriptionsStale' | 'billing.staleLedgerNotice' | 'billing.sessionStaleBadge' | 'billing.heatmapLess' | 'billing.heatmapMore' | 'billing.currency' | 'billing.currencyCny' | 'billing.currencyUsd' | 'billing.heatmap' | 'billing.rounds' | 'billing.roundsHint' | 'billing.anomaly' | 'billing.workspaces' | 'billing.workspacesHint' | 'billing.plan' | 'billing.remaining' | 'billing.unknownModel' | 'billing.model' | 'billing.thModel' | 'billing.thInputMiss' | 'billing.thInputHit' | 'billing.currentRound' | 'billing.costAbbr' | 'billing.tabOverview' | 'billing.tabTrends' | 'billing.tabProviders' | 'billing.tabDetails' | 'billing.tabPricing' | 'billing.tabSettings' | 'billing.settingsHead' | 'billing.settingsHint' | 'billing.budgetHint' | 'billing.peakAlertHint' | 'billing.peakAlertDescPeak' | 'billing.peakAlertDescOff' | 'billing.export' | 'billing.exportCsvDay' | 'billing.exportCsvSession' | 'billing.exportJson' | 'billing.peakShare' | 'billing.peakShareHint' | 'billing.weekCost' | 'billing.roleCost' | 'billing.roleUser' | 'billing.roleAssistant' | 'billing.roleTool' | 'billing.roleHint' | 'billing.tierPeak' | 'billing.tierOff' | 'billing.tierToPeak' | 'billing.tierToOff' | 'billing.tierAlertEnterPeak' | 'billing.tierAlertEnterOff' | 'billing.peakAlertTitlePeak' | 'billing.peakAlertTitleOff' | 'billing.peakAlert' | 'billing.peakAlertLeadMin' | 'billing.peakAlertPos' | 'billing.peakAlertMode' | 'billing.peakAlertPosCorner' | 'billing.peakAlertPosCenter' | 'billing.peakAlertModePeak' | 'billing.peakAlertModeOff' | 'billing.peakAlertModeBoth' | 'billing.peakAlertWebNotify' | 'billing.peakAlertPreview' | 'billing.planTypeCode' | 'billing.planTypeToken' | 'billing.subscriptionFeePerMonth' | 'billing.triggerToday' | 'billing.triggerMonth' | 'billing.subscriptionIncluded' | 'billing.free' | 'billing.official' | 'billing.thirdParty' | 'billing.officialCost' | 'billing.thirdPartyCost' | 'billing.perfSamples' | 'billing.perfTtft' | 'billing.perfP50' | 'billing.perfP90' | 'billing.perfTps' | 'billing.perfLatency' | 'billing.perfEstimated' | 'billing.perfEmpty' | 'billing.perfTpsUnit' | 'billing.perfTitle' | 'billing.perfHint' | 'billing.heatmapYear' | 'billing.heatmapMonth' | 'billing.activeDays' | 'billing.streakDays' | 'billing.subscriptionAutoDetect' | 'billing.pluginInfo' | 'billing.pluginName' | 'billing.pluginDescription' | 'billing.pluginVersion' | 'billing.pluginAuthor' | 'billing.pluginRepository' | 'billing.pluginNpm' | 'billing.pluginLicense' | 'billing.tabToken' | 'billing.tokenExport' | 'billing.tokenExportCsv' | 'billing.tokenCacheHitRate' | 'billing.tokenReasoningShare' | 'billing.tokenReasoningShort' | 'billing.tokenIo' | 'billing.tokenPeak' | 'billing.tokenDaily' | 'billing.tokenByModel' | 'billing.tokenMiss' | 'billing.tokenHit' | 'billing.tokenOutput' | 'billing.tokenTotal' | 'billing.tokenShare' | 'billing.usageStatsTool' | 'billing.usageStatsToolHint' | 'billing.balanceGranted' | 'billing.balanceTopped' | 'billing.balanceDaily' | 'billing.balanceDaysLong' | 'billing.balanceDaysUnit' | 'billing.popTodayModel' | 'billing.popNoConsumption' | 'billing.popQuotaAlert' | 'billing.popRiskNone' | 'billing.popTitle' | 'billing.popDirectLead' | 'billing.popSubLead' | 'billing.popBalanceNormal' | 'billing.popBalanceLow' | 'billing.popQuotaNormal' | 'billing.popQuotaLow' | 'billing.alertBalanceLow' | 'billing.alertQuotaLow' | 'billing.unpricedHint' | 'billing.exportCsvSite' | 'billing.panelRelay' | 'billing.relaySite' | 'billing.relayDirect' | 'billing.relayUnknown' | 'billing.panelRelayQuota' | 'billing.relayBalance' | 'billing.relayNoQuota' | 'billing.relayWindowUsed' | 'billing.relayKindNewApi' | 'billing.relayKindSub2Api' | 'billing.relayKindUnknown' | 'billing.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>;
|
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.0.
|
|
4
|
+
"version": "1.0.7",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -54,7 +54,9 @@
|
|
|
54
54
|
"test": "vitest run"
|
|
55
55
|
},
|
|
56
56
|
"license": "MIT",
|
|
57
|
-
"engines": {
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
59
|
+
},
|
|
58
60
|
"peerDependencies": {
|
|
59
61
|
"@deepseek-ai/dsh-api-remotes": "*",
|
|
60
62
|
"@deepseek-ai/dsh-atomic-write": "*",
|