@kenz1117/dsh-ui-usage-billing 1.1.13 → 1.2.0
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 +42 -24
- package/README.md +37 -32
- package/lib/client.js +5 -5
- package/lib/index.js +558 -61
- package/lib/types/aggregate.d.ts +81 -28
- package/lib/types/client/PerfPanel.d.ts +10 -8
- package/lib/types/client/TokenPanel.d.ts +55 -3
- package/lib/types/client/apply.d.ts +10 -3
- package/lib/types/client/budget-store.d.ts +1 -1
- package/lib/types/client/completion-notify.d.ts +2 -2
- package/lib/types/client/live-cost.d.ts +19 -9
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/pricing.d.ts +60 -8
- package/lib/types/client/provider-display.d.ts +7 -0
- package/lib/types/client/usage-billing-settings.d.ts +42 -0
- package/lib/types/index.d.ts +24 -1
- package/lib/types/subscriptions.d.ts +2 -0
- package/lib/types/tc3.d.ts +60 -0
- package/package.json +46 -24
package/lib/types/aggregate.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* zero while their tokens still count. Pure functions only: the persistence
|
|
11
11
|
* handle is injected, so the fold is unit-testable without a host.
|
|
12
12
|
*/
|
|
13
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
13
14
|
import type { SessionPersistence } from '@deepseek-ai/dsh-session-persistence';
|
|
14
15
|
import type { TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
15
16
|
import { MODEL_KEY_ALIASES, resolveCatalogKey } from './client/pricing.ts';
|
|
@@ -17,9 +18,9 @@ export { MODEL_KEY_ALIASES, resolveCatalogKey };
|
|
|
17
18
|
/**
|
|
18
19
|
* 走订阅套餐(coding / token plan / opencode 订阅)的 provider id:这些通道的
|
|
19
20
|
* 调用按套餐计费,不再按 token 计费,因此即使模型 id 与计费表撞名也一律豁免。
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* 此列表保留为显式配置的参考基线;聚合层缺省改用与订阅卡一致的
|
|
22
|
+
* `isSubscriptionProviderId` 判定(覆盖本列表与全部 `*-token-plan` / `*-coding` 变体),
|
|
23
|
+
* 部署仍可在 plugin config 的 `subscriptionProviders` 中显式覆盖。
|
|
23
24
|
*/
|
|
24
25
|
export declare const DEFAULT_SUBSCRIPTION_PROVIDERS: readonly string[];
|
|
25
26
|
/**
|
|
@@ -28,6 +29,25 @@ export declare const DEFAULT_SUBSCRIPTION_PROVIDERS: readonly string[];
|
|
|
28
29
|
* 调用与费用分桶展示;部署可由配置覆盖(见 {@link AggregateOptions})。
|
|
29
30
|
*/
|
|
30
31
|
export declare function isOfficialProvider(provider: string): boolean;
|
|
32
|
+
/** DeepSeek 官方直连端点的归一化 origin(`siteOriginOf` 口径):有 baseURL 的路由只有它算官方。 */
|
|
33
|
+
export declare const OFFICIAL_DEEPSEEK_ORIGIN = "https://api.deepseek.com";
|
|
34
|
+
/**
|
|
35
|
+
* 官方渠道判定(通道优先):显式 `officialProviderIds` 配置最优先;否则看站点归组——
|
|
36
|
+
* 有 baseURL 的路由只有 origin 为 DeepSeek 官方域才算官方(修复:名为 `deepseek-*`
|
|
37
|
+
* 的中转/网关路由曾被按 id 前缀误判为官方,腾讯网关的 DeepSeek 全被计成官方渠道);
|
|
38
|
+
* 直连路由(配置在册、无 baseURL)与路由表查不到的未知名都退回按 provider id
|
|
39
|
+
* 前缀判定——宿主内置的官方直连不经 llm-pi-ai 路由,其 provider 名不在路由表中,
|
|
40
|
+
* 按 unknown 一刀切会把它错杀成三方(回归修复);配置外的同名网关残留可用
|
|
41
|
+
* `routeAliases` 显式归位到真实通道。
|
|
42
|
+
*/
|
|
43
|
+
export declare function officialChannelOf(provider: string, ref: SiteRef, officialProviderIds?: ReadonlySet<string>): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* 订阅制 provider 匹配器:显式列表(配置覆盖)或判定函数(默认
|
|
46
|
+
* {@link isSubscriptionProviderId},与订阅卡识别同一正则口径,修复两者不一致)。
|
|
47
|
+
*/
|
|
48
|
+
export type SubscriptionMatcher = ReadonlySet<string> | ((provider: string) => boolean);
|
|
49
|
+
/** 一个 provider 是否走订阅套餐计费(豁免按 token 计价)。 */
|
|
50
|
+
export declare function isSubscriptionCall(subscription: SubscriptionMatcher, provider: string): boolean;
|
|
31
51
|
/** 一个 provider 路由的站点视图(来自 llm-pi-ai providers 的 baseURL)。 */
|
|
32
52
|
export interface ProviderRouteView {
|
|
33
53
|
/** 该路由配置的端点地址;无值 = 直连厂商(非中转站)。 */
|
|
@@ -49,19 +69,33 @@ export declare function siteOriginOf(baseURL: string): string;
|
|
|
49
69
|
* 把一个 provider 路由归类为站点引用。判定顺序(与路由在 provider 配置里的状态一致):
|
|
50
70
|
* - 路由存在于当前配置且配了 baseURL → 中转站 `site`(按 origin 归组,同站多 key 合并);
|
|
51
71
|
* - 路由存在于当前配置但无 baseURL → 厂商直连 `direct`;
|
|
52
|
-
* -
|
|
72
|
+
* - 路由不在当前配置里:内置官方直连(`deepseek` / `deepseek-*` 形态,不经 llm-pi-ai
|
|
73
|
+
* 网关)按 `direct` 归位——unknown 一刀切会把官方直连的费用堆进「未知路由」组、
|
|
74
|
+
* 且不算官方渠道(回归修复);订阅豁免命中的通道(显式 `subscriptionProviders`
|
|
75
|
+
* 配置或判定函数)同样按 `direct` 归位——订阅管理类插件注册的通道不经路由表,
|
|
76
|
+
* unknown 桶既掩盖归属又按 token 误计费(issue #37 的 grok build);其余配置外
|
|
77
|
+
* 名称保留 unknown(无法核实通道)。
|
|
53
78
|
* @param provider - 会话日志里的 provider 路由名(request/header 的 `config.provider`)。
|
|
54
79
|
* @param routes - 当前 provider 路由视图(来自 llm-pi-ai providers)。
|
|
80
|
+
* @param opts - `subscription`:该调用是否已被订阅豁免判定命中。
|
|
55
81
|
*/
|
|
56
|
-
export declare function siteRefOf(provider: string, routes: Readonly<Record<string, ProviderRouteView
|
|
82
|
+
export declare function siteRefOf(provider: string, routes: Readonly<Record<string, ProviderRouteView>>, opts?: {
|
|
83
|
+
subscription?: boolean;
|
|
84
|
+
}): SiteRef;
|
|
57
85
|
/** 站点桶的稳定 key:`site:<origin>` 与 `direct:<provider>` 分开,`unknown` 单一桶。 */
|
|
58
86
|
export declare function siteBucketKey(ref: SiteRef): string;
|
|
59
87
|
/** Aggregation tuning options. */
|
|
60
88
|
export interface AggregateOptions {
|
|
61
|
-
/** 订阅制 provider id
|
|
89
|
+
/** 订阅制 provider id 列表;缺省按订阅卡同款 id 判定(`isSubscriptionProviderId`)。 */
|
|
62
90
|
subscriptionProviders?: readonly string[];
|
|
63
|
-
/** 官方渠道 provider id
|
|
91
|
+
/** 官方渠道 provider id 列表;缺省按 {@link officialChannelOf} 判定(通道 origin 优先)。 */
|
|
64
92
|
officialProviderIds?: readonly string[];
|
|
93
|
+
/**
|
|
94
|
+
* 历史路由别名(旧路由名 → 当前路由名):改过名 / 删除过的 provider 路由,
|
|
95
|
+
* 其历史用量原会落「未知路由」桶;配置别名后按目标路由归组(站点、订阅、
|
|
96
|
+
* 官方判定都用别名后的路由名)。
|
|
97
|
+
*/
|
|
98
|
+
routeAliases?: Readonly<Record<string, string>>;
|
|
65
99
|
/** 每会话折叠缓存的上限(默认 {@link DEFAULT_MAX_CACHE_SESSIONS});
|
|
66
100
|
* 超限时按最近使用先后淘汰最久未用的会话,防长期运行内存膨胀。 */
|
|
67
101
|
maxCacheSessions?: number;
|
|
@@ -155,11 +189,15 @@ export declare const UNKNOWN_WORKSPACE_NAME = "\u2014";
|
|
|
155
189
|
export declare function workspaceNameOf(cwd: string | undefined): string;
|
|
156
190
|
/**
|
|
157
191
|
* The persistence surface the aggregate reads: enough of
|
|
158
|
-
* `SessionPersistence` to list sessions and read each log once
|
|
159
|
-
*
|
|
160
|
-
*
|
|
192
|
+
* `SessionPersistence` to list sessions and read each log once. Two
|
|
193
|
+
* optional invalidation-stamp sources, checked in order:
|
|
194
|
+
* `stampOf` (host 0.1.3+: the persistence revision token, exposed by the
|
|
195
|
+
* host-shape adapter) then `locate` (host 0.1.2: artifact mtime + size).
|
|
196
|
+
* Neither present means every round re-folds.
|
|
161
197
|
*/
|
|
162
|
-
export type UsagePersistence = Pick<SessionPersistence, 'list' | 'readFrom'> & Partial<Pick<SessionPersistence, 'locate'
|
|
198
|
+
export type UsagePersistence = Pick<SessionPersistence, 'list' | 'readFrom'> & Partial<Pick<SessionPersistence, 'locate'>> & Partial<{
|
|
199
|
+
stampOf(id: SessionId): Promise<string | null>;
|
|
200
|
+
}>;
|
|
163
201
|
/** The usage-stats document served to the billing dashboard. */
|
|
164
202
|
export interface UsageStatsDocument {
|
|
165
203
|
version: number;
|
|
@@ -220,6 +258,8 @@ export interface UsageStatsDocument {
|
|
|
220
258
|
* 以 step/start 为起点估算并计 estimated。
|
|
221
259
|
*/
|
|
222
260
|
perf?: PerfStats;
|
|
261
|
+
/** 只存在于账本、且缺 foldVersion 的旧会话数;无旧行时省略。 */
|
|
262
|
+
staleLedgerSessions?: number;
|
|
223
263
|
}
|
|
224
264
|
/** 按角色费用归因:user / tool 为输入成本的启发式摊分,assistant 为输出成本实测。 */
|
|
225
265
|
export interface RoleCost {
|
|
@@ -234,8 +274,8 @@ export interface RoleCost {
|
|
|
234
274
|
export interface PerfStats {
|
|
235
275
|
/** 按模型聚合(键 = 计费目录键;未收录模型原样保留)。 */
|
|
236
276
|
byModel: Record<string, ModelPerf>;
|
|
237
|
-
/**
|
|
238
|
-
|
|
277
|
+
/** 按小时×模型聚合(外键 = {@link hourStamp},内键 = 模型目录键;北京时间)。 */
|
|
278
|
+
byHourModel: Record<string, Record<string, HourModelPerf>>;
|
|
239
279
|
}
|
|
240
280
|
/** 一个模型的性能统计:首字延时均值 / P50 / P90、生成速度均值、总延迟均值。 */
|
|
241
281
|
export interface ModelPerf {
|
|
@@ -258,11 +298,11 @@ export interface ModelPerf {
|
|
|
258
298
|
/** 以 step/start 估算的样本数(工具续写步骤无独立 request/header)。 */
|
|
259
299
|
estimatedSamples: number;
|
|
260
300
|
}
|
|
261
|
-
/**
|
|
262
|
-
export interface
|
|
301
|
+
/** 一个小时单模型的性能统计(外键 = {@link hourStamp},内键 = 模型目录键)。 */
|
|
302
|
+
export interface HourModelPerf {
|
|
263
303
|
samples: number;
|
|
264
304
|
ttftAvg: number;
|
|
265
|
-
/** 平均生成速度(tokens/s
|
|
305
|
+
/** 平均生成速度(tokens/s);该小时该模型无可测生成窗口时缺失。 */
|
|
266
306
|
tpsAvg?: number;
|
|
267
307
|
}
|
|
268
308
|
/** 会话明细行:仪表盘「会话明细」面板的数据源。 */
|
|
@@ -383,6 +423,8 @@ export interface SerializedSessionFold {
|
|
|
383
423
|
byModel: Record<string, ModelUsage>;
|
|
384
424
|
byDay: Record<string, ModelUsage>;
|
|
385
425
|
byDayModels: Record<string, Record<string, ModelUsage>>;
|
|
426
|
+
/** 会话标题(session/title 事件的最新文本);1.0.30 前的账本行不持久化它,缺失回退 id。 */
|
|
427
|
+
title?: string;
|
|
386
428
|
/** 1.0.10(issue #16)新增;模型×日期×站点三维,旧账本行缺失(合并按空处理)。 */
|
|
387
429
|
byDayModelsSite?: Record<string, Record<string, Record<string, ModelUsage>>>;
|
|
388
430
|
/** 1.0.8 起新增;旧账本行缺失(合并时按空处理,不触发重折算)。 */
|
|
@@ -407,6 +449,11 @@ export interface UsageLedgerSession {
|
|
|
407
449
|
* 旧算法行(加载边界由迁移统一回填为 1)。
|
|
408
450
|
*/
|
|
409
451
|
foldVersion?: number;
|
|
452
|
+
/**
|
|
453
|
+
* 折叠该行时的聚合配置指纹({@link configFingerprint})。缺失 = 1.0.32 及
|
|
454
|
+
* 更早写入的行(配置不参与复用判定);与当前指纹不一致的行不复用、全量重折。
|
|
455
|
+
*/
|
|
456
|
+
fingerprint?: string;
|
|
410
457
|
fold: SerializedSessionFold;
|
|
411
458
|
}
|
|
412
459
|
/** On-disk durable usage ledger. Versioned independently from the dashboard document. */
|
|
@@ -422,17 +469,16 @@ export interface UsageLedgerDocument {
|
|
|
422
469
|
* 两次 header 之间的用量串到上一个模型,订阅模型首当其冲,issue #14);v2 =
|
|
423
470
|
* `assistant/message` 自带 source 归账(1.0.7 起);v3 = 联网搜索请求按次估算
|
|
424
471
|
* 计费(issue #15,1.0.9 起);v4 = 模型×日期×站点三维桶(issue #16,按 origin
|
|
425
|
-
* 绑定自定义价的显示层重估)——旧行缺该维度,按无 origin 价处理;
|
|
426
|
-
*
|
|
472
|
+
* 绑定自定义价的显示层重估)——旧行缺该维度,按无 origin 价处理;v5 = 峰谷
|
|
473
|
+
* 时代之前(2026-08-16T16:00Z)的 DeepSeek 事件按当时基础价计费(v4 把全部
|
|
474
|
+
* 历史套现行峰/谷档价,高估约 50%);v6 = v1 峰谷窗口(至 2026-08-22T16:00Z)
|
|
475
|
+
* 的周末不豁免峰时(v5 错套现行周末全谷规则,低估该窗口周六日的峰时费用);
|
|
476
|
+
* v7 = fork 种子边界改用持久化 `SessionHeader.seedLength`(v6 及更早扫描最后一个
|
|
427
477
|
* `session/end-seed`,resume 续写后继续对话时把本会话历史段误判为种子丢弃,
|
|
428
478
|
* 会话费用只剩最近一段,issue #29)。
|
|
429
479
|
* 持久账本行据此区分新旧算法:日志已删/不可读而只能沿用旧行时,UI 标注置信度提示。
|
|
430
|
-
* 8:官方公告自 2026-09-10 12:00(北京)起 V4 Pro 请求路由至 V4.1 Flash 按 Flash
|
|
431
|
-
* 单价计费(V4.1 Pro 上线前)——pro 目录价改写为 Flash 价、V4 Pro 刊例(峰
|
|
432
|
-
* 9/0.3/27、谷 4.5/0.15/13.5)进 FLASH_REPRICED_OFFPEAK 供分界前回算;v7 及更早
|
|
433
|
-
* 的行把分界后的 pro 全部按 V4 Pro 刊例折算(高估数倍),bump 全量重折对齐时间线。
|
|
434
480
|
*/
|
|
435
|
-
export declare const FOLD_VERSION =
|
|
481
|
+
export declare const FOLD_VERSION = 13;
|
|
436
482
|
/**
|
|
437
483
|
* 一次性账本迁移:id 唯一,apply 在加载边界对原始文档执行,已应用过的跳过。
|
|
438
484
|
* 未来账本/schema 字段变更(重命名、拆桶、语义调整)时,在此追加一条迁移并
|
|
@@ -473,15 +519,15 @@ export declare function messageTextLength(message: unknown): number;
|
|
|
473
519
|
* 兜底到最近一次 request/header 的状态。同时提取最新会话标题、最后活跃时间,
|
|
474
520
|
* 并按轮次折叠每轮费用明细(turn/start → turn/end;调用按 (turn) 归组)。
|
|
475
521
|
* @param events - the session's persisted events in log order.
|
|
476
|
-
* @param subscriptionProviders -
|
|
522
|
+
* @param subscriptionProviders - 订阅套餐匹配器(显式集合或判定函数)。
|
|
477
523
|
* @param officialProviderIds - provider ids treated as the official DeepSeek channel
|
|
478
|
-
* (default:
|
|
524
|
+
* (default: channel-origin based via {@link officialChannelOf}). Others count as third-party.
|
|
479
525
|
* @param routes - 当前 provider 路由视图(中转站归组)。
|
|
480
526
|
* @param searchCallEstimateCny - 联网搜索请求的单次费用估算(人民币元;0 关闭估算)。
|
|
481
|
-
* @param seedLength - 持久化的 fork
|
|
527
|
+
* @param seedLength - 持久化的 fork 血缘边界(存储元数据 `inheritedEventCount`,缺省 0):
|
|
482
528
|
* fork 子会话日志里 `seq < seedLength` 的事件拷贝自父会话、已在父会话计费,
|
|
483
529
|
* 折叠时跳过以避免重复计费;resume 续写复用同一会话日志(每次续写追加一个
|
|
484
|
-
* `session/end-seed`
|
|
530
|
+
* `session/end-seed` 标记)但继承切割保持原值,历史段照常计费。
|
|
485
531
|
* @returns the per-session fold (cached by the incremental aggregator).
|
|
486
532
|
*/
|
|
487
533
|
export declare function foldSession(events: readonly {
|
|
@@ -489,7 +535,7 @@ export declare function foldSession(events: readonly {
|
|
|
489
535
|
time: number;
|
|
490
536
|
data: unknown;
|
|
491
537
|
seq?: number;
|
|
492
|
-
}[], subscriptionProviders:
|
|
538
|
+
}[], subscriptionProviders: SubscriptionMatcher, officialProviderIds?: ReadonlySet<string>, routes?: Readonly<Record<string, ProviderRouteView>>, searchCallEstimateCny?: number, seedLength?: number, routeAliases?: Readonly<Record<string, string>>): SessionFold;
|
|
493
539
|
/**
|
|
494
540
|
* 增量聚合器:按会话缓存折叠结果,用日志文件的 mtime+size 作失效键——
|
|
495
541
|
* 日志没动的会话直接复用,只有写过的会话重新折叠;整份文档另有短 TTL
|
|
@@ -505,6 +551,13 @@ export interface UsageAggregator {
|
|
|
505
551
|
* 进行中的聚合先等完再存,折叠失败仍保存已成功部分。 */
|
|
506
552
|
flush(): Promise<void>;
|
|
507
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* 聚合配置指纹:影响折叠语义的全部配置(订阅豁免、官方名单、路由别名、搜索估值)
|
|
556
|
+
* 的稳定序列化。账本行的复用判定携带该指纹——用户改配置后(如为 grok build 加
|
|
557
|
+
* 订阅豁免),历史账本行立即失效并全量重折,配置变更即时生效(issue #37)。
|
|
558
|
+
* 判定函数无法序列化,统一记为 `fn`(任何函数形态互视为同一指纹)。
|
|
559
|
+
*/
|
|
560
|
+
export declare function configFingerprint(subscriptionMatcher: SubscriptionMatcher, officialProviderIds: ReadonlySet<string> | undefined, routeAliases: Readonly<Record<string, string>>, searchEstimate: number): string;
|
|
508
561
|
/**
|
|
509
562
|
* Create the incremental usage aggregator.
|
|
510
563
|
* @param persistence - the session persistence service.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PerfPanel: per-model latency/perf table + per-hour
|
|
2
|
+
* PerfPanel: per-model latency/perf table + per-hour per-model comparison curve.
|
|
3
3
|
*
|
|
4
4
|
* Reads the optional `perf` field of the usage-stats document (aggregated by
|
|
5
5
|
* the host from session logs). Renders a per-model table of TTFT mean/P50/P90,
|
|
6
6
|
* generation speed, total latency and estimated-step count, plus a small
|
|
7
|
-
* dependency-free SVG
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* dependency-free SVG hourly curve: one colored polyline per lit model with a
|
|
8
|
+
* metric tab (TTFT ms / tok/s) and clickable model chips; hovering snaps to the
|
|
9
|
+
* nearest hour and shows a crosshair + tooltip listing every lit model's value.
|
|
10
|
+
* Absent `perf` renders an empty state; the panel never fabricates samples.
|
|
10
11
|
*/
|
|
11
12
|
import type { TrendSeriesModel } from './TrendChart.tsx';
|
|
12
13
|
import type { UsageBillingKey } from './locales.ts';
|
|
@@ -24,8 +25,8 @@ export interface PerfModelData {
|
|
|
24
25
|
latencyAvg: number;
|
|
25
26
|
estimatedSamples: number;
|
|
26
27
|
}
|
|
27
|
-
/**
|
|
28
|
-
export interface
|
|
28
|
+
/** 小时×模型性能统计(与服务端 `HourModelPerf` 同形)。 */
|
|
29
|
+
export interface PerfHourModelData {
|
|
29
30
|
samples: number;
|
|
30
31
|
ttftAvg: number;
|
|
31
32
|
tpsAvg?: number;
|
|
@@ -33,12 +34,13 @@ export interface PerfHourData {
|
|
|
33
34
|
/** 性能指标文档(服务端可选 `perf` 字段;旧快照缺失)。 */
|
|
34
35
|
export interface ClientPerf {
|
|
35
36
|
byModel: Record<string, PerfModelData>;
|
|
36
|
-
|
|
37
|
+
/** 小时 → 模型 → 小时统计;旧 host 文档缺失时图表区按空态兜底。 */
|
|
38
|
+
byHourModel: Record<string, Record<string, PerfHourModelData>>;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Render the performance panel.
|
|
40
42
|
* @param props.perf - the optional perf doc; `undefined`/empty renders an empty state.
|
|
41
|
-
* @param props.models - model legend (key/name/color) for the table swatches and curve
|
|
43
|
+
* @param props.models - model legend (key/name/color) for the table swatches and curve chips.
|
|
42
44
|
* @param props.t - locale function.
|
|
43
45
|
*/
|
|
44
46
|
export declare function PerfPanel({ perf, models, t, }: {
|
|
@@ -1,23 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TokenPanel: 「Token」分区——把 token 从费用里独立出来洞察。
|
|
3
3
|
* 四个板块 + 导出,全部由 `UsageStats` 派生,服务端零改动:
|
|
4
|
-
* 1. 每日 Token
|
|
5
|
-
*
|
|
4
|
+
* 1. 每日 Token 趋势,双视角切换(7/30 天):
|
|
5
|
+
* - 按结构:未命中输入 / 缓存命中 / 输出[含 reasoning] 三桶堆叠;
|
|
6
|
+
* - 按模型:每天按模型堆叠,段 = 该模型当日「模型总 Token」(输入[含命中] + 输出),
|
|
7
|
+
* 分色复用趋势页 `chartModels`(同模型同色跨页一致);
|
|
8
|
+
* 旧快照缺 `byDayModels` 时隐藏切换钮,仅保留结构视角。
|
|
9
|
+
* 悬停显示当日精确明细;图例 / 「模型 Token」表格行可点击聚焦单个模型
|
|
10
|
+
* (目标段保持原色,其余段弱化,y 轴不变)。
|
|
11
|
+
* 归因边界:reasoning 无按日 × 模型明细(`byDayModels` 无该字段),图与导出不含此列。
|
|
12
|
+
* 2. 模型 Token 总量排行 + 占比(行点击 = 聚焦该模型并切到按模型视角);
|
|
6
13
|
* 3. Token 结构 KPI(缓存命中率 / reasoning 占比 / 输入:输出比 / 峰值日)+ 显式缓存写入;
|
|
7
14
|
* 4. 工具调用排行(byTool 计次;token 无法按工具归因)。
|
|
8
15
|
*/
|
|
9
16
|
import type { UsageBillingKey } from './locales.ts';
|
|
17
|
+
import type { TrendSeriesModel } from './TrendChart.tsx';
|
|
10
18
|
import type { UsageStats } from './UsageBilling.tsx';
|
|
19
|
+
/** 每日 token 堆叠图元(按结构视角)。 */
|
|
20
|
+
interface DailyBucket {
|
|
21
|
+
date: string;
|
|
22
|
+
miss: number;
|
|
23
|
+
hit: number;
|
|
24
|
+
output: number;
|
|
25
|
+
reasoning: number;
|
|
26
|
+
}
|
|
27
|
+
/** 按模型视角下某模型某日的 token 明细(`byDayModels` 无 reasoning 列)。 */
|
|
28
|
+
interface ModelDayCell {
|
|
29
|
+
hit: number;
|
|
30
|
+
miss: number;
|
|
31
|
+
output: number;
|
|
32
|
+
/** 命中 + 未命中 + 输出(= 模型总 Token 口径)。 */
|
|
33
|
+
total: number;
|
|
34
|
+
}
|
|
35
|
+
/** 按模型视角的一天:各模型段 + 当日合计。 */
|
|
36
|
+
interface DayModelsRow {
|
|
37
|
+
date: string;
|
|
38
|
+
models: Record<string, ModelDayCell>;
|
|
39
|
+
total: number;
|
|
40
|
+
}
|
|
41
|
+
/** 模型 token 行。 */
|
|
42
|
+
interface ModelTokenRow {
|
|
43
|
+
key: string;
|
|
44
|
+
name: string;
|
|
45
|
+
input: number;
|
|
46
|
+
output: number;
|
|
47
|
+
reasoning: number;
|
|
48
|
+
calls: number;
|
|
49
|
+
cacheHit: number;
|
|
50
|
+
cacheMiss: number;
|
|
51
|
+
cacheHitRate: number;
|
|
52
|
+
total: number;
|
|
53
|
+
/** 占总 token 比例(0..1)。 */
|
|
54
|
+
share: number;
|
|
55
|
+
}
|
|
56
|
+
/** 导出全量 JSON 文档:按日结构 + 模型排行 + 按日×模型明细 + 总量(无 reasoning 列)。 */
|
|
57
|
+
export declare function tokenDailyJson(days: readonly DailyBucket[], models: readonly ModelTokenRow[], dayModels: readonly DayModelsRow[], total: UsageStats['total']): string;
|
|
11
58
|
/**
|
|
12
59
|
* Token 洞察面板。
|
|
13
|
-
* @param props.stats - usage-stats 文档(byDay/byModel/total)。
|
|
60
|
+
* @param props.stats - usage-stats 文档(byDay/byModel/byDayModels/total)。
|
|
14
61
|
* @param props.trendDays - 每日 token 窗口(7/30 天)。
|
|
15
62
|
* @param props.onTrendDays - 切换趋势窗口。
|
|
63
|
+
* @param props.models - 趋势页同款模型图例(key/name/色):按模型视角的分色来源;缺省用兜底灰。
|
|
16
64
|
*/
|
|
17
65
|
export declare function TokenPanel(props: {
|
|
18
66
|
stats: UsageStats;
|
|
19
67
|
trendDays: 7 | 30;
|
|
20
68
|
onTrendDays: (d: 7 | 30) => void;
|
|
69
|
+
models?: readonly TrendSeriesModel[];
|
|
70
|
+
/** 金额格式化(跟随仪表盘币种切换):费用构成区块展示用。 */
|
|
71
|
+
money: (cny: number) => string;
|
|
21
72
|
t: (key: UsageBillingKey) => string;
|
|
22
73
|
}): React.ReactNode;
|
|
74
|
+
export {};
|
|
23
75
|
//# sourceMappingURL=TokenPanel.d.ts.map
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*(billing.dashboard.decor)并注册计费指标服务(ctx.billingMetrics),主题
|
|
11
11
|
* 插件主动注入装饰视觉、消费费用数据——billing 不反向依赖任何主题包。
|
|
12
12
|
*/
|
|
13
|
-
import type {
|
|
13
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
14
14
|
import { type UsageBillingKey } from './locales.ts';
|
|
15
15
|
import { type BillingMetricsService } from './billing-service.ts';
|
|
16
16
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
@@ -45,11 +45,18 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
45
45
|
usageBilling: UsageBillingKey;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
/** Required services for the usage billing surface.
|
|
48
|
+
/** Required services for the usage billing surface.
|
|
49
|
+
*
|
|
50
|
+
* `remote.llm` is deliberately NOT injected: the LLM remote namespace only
|
|
51
|
+
* exists on 0.1.2-alpha.1 hosts, and a pending injection blocks the whole
|
|
52
|
+
* web boot on older hosts. `checkModels` probes `ctx.remote.llm` defensively
|
|
53
|
+
* instead — on hosts without it the model health check degrades to the
|
|
54
|
+
* static catalog result (the surrounding try/catch already swallows the
|
|
55
|
+
* undefined access). */
|
|
49
56
|
export declare const inject: string[];
|
|
50
57
|
/**
|
|
51
58
|
* Client plugin body: the UsageBilling entry in the sidebar footer.
|
|
52
59
|
* @param ctx - client root context.
|
|
53
60
|
*/
|
|
54
|
-
export declare function apply(ctx:
|
|
61
|
+
export declare function apply(ctx: Context): void;
|
|
55
62
|
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* store 引擎持久化到 localStorage(persist key 即存储身份),重启后保留。
|
|
6
6
|
* 宿主 Config 的 monthlyBudget 仅作为金额未设置时的默认值,用户输入优先。
|
|
7
7
|
*/
|
|
8
|
-
import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-
|
|
8
|
+
import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
|
|
9
9
|
/** 预算偏好状态。 */
|
|
10
10
|
export interface BudgetPrefsState {
|
|
11
11
|
/** 预算条开关:关 = 只显示标题行与开关,不显示进度。 */
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* 可选:跨 tab 只保留一个提醒 leader(Web Locks 优先,降级 localStorage 租约),
|
|
6
6
|
* 避免多窗口同时弹同一条。配置持久化在 localStorage(默认关闭,用户在面板设置开启)。
|
|
7
7
|
*/
|
|
8
|
-
import type { SessionListState } from '@deepseek-ai/dsh-
|
|
9
|
-
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-
|
|
8
|
+
import type { SessionListState } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
9
|
+
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store';
|
|
10
10
|
/** 配置持久化 key:开启/关闭 + 提醒持续模式(0=常驻,其余=秒后自动关)。 */
|
|
11
11
|
export declare const COMPLETION_NOTIFY_KEY = "dsh-billing-completion-notify-v1";
|
|
12
12
|
export interface CompletionNotifyConfig {
|
|
@@ -6,17 +6,16 @@
|
|
|
6
6
|
* composer card, same posture as ui-conversation's own StatsLine), so it stays
|
|
7
7
|
* visible while working without opening the full dashboard. Data comes from the
|
|
8
8
|
* same `/api/billing/usage-stats` endpoint the dashboard polls; the bar reads
|
|
9
|
-
* the current session id
|
|
10
|
-
* `
|
|
11
|
-
*
|
|
9
|
+
* the current session id from the session-scope standard kit and matches
|
|
10
|
+
* `bySession` (session total) and `byTurn` (latest turn cost). Rendering is a
|
|
11
|
+
* pure function of props and polled data, never a side effect.
|
|
12
12
|
*
|
|
13
13
|
* The bar also carries two ambient signals: the current peak/off-peak pricing
|
|
14
14
|
* tier with a switch countdown (DeepSeek time-of-day pricing), and quota chips
|
|
15
15
|
* for subscription plans running low (≤20% remaining), so cost pressure is
|
|
16
16
|
* visible without opening the dashboard.
|
|
17
17
|
*/
|
|
18
|
-
import type {
|
|
19
|
-
import type { ConversationSnapshot } from '@deepseek-ai/dsh-client-runtime/client';
|
|
18
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
20
19
|
import type { UsageBillingKey } from './locales.ts';
|
|
21
20
|
/** The usage-stats shape the composer bar needs (a thin slice, not the whole doc). */
|
|
22
21
|
export interface LiveStats {
|
|
@@ -67,15 +66,26 @@ export declare function lowQuotaChips(quotas: readonly QuotaSlice[], threshold?:
|
|
|
67
66
|
kind: string;
|
|
68
67
|
pct: number;
|
|
69
68
|
}[];
|
|
70
|
-
/** Props: the session
|
|
69
|
+
/** Props: the framework's session identity plus the owning dock's locale seat. */
|
|
71
70
|
export interface LiveCostBarProps {
|
|
72
|
-
|
|
71
|
+
/** Current Session identity supplied by the session-scope standard kit. */
|
|
72
|
+
sessionId: SessionId;
|
|
73
73
|
/** The owning dock's locale seat (bound to the billing NS). */
|
|
74
74
|
t: (key: UsageBillingKey) => string;
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Render the live cost ticker for the current session.
|
|
78
|
-
* @param props - framework session
|
|
78
|
+
* @param props - framework session identity and locale.
|
|
79
79
|
*/
|
|
80
|
-
export declare function LiveCostBar({
|
|
80
|
+
export declare function LiveCostBar({ sessionId, t }: LiveCostBarProps): React.ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* Render the compact inline chip for the composer tool row (position
|
|
83
|
+
* 「模型选择前」). Occupies a fixed minimal footprint — tier glyph + session
|
|
84
|
+
* spend — so it never crowds the model picker; the full breakdown (switch
|
|
85
|
+
* countdown, turn cost, quota alerts) rides the host Tooltip primitive (the
|
|
86
|
+
* native title never renders in the webview), and a low quota tints the chip
|
|
87
|
+
* amber/red instead of growing it.
|
|
88
|
+
* @param props - framework session identity and locale.
|
|
89
|
+
*/
|
|
90
|
+
export declare function LiveCostChip({ sessionId, t }: LiveCostBarProps): React.ReactNode;
|
|
81
91
|
//# sourceMappingURL=live-cost.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'title' | '
|
|
2
|
+
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'liveTurn' | 'liveSession' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'trendEmpty' | 'budget' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'channelUnknown' | 'actual' | 'pricing' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'band' | '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' | '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' | 'subscriptionsStale' | 'staleLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceOffPeak' | 'userPriceNormal' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemoveSelected' | 'userPriceSelect' | 'sessionStaleBadge' | 'sessionUntitled' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabPricing' | 'tabSettings' | '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' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'perfAll' | 'perfChartEmpty' | 'heatmapYear' | 'heatmapMonth' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenCacheHitRate' | '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';
|
|
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>;
|
|
@@ -26,6 +26,12 @@ import type { LivePricing } from '../pricing-shared.ts';
|
|
|
26
26
|
* live rate arrives the built-in value stays in force.
|
|
27
27
|
*/
|
|
28
28
|
export declare const USD_TO_CNY = 6.79;
|
|
29
|
+
/**
|
|
30
|
+
* 注入用户自定义模型别名(node 半区在插件启动时调用一次)。纯内存状态:
|
|
31
|
+
* 聚合折叠与客户端渲染共用同一份(两侧一致性由同一注入点保证)。
|
|
32
|
+
* @param aliases - `model id → 目录键` 映射;undefined/空 = 清除,回退内置表。
|
|
33
|
+
*/
|
|
34
|
+
export declare function applyUserModelAliases(aliases: Readonly<Record<string, string>> | undefined): void;
|
|
29
35
|
/**
|
|
30
36
|
* 用户自定义单价(设置面板录入,localStorage 持久化):覆盖内置/models.dev/
|
|
31
37
|
* dsh-spend 的全部价格来源,用于新模型上线目录未跟、或厂商未公布按量价的场景。
|
|
@@ -41,6 +47,12 @@ export interface UserPrice {
|
|
|
41
47
|
output: number;
|
|
42
48
|
/** 计价币种;缺省 CNY。 */
|
|
43
49
|
currency?: 'CNY' | 'USD';
|
|
50
|
+
/** 低谷档三桶(元或美元 / 每百万 token);缺省 = 平档(峰谷同价)。 */
|
|
51
|
+
offPeak?: {
|
|
52
|
+
input: number;
|
|
53
|
+
cacheHit: number;
|
|
54
|
+
output: number;
|
|
55
|
+
};
|
|
44
56
|
}
|
|
45
57
|
/** 一条用户自定义价:绑定「模型(计费目录键)+ 可选来源(中转站 origin)」。
|
|
46
58
|
* origin 缺省 = 该模型的默认价;带 origin = 仅该中转站的同名模型用此价。 */
|
|
@@ -50,6 +62,22 @@ export interface UserPriceEntry extends UserPrice {
|
|
|
50
62
|
/** 绑定来源(中转站 origin,如 `https://api.my-relay.com`);缺省 = 默认价。 */
|
|
51
63
|
origin?: string;
|
|
52
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* 中转站 origin 宽松匹配:双方规范化到 `protocol://host[:port]` 后比较。
|
|
67
|
+
* 宿主侧站点桶的 origin 来自 `new URL(baseURL).origin`,用户手填的来源常缺
|
|
68
|
+
* 协议、带路径或尾斜杠——精确全等会让自定义价静默失效(issue #18)。
|
|
69
|
+
* 规范化失败(无法解析成 URL)时回退小写去尾斜杠的字面比较。
|
|
70
|
+
* @param a - 用户录入的来源(可缺协议/带路径)。
|
|
71
|
+
* @param b - 宿主站点桶的 origin(`new URL().origin` 形态)。
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* 把用户手填的中转站来源规范化为 `protocol://host[:port]` 形态:缺协议补
|
|
75
|
+
* `https://`、带路径取 origin。无法解析时回退小写去尾斜杠的字面值。
|
|
76
|
+
* 与 {@link originsMatch} 的比较口径一致——保存前规范化一次,匹配时双向兜底。
|
|
77
|
+
* @param raw - 用户录入的来源(可缺协议/带路径)。
|
|
78
|
+
*/
|
|
79
|
+
export declare function normalizeOriginInput(raw: string): string;
|
|
80
|
+
export declare function originsMatch(a: string, b: string): boolean;
|
|
53
81
|
/**
|
|
54
82
|
* 注入用户自定义单价列表。每条含模型目录键 + 可选来源(origin)。空数组 = 清除全部
|
|
55
83
|
* 自定义价,回退内置目录。
|
|
@@ -65,6 +93,20 @@ export declare function getUserPrices(): Readonly<UserPriceEntry[]> | undefined;
|
|
|
65
93
|
* @param origin - 调用来源(中转站 origin);缺省仅查默认价。
|
|
66
94
|
*/
|
|
67
95
|
export declare function userPriceOf(key: string, origin?: string): UserPrice | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* 查一个模型(可选来源)的完整用户价条目(含 origin 绑定信息)。
|
|
98
|
+
* 匹配优先级:origin 宽松精确命中(模型×来源)→ 无来源默认价。
|
|
99
|
+
* @param key - 计费目录键。
|
|
100
|
+
* @param origin - 调用来源(中转站 origin);缺省仅查默认价。
|
|
101
|
+
*/
|
|
102
|
+
export declare function userPriceEntryOf(key: string, origin?: string): UserPriceEntry | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* 查一个模型的「带来源」用户价条目(无视来源值,取第一条命中模型名的
|
|
105
|
+
* 带 origin 条目)。供 recost 在三维站点数据缺失时兜底:用户填了来源价
|
|
106
|
+
* 就按它重估,而不是静默回退宿主原价(issue #18)。
|
|
107
|
+
* @param key - 计费目录键。
|
|
108
|
+
*/
|
|
109
|
+
export declare function userOriginPriceEntryOf(key: string): UserPriceEntry | undefined;
|
|
68
110
|
/**
|
|
69
111
|
* Apply the node half's live pricing snapshot. Absent fields keep the
|
|
70
112
|
* built-in catalog and rate; callers never fabricate values.
|
|
@@ -281,14 +323,6 @@ export declare const MODEL_KEY_ALIASES: Readonly<Record<string, string>>;
|
|
|
281
323
|
* @returns 归一化键(字母数字小写串)。
|
|
282
324
|
*/
|
|
283
325
|
export declare function canonModelId(id: string): string;
|
|
284
|
-
/**
|
|
285
|
-
* 解析真实日志模型 id → 计费目录键。先精确别名映射(既有行为);未命中时做
|
|
286
|
-
* 归一化匹配(忽略大小写/分隔符/括号附注),命中内置目录 / 别名目标 / 兜底键 /
|
|
287
|
-
* models.dev 补充键即返回其真实键;完全未知时保持原样(回退 other,不计费)。
|
|
288
|
-
* 供聚合层折叠与客户端渲染共用,两侧一致。
|
|
289
|
-
* @param id - 真实模型 id(日志里出现的形式)。
|
|
290
|
-
* @returns 计费目录键。
|
|
291
|
-
*/
|
|
292
326
|
export declare function resolveCatalogKey(id: string): string;
|
|
293
327
|
/** Lookup a model by its stats key; falls back to the generic `other` entry. */
|
|
294
328
|
export declare function modelOf(key: string): ModelEntry;
|
|
@@ -341,6 +375,24 @@ export declare function resolveToken(name: string): string;
|
|
|
341
375
|
* @returns the estimated cost in CNY.
|
|
342
376
|
*/
|
|
343
377
|
export declare function computeCost(entry: ModelEntry, buckets: TokenUsageBuckets, peakShare?: number, nowMs?: number): number;
|
|
378
|
+
/**
|
|
379
|
+
* 按调用时刻精确判定高峰/空闲档并计价(P0-1:替代固定比例混合)。时刻未知
|
|
380
|
+
* (null/NaN,理论不发生在真实事件流)时回退 {@link DEFAULT_PEAK_SHARE} 混合,
|
|
381
|
+
* 保持旧语义不低估。平档模型(无 offPeak)两个时段同价。限时促销与峰谷档
|
|
382
|
+
* 同口径:按事件时刻判定该笔流量当时享受的单价。
|
|
383
|
+
*
|
|
384
|
+
* 历史正确性(按变更节点分段适用规则,不统一套现行价重算历史):
|
|
385
|
+
* - 早于 {@link PEAK_ERA_START_MS} 的事件按当时官方基础价
|
|
386
|
+
* ({@link LEGACY_DEEPSEEK_BANDS})计费;
|
|
387
|
+
* - 峰谷开闸至 {@link WEEKEND_OFFPEAK_START_MS} 之间按 v1 规则(周末不豁免,
|
|
388
|
+
* 周六日 9-12 / 14-18 计峰);
|
|
389
|
+
* - 周末全谷分界起按现行规则({@link tierAt},周六日全天低谷)。
|
|
390
|
+
* @param entry - the catalog entry whose prices apply.
|
|
391
|
+
* @param buckets - token usage counts.
|
|
392
|
+
* @param timeMs - the call's wall-clock time (epoch ms); null falls back to the peak-share mix.
|
|
393
|
+
* @param peakShare - fallback mix used only when `timeMs` is missing.
|
|
394
|
+
* @returns the estimated cost in CNY(USD 计价模型已按当前汇率折算)。
|
|
395
|
+
*/
|
|
344
396
|
export declare function computeCostAt(entry: ModelEntry, buckets: TokenUsageBuckets, timeMs: number | null | undefined, peakShare?: number): number;
|
|
345
397
|
/** 人民币 → 美元(显示换算用):用当前生效汇率(实时优先,缺失回退内置),
|
|
346
398
|
* 与计价链路的 `currentRate()` 同口径,避免实时汇率生效时 USD 显示与计价不一致。 */
|
|
@@ -17,5 +17,12 @@ type ProviderLang = 'zh' | 'en';
|
|
|
17
17
|
export declare function localizeProviderName(name: string, lang: ProviderLang): string;
|
|
18
18
|
/** 判断一个厂商显示名是否包含中文(用于测试/守卫:保证映射覆盖完整)。 */
|
|
19
19
|
export declare function hasCjk(name: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* 站点桶 key(`site:<origin>` / `direct:<provider>` / `unknown`)→ 通道显示名。
|
|
22
|
+
* @param siteKey - 聚合文档 bySite 的桶 key。
|
|
23
|
+
* @param lang - 显示语言;zh(缺省)用内置中文名,en 走英文章表。
|
|
24
|
+
* @returns 未知路由桶返回 undefined(渲染层用 locale 文案兜底)。
|
|
25
|
+
*/
|
|
26
|
+
export declare function channelDisplayName(siteKey: string, lang?: ProviderLang): string | undefined;
|
|
20
27
|
export {};
|
|
21
28
|
//# sourceMappingURL=provider-display.d.ts.map
|