@rayadesu/dsh-llm-billing 0.3.16 → 0.3.18
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.i18n.yaml +2 -2
- package/README.md +19 -8
- package/README.zh.md +20 -9
- package/icon.svg +14 -0
- package/lib/index.js +749 -416
- package/lib/typert.host.js +17 -7
- package/lib/typert.remote-client.js +17 -7
- package/lib/types/balance.d.ts +10 -0
- package/lib/types/balance.js +79 -13
- package/lib/types/beijing-time.d.ts +52 -0
- package/lib/types/beijing-time.js +88 -0
- package/lib/types/billing.d.ts +27 -388
- package/lib/types/billing.js +28 -627
- package/lib/types/cache.d.ts +110 -0
- package/lib/types/cache.js +155 -0
- package/lib/types/fold.d.ts +93 -0
- package/lib/types/fold.js +188 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/persistence.d.ts +113 -0
- package/lib/types/persistence.js +63 -0
- package/lib/types/pricing-table.d.ts +43 -0
- package/lib/types/pricing-table.js +118 -0
- package/lib/types/pricing.d.ts +203 -0
- package/lib/types/pricing.js +203 -0
- package/lib/types/projection.js +14 -0
- package/lib/types/session-lineage.d.ts +70 -0
- package/lib/types/session-lineage.js +99 -0
- package/lib/types/spend.d.ts +58 -0
- package/lib/types/spend.js +190 -0
- package/lib/types/today-spend.d.ts +27 -233
- package/lib/types/today-spend.js +73 -254
- package/lib/types/types.d.ts +28 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +21 -17
package/lib/types/billing.d.ts
CHANGED
|
@@ -1,198 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DeepSeek billing: the
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* a key.
|
|
2
|
+
* DeepSeek billing aggregation: the session/turn/today spend computations
|
|
3
|
+
* over the pricing engine (`pricing.ts`) and the per-event fold state machine
|
|
4
|
+
* (`fold.ts`). Pure functions over session events, so the whole spend is
|
|
5
|
+
* testable without a key and the Remote gateway stays transport-free.
|
|
6
6
|
*
|
|
7
|
-
* The
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* through the same primitives, so a pricing-table change cannot drift one path
|
|
12
|
-
* from the others.
|
|
7
|
+
* The fold in {@link BillingFolder} / {@link applyBillingEvent} (see `fold.ts`)
|
|
8
|
+
* and the per-event pricing in `pricing.ts` are the single source of truth the
|
|
9
|
+
* events-scan paths, the session-projection unit, and the scanner all price
|
|
10
|
+
* through, so a pricing-table change cannot drift one path from the others.
|
|
13
11
|
* @module @rayadesu/dsh-llm-billing/billing
|
|
14
12
|
*/
|
|
15
|
-
import type { TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
16
13
|
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
17
14
|
import type { DeepSeekSessionSpend, DeepSeekSessionTurnSpends, DeepSeekTodaySpend, DeepSeekTurnSpend } from './types.ts';
|
|
18
|
-
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
cacheMissInput: number;
|
|
24
|
-
/** 1M output tokens. */
|
|
25
|
-
output: number;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* One published peak/off-peak rate revision of a model: the price pair plus the
|
|
29
|
-
* instant it took effect. A provider re-prices a series without repricing its
|
|
30
|
-
* history, so the table keeps every revision and prices each sample at the
|
|
31
|
-
* rates of the sample's own timestamp.
|
|
32
|
-
*/
|
|
33
|
-
export interface DeepSeekRateRevision {
|
|
34
|
-
/** Price during peak hours. */
|
|
35
|
-
peak: DeepSeekTokenPrice;
|
|
36
|
-
/** Price during off-peak hours. */
|
|
37
|
-
offPeak: DeepSeekTokenPrice;
|
|
38
|
-
/**
|
|
39
|
-
* Inclusive epoch ms this revision takes effect: it prices every sample at or
|
|
40
|
-
* after that instant. `undefined` on a model's base revision, which also
|
|
41
|
-
* covers every earlier instant.
|
|
42
|
-
*/
|
|
43
|
-
effectiveFrom?: number;
|
|
44
|
-
}
|
|
45
|
-
/** Resolved pricing for one model: its published rate revisions, oldest first. */
|
|
46
|
-
export interface DeepSeekModelPricing {
|
|
47
|
-
/** Peak-hour price of the newest revision (the rates in effect now). */
|
|
48
|
-
peak: DeepSeekTokenPrice;
|
|
49
|
-
/** Off-peak price of the newest revision (the rates in effect now). */
|
|
50
|
-
offPeak: DeepSeekTokenPrice;
|
|
51
|
-
/**
|
|
52
|
-
* Every published revision of this model, ascending by `effectiveFrom` (an
|
|
53
|
-
* undated base revision first); always at least one. {@link priceUsage} picks
|
|
54
|
-
* the revision in effect at the priced sample's own timestamp.
|
|
55
|
-
*/
|
|
56
|
-
revisions: readonly DeepSeekRateRevision[];
|
|
57
|
-
}
|
|
58
|
-
/** One model's pricing-table row in configuration form. */
|
|
59
|
-
export interface BillingConfigModel extends DeepSeekRateRevision {
|
|
60
|
-
/** Wire model id. */
|
|
61
|
-
model: string;
|
|
62
|
-
}
|
|
63
|
-
/** One peak-hour window on a 24h Beijing-time clock, applied weekdays only. */
|
|
64
|
-
export interface PeakHourWindow {
|
|
65
|
-
/** Inclusive start hour, `0`–`23`. */
|
|
66
|
-
start: number;
|
|
67
|
-
/** Exclusive end hour, `1`–`24`. */
|
|
68
|
-
end: number;
|
|
69
|
-
}
|
|
70
|
-
/** Optional billing configuration; omission uses the published defaults. */
|
|
71
|
-
export interface BillingConfig {
|
|
72
|
-
/**
|
|
73
|
-
* Peak-hour windows in Beijing time, applied on weekdays (Monday–Friday)
|
|
74
|
-
* only; weekends (Saturday and Sunday) are always off-peak.
|
|
75
|
-
*/
|
|
76
|
-
peakHours?: PeakHourWindow[];
|
|
77
|
-
/**
|
|
78
|
-
* Per-model pricing rows; omission uses the published V4 and MiMo rates.
|
|
79
|
-
* Several rows for one model declare that model's rate history, priced per
|
|
80
|
-
* sample by `effectiveFrom` (see {@link BillingConfigModel}).
|
|
81
|
-
*/
|
|
82
|
-
models?: BillingConfigModel[];
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Published peak-hour windows (Beijing time): 09:00–12:00 and 14:00–18:00,
|
|
86
|
-
* applied on weekdays (Monday–Friday) only — weekends are always off-peak
|
|
87
|
-
* (effective 2026-08-23).
|
|
88
|
-
*/
|
|
89
|
-
export declare const DEFAULT_PEAK_HOURS: readonly PeakHourWindow[];
|
|
90
|
-
/**
|
|
91
|
-
* Inclusive epoch ms of the published V4 Flash series re-pricing:
|
|
92
|
-
* 2026-09-10 12:00 Beijing time (UTC+8, no DST) = 04:00 UTC. Samples before
|
|
93
|
-
* this instant keep the base rates; samples at or after it bill at the second
|
|
94
|
-
* revision.
|
|
95
|
-
*/
|
|
96
|
-
export declare const FLASH_SERIES_RATE_CHANGE_AT: number;
|
|
97
|
-
/**
|
|
98
|
-
* Inclusive epoch ms of the announced V4 Pro route switch: 2026-09-14 12:00
|
|
99
|
-
* Beijing time (UTC+8, no DST) = 04:00 UTC. From that instant the V4 Pro route
|
|
100
|
-
* is served by V4.1 Flash and billed at the V4.1 Flash rates.
|
|
101
|
-
*/
|
|
102
|
-
export declare const V4_PRO_ROUTE_SWITCH_AT: number;
|
|
103
|
-
/**
|
|
104
|
-
* Official peak/off-peak rates (CNY per 1M tokens) per model, as dated
|
|
105
|
-
* revisions. Base rows are the schedule effective 2026-08-17; the V4 Flash
|
|
106
|
-
* series (V4.1 Flash, V4 Flash, V4 Flash Vision Exp) carries the second
|
|
107
|
-
* revision effective 2026-09-10 12:00 Beijing, and the V4 Pro row the V4.1
|
|
108
|
-
* Flash rates from its announced route switch (2026-09-14 12:00 Beijing) —
|
|
109
|
-
* the MiMo series (V2.5, and V2.6 which kept V2.5's pricing) is untouched by
|
|
110
|
-
* either adjustment. Rows sharing a model are that model's rate history.
|
|
111
|
-
*/
|
|
112
|
-
export declare const DEFAULT_MODEL_PRICING: readonly BillingConfigModel[];
|
|
113
|
-
/** Resolved billing configuration: a pricing table plus peak-hour windows. */
|
|
114
|
-
export interface ResolvedBilling {
|
|
115
|
-
peakHours: readonly {
|
|
116
|
-
start: number;
|
|
117
|
-
end: number;
|
|
118
|
-
}[];
|
|
119
|
-
models: ReadonlyMap<string, DeepSeekModelPricing>;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Resolve optional configuration to a pricing table, defaulting omitted or
|
|
123
|
-
* empty rows to the published rates. Schemastery materializes an absent
|
|
124
|
-
* `z.array` as `[]` rather than `undefined`, so emptiness — not just absence —
|
|
125
|
-
* selects the defaults. Explicit non-empty rows override the same model; a
|
|
126
|
-
* supplied non-empty `models` list is authoritative.
|
|
127
|
-
*
|
|
128
|
-
* Rows sharing a model are that model's rate revisions, kept in ascending
|
|
129
|
-
* `effectiveFrom` order (an undated base revision first). Two rows declaring
|
|
130
|
-
* the same effective instant are one revision and the later row wins — the
|
|
131
|
-
* historical override rule — so re-declaring a model can neither duplicate a
|
|
132
|
-
* revision nor install a second undated base.
|
|
133
|
-
* @param config - optional raw billing configuration.
|
|
134
|
-
* @returns the resolved table (per model: its revisions plus the newest rates) and peak-hour windows.
|
|
135
|
-
*/
|
|
136
|
-
export declare function resolveBilling(config: BillingConfig | undefined): ResolvedBilling;
|
|
137
|
-
/** One shifted-timestamp view of a Beijing (UTC+8, no DST) instant. */
|
|
138
|
-
export interface BeijingParts {
|
|
139
|
-
/**
|
|
140
|
-
* The instant in epoch milliseconds. Pricing needs it back to resolve the
|
|
141
|
-
* rate revision in effect at the sample's own timestamp (see
|
|
142
|
-
* {@link ratesAt}), so the view carries it instead of a second parse.
|
|
143
|
-
*/
|
|
144
|
-
time: number;
|
|
145
|
-
/** Beijing hour, `0`–`23`. */
|
|
146
|
-
hour: number;
|
|
147
|
-
/** Beijing weekday as `getUTCDay()`: `0` is Sunday, `6` is Saturday. */
|
|
148
|
-
weekday: number;
|
|
149
|
-
/** Beijing calendar-day key (`YYYY-MM-DD`). */
|
|
150
|
-
dayKey: string;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Derive the Beijing hour, weekday, and calendar-day key of one timestamp with
|
|
154
|
-
* pure integer arithmetic — every timezone-sensitive read shares this one
|
|
155
|
-
* implementation, so the pieces cannot drift apart. Callers that filter by
|
|
156
|
-
* day and then price the same event reuse the returned view, so each event is
|
|
157
|
-
* parsed exactly once. (The hot fold path runs this per committed event; the
|
|
158
|
-
* previous `Date` + `toISOString().slice()` version allocated a `Date` and a
|
|
159
|
-
* 24-character string per call.)
|
|
160
|
-
* @param time - epoch milliseconds.
|
|
161
|
-
* @throws {RangeError} when `time` is not a finite number.
|
|
162
|
-
*/
|
|
163
|
-
export declare function beijingPartsOf(time: number): BeijingParts;
|
|
164
|
-
/** The Beijing (Asia/Shanghai, UTC+8, no DST) calendar-day key of a timestamp. */
|
|
165
|
-
export declare function beijingDayKey(now: Date): string;
|
|
15
|
+
import type { ResolvedBilling } from './pricing.ts';
|
|
16
|
+
export * from './beijing-time.ts';
|
|
17
|
+
export * from './spend.ts';
|
|
18
|
+
export * from './pricing.ts';
|
|
19
|
+
export * from './fold.ts';
|
|
166
20
|
/**
|
|
167
21
|
* Structural source of a session's durable inherited-prefix boundary. The
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* the persistence `inspect` result as `meta.seedLength`.
|
|
176
|
-
*
|
|
177
|
-
* The reader accepts any of the three shapes and prefers the newer,
|
|
178
|
-
* exact-count field, so the same plugin code prices correctly on both
|
|
179
|
-
* families of runtime.
|
|
22
|
+
* exact cut moved between DSH runtimes: since 0.1.2-alpha.4,
|
|
23
|
+
* `SessionHeader.seedLength` was removed (the header now carries only
|
|
24
|
+
* `isSeeded`: boolean) and the count moved to `Session.inheritedEventCount` /
|
|
25
|
+
* `SessionHandle.inheritedEventCount`. The reader prefers that exact-count
|
|
26
|
+
* field and otherwise falls back to the older `seedLength` on the durable
|
|
27
|
+
* header, so the same plugin code prices correctly across the live-session
|
|
28
|
+
* and handle surfaces it still meets.
|
|
180
29
|
*/
|
|
181
30
|
export interface ForkBoundarySource {
|
|
182
|
-
/** 0.1.2-alpha.4+: `Session.inheritedEventCount` / `
|
|
31
|
+
/** 0.1.2-alpha.4+: `Session.inheritedEventCount` / `SessionHandle.inheritedEventCount`. */
|
|
183
32
|
readonly inheritedEventCount?: number;
|
|
184
|
-
/** 0.1.1-rc.2
|
|
33
|
+
/** ≤ 0.1.1-rc.2 live-session header: `SessionHeader.seedLength`. */
|
|
185
34
|
readonly seedLength?: number;
|
|
186
|
-
/**
|
|
35
|
+
/** Durable header slice of a live session or opened handle (its `seedLength`). */
|
|
187
36
|
readonly header?: {
|
|
188
37
|
readonly seedLength?: number;
|
|
189
38
|
readonly isSeeded?: boolean;
|
|
190
39
|
};
|
|
191
|
-
/** ≤ 0.1.1-rc.2: the `meta` of a persistence `inspect` result (its `seedLength`). */
|
|
192
|
-
readonly meta?: {
|
|
193
|
-
readonly seedLength?: number;
|
|
194
|
-
readonly isSeeded?: boolean;
|
|
195
|
-
};
|
|
196
40
|
}
|
|
197
41
|
/**
|
|
198
42
|
* The durable inherited-prefix boundary of one session: the number of leading
|
|
@@ -201,222 +45,17 @@ export interface ForkBoundarySource {
|
|
|
201
45
|
* in its session state; every event with `seq < seedLength` is a copy of an
|
|
202
46
|
* event already billed in that source session, so pricing must skip them or
|
|
203
47
|
* the same model output is counted once per copy. Accepts the durable field
|
|
204
|
-
* of
|
|
205
|
-
* @param source - the session,
|
|
206
|
-
*
|
|
48
|
+
* of the live-session and handle surfaces (see {@link ForkBoundarySource}).
|
|
49
|
+
* @param source - the session, header slice, or opened handle carrying the
|
|
50
|
+
* boundary; `undefined` reads as 0.
|
|
207
51
|
* @returns the inherited-prefix length; 0 for an unseeded session.
|
|
208
52
|
*/
|
|
209
53
|
export declare function forkBoundaryOf(source: ForkBoundarySource | undefined): number;
|
|
210
|
-
/** Whether a durable header marks a fork-inherited (seeded) session across
|
|
54
|
+
/** Whether a durable header marks a fork-inherited (seeded) session across the live-session and handle surfaces. */
|
|
211
55
|
export declare function isSeededSession(header: {
|
|
212
56
|
readonly seedLength?: number;
|
|
213
57
|
readonly isSeeded?: boolean;
|
|
214
58
|
} | undefined): boolean;
|
|
215
|
-
/**
|
|
216
|
-
* Whether a timestamp falls inside any peak-hour window (Beijing time,
|
|
217
|
-
* weekdays Monday–Friday only). Weekends (Saturday and Sunday) are always
|
|
218
|
-
* off-peak, matching the published peak-hours rule.
|
|
219
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
220
|
-
* @param now - the moment to classify.
|
|
221
|
-
* @returns true during a weekday peak hour.
|
|
222
|
-
*/
|
|
223
|
-
export declare function isPeak(billing: ResolvedBilling, now: Date): boolean;
|
|
224
|
-
/**
|
|
225
|
-
* One priced billed event's contribution: the model row plus the Beijing
|
|
226
|
-
* calendar day its timestamp falls on. `undefined` when the event carries no
|
|
227
|
-
* priced usage (not an `assistant/message`, no usage report, or a model
|
|
228
|
-
* without a pricing row).
|
|
229
|
-
*/
|
|
230
|
-
export interface BillingEventContribution {
|
|
231
|
-
/** Beijing-time calendar-day key of the event's timestamp. */
|
|
232
|
-
dayKey: string;
|
|
233
|
-
/** Wire model id, e.g. `deepseek-v4-flash`. */
|
|
234
|
-
model: string;
|
|
235
|
-
/** Selector label for the model. */
|
|
236
|
-
displayName: string;
|
|
237
|
-
/** Billed cost in CNY (peak plus off-peak portions). */
|
|
238
|
-
cost: number;
|
|
239
|
-
/** Cost portion billed at peak rates. */
|
|
240
|
-
peakCost: number;
|
|
241
|
-
/** Cost portion billed at off-peak rates. */
|
|
242
|
-
offPeakCost: number;
|
|
243
|
-
/** Cache-hit input tokens billed at the hit rate. */
|
|
244
|
-
cacheHitInputTokens: number;
|
|
245
|
-
/** Cache-miss input tokens (uncached input plus cache writes), billed at the miss rate. */
|
|
246
|
-
cacheMissInputTokens: number;
|
|
247
|
-
/** Output tokens (reasoning included), billed at the output rate. */
|
|
248
|
-
outputTokens: number;
|
|
249
|
-
/** Billed cost of cache-hit input tokens in CNY. */
|
|
250
|
-
cacheHitInputCost: number;
|
|
251
|
-
/** Billed cost of cache-miss input tokens (uncached input plus cache writes) in CNY. */
|
|
252
|
-
cacheMissInputCost: number;
|
|
253
|
-
/** Billed cost of output tokens (reasoning included) in CNY. */
|
|
254
|
-
outputCost: number;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Price one event at the official per-model rates, applying the peak/off-peak
|
|
258
|
-
* table by its Beijing-time hour and weekday (peak windows apply Monday–Friday
|
|
259
|
-
* only; weekends are off-peak) and the rate revision in effect at its own
|
|
260
|
-
* timestamp. Each `assistant/message` event with usage
|
|
261
|
-
* contributes cache-hit input, cache-miss input (uncached input plus cache
|
|
262
|
-
* writes), and output (reasoning included) tokens at the rate of its own
|
|
263
|
-
* timestamp; a model with usage but no pricing row contributes nothing.
|
|
264
|
-
* @param event - the event to price.
|
|
265
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
266
|
-
* @param names - model id → display label.
|
|
267
|
-
* @returns the priced contribution, or `undefined` when the event has no priced usage.
|
|
268
|
-
*/
|
|
269
|
-
export declare function priceEvent(event: SessionEvent, billing: ResolvedBilling, names: ReadonlyMap<string, string>): BillingEventContribution | undefined;
|
|
270
|
-
/**
|
|
271
|
-
* Price one event at the official per-model rates using a precomputed
|
|
272
|
-
* Beijing-time view — the day-filtering and pricing of one event share a
|
|
273
|
-
* single timezone parse (see {@link beijingPartsOf}). Semantics are identical
|
|
274
|
-
* to {@link priceEvent}.
|
|
275
|
-
* @param parts - the event's Beijing-time view.
|
|
276
|
-
* @param event - the event to price.
|
|
277
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
278
|
-
* @param names - model id → display label.
|
|
279
|
-
* @returns the priced contribution, or `undefined` when the event has no priced usage.
|
|
280
|
-
*/
|
|
281
|
-
export declare function priceEventAt(parts: BeijingParts, event: SessionEvent, billing: ResolvedBilling, names: ReadonlyMap<string, string>): BillingEventContribution | undefined;
|
|
282
|
-
/**
|
|
283
|
-
* Price one provider-reported usage sample for one model at the rates of the
|
|
284
|
-
* sample's own Beijing-time hour and weekday — the peak or off-peak price of
|
|
285
|
-
* the rate revision in effect at the sample's own timestamp (a re-priced series
|
|
286
|
-
* bills its history at the rates that applied then). `undefined` when the model
|
|
287
|
-
* has no pricing row.
|
|
288
|
-
* @param parts - the sample's Beijing-time view.
|
|
289
|
-
* @param usage - the reported token buckets.
|
|
290
|
-
* @param model - the wire model id the sample belongs to.
|
|
291
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
292
|
-
* @param names - model id → display label.
|
|
293
|
-
* @returns the priced contribution, or `undefined` when the model has no rate row.
|
|
294
|
-
*/
|
|
295
|
-
export declare function priceUsage(parts: BeijingParts, usage: TokenUsage, model: string, billing: ResolvedBilling, names: ReadonlyMap<string, string>): BillingEventContribution | undefined;
|
|
296
|
-
/** A spend with no priced usage. */
|
|
297
|
-
export declare function emptyTodaySpend(): DeepSeekTodaySpend;
|
|
298
|
-
/**
|
|
299
|
-
* Mutable model-row accumulator behind every spend fold. Rows keep first-seen
|
|
300
|
-
* model order — the same shape a pure `addEventContribution` chain produces —
|
|
301
|
-
* so the single-pass scan path and the pure public paths cannot diverge. One
|
|
302
|
-
* `Map` lookup per contribution instead of a per-event array copy: the huge
|
|
303
|
-
* event-log folds allocate one row object per model, not one intermediate
|
|
304
|
-
* array per event.
|
|
305
|
-
*/
|
|
306
|
-
export declare class SpendAccumulator {
|
|
307
|
-
private readonly rows;
|
|
308
|
-
private total;
|
|
309
|
-
/** Add one priced contribution. */
|
|
310
|
-
add(priced: BillingEventContribution): void;
|
|
311
|
-
/** The folded spend; the accumulator stays usable afterwards. */
|
|
312
|
-
finish(): DeepSeekTodaySpend;
|
|
313
|
-
}
|
|
314
|
-
/** The additive inverse of one spend (pure): used to replace a priced sample. */
|
|
315
|
-
export declare function negateSpend(spend: DeepSeekTodaySpend): DeepSeekTodaySpend;
|
|
316
|
-
/**
|
|
317
|
-
* Subtract one spend from another (pure). Rows that cancel out completely are
|
|
318
|
-
* dropped so a replaced sample leaves no zero row behind.
|
|
319
|
-
* @param target - the spend to subtract from.
|
|
320
|
-
* @param source - the spend to remove.
|
|
321
|
-
* @returns the difference.
|
|
322
|
-
*/
|
|
323
|
-
export declare function subtractSpend(target: DeepSeekTodaySpend, source: DeepSeekTodaySpend): DeepSeekTodaySpend;
|
|
324
|
-
/**
|
|
325
|
-
* One priced attempt sample kept for same-step replacement: DSH can report the
|
|
326
|
-
* same `(turn, step)` twice (an `assistant/attempt` stream and the
|
|
327
|
-
* `assistant/message` that assembles from it), and a later sample replaces the
|
|
328
|
-
* earlier one instead of adding to it. `llm/retry-started` clears the slot, so
|
|
329
|
-
* a retried attempt adds rather than replaces (both requests were billed).
|
|
330
|
-
*/
|
|
331
|
-
export interface BillingFoldSample {
|
|
332
|
-
/** Turn of the producing attempt. */
|
|
333
|
-
turn: number;
|
|
334
|
-
/** Step of the producing attempt. */
|
|
335
|
-
step: number;
|
|
336
|
-
/** Beijing day of the sample's timestamp. */
|
|
337
|
-
dayKey: string;
|
|
338
|
-
/** The sample's contribution as a one-row spend (subtracted on replacement). */
|
|
339
|
-
spend: DeepSeekTodaySpend;
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Plain-JSON fold state of one session's billed spend: the latest priced day,
|
|
343
|
-
* the whole-session total, the fork boundary, the model of the latest request
|
|
344
|
-
* (needed to price an `assistant/attempt`, which carries no route), and the
|
|
345
|
-
* last sample kept for replacement.
|
|
346
|
-
*/
|
|
347
|
-
export interface BillingFoldState {
|
|
348
|
-
/** Beijing-time calendar-day key of `spend`; `''` for no priced usage. */
|
|
349
|
-
dayKey: string;
|
|
350
|
-
/** The spend of the session's latest priced Beijing day (own events only). */
|
|
351
|
-
spend: DeepSeekTodaySpend;
|
|
352
|
-
/** The spend of the session's OWN events across every day. */
|
|
353
|
-
session: DeepSeekTodaySpend;
|
|
354
|
-
/** Fork-inherited prefix length; events below it belong to the source session. */
|
|
355
|
-
inheritedEventCount: number;
|
|
356
|
-
/** Wire model of the latest `request/header`; `''` before the first one. */
|
|
357
|
-
model: string;
|
|
358
|
-
/** Latest priced attempt sample, for same-step replacement. */
|
|
359
|
-
last: BillingFoldSample | null;
|
|
360
|
-
}
|
|
361
|
-
/** The empty fold state for one fork boundary. */
|
|
362
|
-
export declare function emptyBillingFoldState(inheritedEventCount?: number): BillingFoldState;
|
|
363
|
-
/**
|
|
364
|
-
* Fold one committed event into a session's billed-spend state.
|
|
365
|
-
*
|
|
366
|
-
* Priced samples come from `assistant/message` (its own reported usage, or the
|
|
367
|
-
* stream's last usage chunk) and `assistant/attempt` (the stream's last usage
|
|
368
|
-
* chunk, priced with the model of the latest `request/header`, since an
|
|
369
|
-
* attempt carries no route). A sample for the same `(turn, step)` replaces the
|
|
370
|
-
* previous one; `llm/retry-started` closes the replacement slot so a retried
|
|
371
|
-
* attempt adds. Every other event is inert and returns the same state
|
|
372
|
-
* reference.
|
|
373
|
-
* @param state - the previous fold state.
|
|
374
|
-
* @param event - the committed event.
|
|
375
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
376
|
-
* @param names - model id → display label.
|
|
377
|
-
* @returns the next state (the same reference when nothing was priced).
|
|
378
|
-
*/
|
|
379
|
-
export declare function applyBillingEvent(state: BillingFoldState, event: SessionEvent, billing: ResolvedBilling, names: ReadonlyMap<string, string>): BillingFoldState;
|
|
380
|
-
/**
|
|
381
|
-
* Mutable wrapper over {@link applyBillingEvent} for the pure pricing paths:
|
|
382
|
-
* feed events in order, read the folded spend.
|
|
383
|
-
*/
|
|
384
|
-
export declare class BillingFolder {
|
|
385
|
-
private readonly billing;
|
|
386
|
-
private state;
|
|
387
|
-
/**
|
|
388
|
-
* @param billing - resolved pricing with peak-hour windows.
|
|
389
|
-
* @param catalog - model display rows, in presentation order.
|
|
390
|
-
* @param inheritedEventCount - fork boundary to skip (default 0).
|
|
391
|
-
*/
|
|
392
|
-
constructor(billing: ResolvedBilling, catalog: readonly {
|
|
393
|
-
id: string;
|
|
394
|
-
name: string;
|
|
395
|
-
}[], inheritedEventCount?: number);
|
|
396
|
-
private readonly names;
|
|
397
|
-
/** Fold one event. */
|
|
398
|
-
add(event: SessionEvent): void;
|
|
399
|
-
/** Fold every event, in order. */
|
|
400
|
-
addAll(events: readonly SessionEvent[]): void;
|
|
401
|
-
/** The folded state (live reference; do not mutate). */
|
|
402
|
-
get fold(): BillingFoldState;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Merge one priced event's contribution into an accumulator spend (pure:
|
|
406
|
-
* returns a new spend, never mutates its input).
|
|
407
|
-
* @param spend - the accumulator (per session and day, or across sessions).
|
|
408
|
-
* @param priced - the priced contribution to add.
|
|
409
|
-
* @returns the merged spend.
|
|
410
|
-
*/
|
|
411
|
-
export declare function addEventContribution(spend: DeepSeekTodaySpend, priced: BillingEventContribution): DeepSeekTodaySpend;
|
|
412
|
-
/**
|
|
413
|
-
* Sum two spends (per session and day, or across sessions) into one (pure:
|
|
414
|
-
* returns a new spend, never mutates its inputs).
|
|
415
|
-
* @param target - the accumulator spend.
|
|
416
|
-
* @param source - the spend to add.
|
|
417
|
-
* @returns the summed spend.
|
|
418
|
-
*/
|
|
419
|
-
export declare function mergeTodaySpend(target: DeepSeekTodaySpend, source: DeepSeekTodaySpend): DeepSeekTodaySpend;
|
|
420
59
|
/**
|
|
421
60
|
* Price one session's complete event log at the official per-model rates,
|
|
422
61
|
* with DSH's attempt semantics: every provider-reported sample (an
|