@rayadesu/dsh-client-ui-billing 0.3.11 → 0.3.13
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 +11 -6
- package/README.zh.md +12 -6
- package/lib/client.js +502 -63
- package/lib/types/client/BalanceBadge.d.ts +17 -7
- package/lib/types/client/BalancePanel.d.ts +6 -1
- package/lib/types/client/SpendCard.d.ts +41 -0
- package/lib/types/client/format.d.ts +81 -4
- package/lib/types/client/icons.d.ts +20 -0
- package/lib/types/client/index.d.ts +1 -0
- package/lib/types/client/locales.d.ts +14 -7
- package/lib/types/client/spendBuckets.d.ts +68 -0
- package/lib/types/client/spends.d.ts +22 -0
- package/lib/types/client/useBillingData.d.ts +23 -6
- package/lib/types/client/useCardDialog.d.ts +34 -0
- package/package.json +45 -25
package/lib/client.js
CHANGED
|
@@ -4108,6 +4108,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4108
4108
|
"toppedUp": string()
|
|
4109
4109
|
}))
|
|
4110
4110
|
});
|
|
4111
|
+
const _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_0$schema = intersection(string(), unknown());
|
|
4112
|
+
const _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_1$schema = union([
|
|
4113
|
+
_undefined(),
|
|
4114
|
+
literal(false),
|
|
4115
|
+
literal(true)
|
|
4116
|
+
]);
|
|
4117
|
+
const _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_result$schema = object({
|
|
4118
|
+
"total": number(),
|
|
4119
|
+
"models": array(object({
|
|
4120
|
+
"model": string(),
|
|
4121
|
+
"displayName": string(),
|
|
4122
|
+
"cost": number(),
|
|
4123
|
+
"peakCost": number(),
|
|
4124
|
+
"offPeakCost": number(),
|
|
4125
|
+
"cacheHitInputTokens": number(),
|
|
4126
|
+
"cacheMissInputTokens": number(),
|
|
4127
|
+
"outputTokens": number(),
|
|
4128
|
+
"cacheHitInputCost": number(),
|
|
4129
|
+
"cacheMissInputCost": number(),
|
|
4130
|
+
"outputCost": number()
|
|
4131
|
+
})),
|
|
4132
|
+
"isSubagent": boolean(),
|
|
4133
|
+
"crossedDay": boolean()
|
|
4134
|
+
});
|
|
4111
4135
|
const _rayadesu_dsh_llm_billing_billing_getSessionSpend_parameter_0$schema = intersection(string(), unknown());
|
|
4112
4136
|
const _rayadesu_dsh_llm_billing_billing_getSessionSpend_result$schema = object({
|
|
4113
4137
|
"total": number(),
|
|
@@ -4138,7 +4162,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4138
4162
|
const _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_result$schema = object({ "sessions": array(object({
|
|
4139
4163
|
"sessionId": intersection(string(), unknown()),
|
|
4140
4164
|
"title": union([literal(null), string()]),
|
|
4141
|
-
"total": number()
|
|
4165
|
+
"total": number(),
|
|
4166
|
+
"ownTotal": number()
|
|
4142
4167
|
})) });
|
|
4143
4168
|
const _rayadesu_dsh_llm_billing_billing_getTodaySpend_parameter_0$schema = union([
|
|
4144
4169
|
_undefined(),
|
|
@@ -4181,17 +4206,59 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4181
4206
|
codec: {
|
|
4182
4207
|
mode: "strict",
|
|
4183
4208
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getBalance:force",
|
|
4184
|
-
schema: _rayadesu_dsh_llm_billing_billing_getBalance_parameter_0$schema
|
|
4209
|
+
schema: _rayadesu_dsh_llm_billing_billing_getBalance_parameter_0$schema,
|
|
4210
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getBalance_parameter_0$schema
|
|
4185
4211
|
}
|
|
4186
4212
|
}],
|
|
4187
4213
|
result: {
|
|
4188
4214
|
mode: "strict",
|
|
4189
4215
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekBalance",
|
|
4190
|
-
schema: _rayadesu_dsh_llm_billing_billing_getBalance_result$schema
|
|
4216
|
+
schema: _rayadesu_dsh_llm_billing_billing_getBalance_result$schema,
|
|
4217
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getBalance_result$schema
|
|
4218
|
+
},
|
|
4219
|
+
sourceLocation: {
|
|
4220
|
+
"file": "packages/llm-billing/src/balance.ts",
|
|
4221
|
+
"line": 172,
|
|
4222
|
+
"column": 3
|
|
4223
|
+
}
|
|
4224
|
+
},
|
|
4225
|
+
{
|
|
4226
|
+
id: "@rayadesu/dsh-llm-billing#billing/getDelegatedSpend",
|
|
4227
|
+
service: "billing",
|
|
4228
|
+
namespace: "billing",
|
|
4229
|
+
method: "getDelegatedSpend",
|
|
4230
|
+
invocation: { kind: "direct" },
|
|
4231
|
+
parameters: [{
|
|
4232
|
+
name: "sessionId",
|
|
4233
|
+
wire: "sessionId",
|
|
4234
|
+
source: "json",
|
|
4235
|
+
codec: {
|
|
4236
|
+
mode: "strict",
|
|
4237
|
+
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getDelegatedSpend:sessionId",
|
|
4238
|
+
schema: _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_0$schema,
|
|
4239
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_0$schema
|
|
4240
|
+
}
|
|
4241
|
+
}, {
|
|
4242
|
+
name: "force",
|
|
4243
|
+
wire: "force",
|
|
4244
|
+
source: "json",
|
|
4245
|
+
acceptsUndefined: true,
|
|
4246
|
+
codec: {
|
|
4247
|
+
mode: "strict",
|
|
4248
|
+
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getDelegatedSpend:force",
|
|
4249
|
+
schema: _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_1$schema,
|
|
4250
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_parameter_1$schema
|
|
4251
|
+
}
|
|
4252
|
+
}],
|
|
4253
|
+
result: {
|
|
4254
|
+
mode: "strict",
|
|
4255
|
+
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekDelegatedSpend",
|
|
4256
|
+
schema: _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_result$schema,
|
|
4257
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getDelegatedSpend_result$schema
|
|
4191
4258
|
},
|
|
4192
4259
|
sourceLocation: {
|
|
4193
4260
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4194
|
-
"line":
|
|
4261
|
+
"line": 226,
|
|
4195
4262
|
"column": 3
|
|
4196
4263
|
}
|
|
4197
4264
|
},
|
|
@@ -4208,17 +4275,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4208
4275
|
codec: {
|
|
4209
4276
|
mode: "strict",
|
|
4210
4277
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getSessionSpend:sessionId",
|
|
4211
|
-
schema: _rayadesu_dsh_llm_billing_billing_getSessionSpend_parameter_0$schema
|
|
4278
|
+
schema: _rayadesu_dsh_llm_billing_billing_getSessionSpend_parameter_0$schema,
|
|
4279
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getSessionSpend_parameter_0$schema
|
|
4212
4280
|
}
|
|
4213
4281
|
}],
|
|
4214
4282
|
result: {
|
|
4215
4283
|
mode: "strict",
|
|
4216
4284
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekSessionSpend",
|
|
4217
|
-
schema: _rayadesu_dsh_llm_billing_billing_getSessionSpend_result$schema
|
|
4285
|
+
schema: _rayadesu_dsh_llm_billing_billing_getSessionSpend_result$schema,
|
|
4286
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getSessionSpend_result$schema
|
|
4218
4287
|
},
|
|
4219
4288
|
sourceLocation: {
|
|
4220
4289
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4221
|
-
"line":
|
|
4290
|
+
"line": 183,
|
|
4222
4291
|
"column": 3
|
|
4223
4292
|
}
|
|
4224
4293
|
},
|
|
@@ -4235,17 +4304,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4235
4304
|
codec: {
|
|
4236
4305
|
mode: "strict",
|
|
4237
4306
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getSessionTurnSpends:sessionId",
|
|
4238
|
-
schema: _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_parameter_0$schema
|
|
4307
|
+
schema: _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_parameter_0$schema,
|
|
4308
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_parameter_0$schema
|
|
4239
4309
|
}
|
|
4240
4310
|
}],
|
|
4241
4311
|
result: {
|
|
4242
4312
|
mode: "strict",
|
|
4243
4313
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekSessionTurnSpends",
|
|
4244
|
-
schema: _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_result$schema
|
|
4314
|
+
schema: _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_result$schema,
|
|
4315
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getSessionTurnSpends_result$schema
|
|
4245
4316
|
},
|
|
4246
4317
|
sourceLocation: {
|
|
4247
4318
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4248
|
-
"line":
|
|
4319
|
+
"line": 251,
|
|
4249
4320
|
"column": 3
|
|
4250
4321
|
}
|
|
4251
4322
|
},
|
|
@@ -4263,17 +4334,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4263
4334
|
codec: {
|
|
4264
4335
|
mode: "strict",
|
|
4265
4336
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getTodaySessionsSpend:force",
|
|
4266
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_parameter_0$schema
|
|
4337
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_parameter_0$schema,
|
|
4338
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_parameter_0$schema
|
|
4267
4339
|
}
|
|
4268
4340
|
}],
|
|
4269
4341
|
result: {
|
|
4270
4342
|
mode: "strict",
|
|
4271
4343
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekTodaySessionsSpend",
|
|
4272
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_result$schema
|
|
4344
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_result$schema,
|
|
4345
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTodaySessionsSpend_result$schema
|
|
4273
4346
|
},
|
|
4274
4347
|
sourceLocation: {
|
|
4275
4348
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4276
|
-
"line":
|
|
4349
|
+
"line": 211,
|
|
4277
4350
|
"column": 3
|
|
4278
4351
|
}
|
|
4279
4352
|
},
|
|
@@ -4291,17 +4364,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4291
4364
|
codec: {
|
|
4292
4365
|
mode: "strict",
|
|
4293
4366
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getTodaySpend:force",
|
|
4294
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTodaySpend_parameter_0$schema
|
|
4367
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTodaySpend_parameter_0$schema,
|
|
4368
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTodaySpend_parameter_0$schema
|
|
4295
4369
|
}
|
|
4296
4370
|
}],
|
|
4297
4371
|
result: {
|
|
4298
4372
|
mode: "strict",
|
|
4299
4373
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekTodaySpend",
|
|
4300
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTodaySpend_result$schema
|
|
4374
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTodaySpend_result$schema,
|
|
4375
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTodaySpend_result$schema
|
|
4301
4376
|
},
|
|
4302
4377
|
sourceLocation: {
|
|
4303
4378
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4304
|
-
"line":
|
|
4379
|
+
"line": 196,
|
|
4305
4380
|
"column": 3
|
|
4306
4381
|
}
|
|
4307
4382
|
},
|
|
@@ -4318,7 +4393,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4318
4393
|
codec: {
|
|
4319
4394
|
mode: "strict",
|
|
4320
4395
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getTurnSpend:sessionId",
|
|
4321
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_0$schema
|
|
4396
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_0$schema,
|
|
4397
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_0$schema
|
|
4322
4398
|
}
|
|
4323
4399
|
}, {
|
|
4324
4400
|
name: "messageId",
|
|
@@ -4327,17 +4403,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4327
4403
|
codec: {
|
|
4328
4404
|
mode: "strict",
|
|
4329
4405
|
typeSymbol: "@rayadesu/dsh-llm-billing#billing/getTurnSpend:messageId",
|
|
4330
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_1$schema
|
|
4406
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_1$schema,
|
|
4407
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTurnSpend_parameter_1$schema
|
|
4331
4408
|
}
|
|
4332
4409
|
}],
|
|
4333
4410
|
result: {
|
|
4334
4411
|
mode: "strict",
|
|
4335
4412
|
typeSymbol: "@rayadesu/dsh-llm-billing/types#DeepSeekTurnSpend",
|
|
4336
|
-
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_result$schema
|
|
4413
|
+
schema: _rayadesu_dsh_llm_billing_billing_getTurnSpend_result$schema,
|
|
4414
|
+
create: () => _rayadesu_dsh_llm_billing_billing_getTurnSpend_result$schema
|
|
4337
4415
|
},
|
|
4338
4416
|
sourceLocation: {
|
|
4339
4417
|
"file": "packages/llm-billing/src/balance.ts",
|
|
4340
|
-
"line":
|
|
4418
|
+
"line": 239,
|
|
4341
4419
|
"column": 3
|
|
4342
4420
|
}
|
|
4343
4421
|
}
|
|
@@ -4360,10 +4438,229 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4360
4438
|
total: line.total
|
|
4361
4439
|
};
|
|
4362
4440
|
}
|
|
4363
|
-
/**
|
|
4441
|
+
/**
|
|
4442
|
+
* CNY amount, up to four decimals with trailing zeros trimmed. The balance line's
|
|
4443
|
+
* renderer; spend figures go through {@link formatSpendSignificant} instead.
|
|
4444
|
+
*/
|
|
4364
4445
|
function formatSpend(amount) {
|
|
4365
4446
|
return `¥${amount.toFixed(4).replace(/\.?0+$/, "")}`;
|
|
4366
4447
|
}
|
|
4448
|
+
/**
|
|
4449
|
+
* CNY spend amount at a fixed number of SIGNIFICANT digits (default three),
|
|
4450
|
+
* trailing zeros trimmed, prefixed with `¥` — and never finer than the panel's
|
|
4451
|
+
* own four-decimal resolution.
|
|
4452
|
+
*
|
|
4453
|
+
* Every spend figure the plugin renders goes through this: the day's own amount
|
|
4454
|
+
* and its three bucket costs, this session's spend and the parenthesized today
|
|
4455
|
+
* share after it, the per-model rows and their bucket breakdowns, the ranking
|
|
4456
|
+
* amounts, and the badge's own spend line. Four decimals are noise at these
|
|
4457
|
+
* magnitudes — their last digits move with every request (`¥0.5068` → `¥0.507`)
|
|
4458
|
+
* — while the four-decimal bound keeps a microscopic amount from growing a long
|
|
4459
|
+
* `¥0.00002` string that would widen its column: an amount that rounds to zero
|
|
4460
|
+
* there reads `¥0`. Only the BALANCE line keeps {@link formatSpend}'s plain four
|
|
4461
|
+
* decimals, because remaining credit is a balance, not a spend measurement.
|
|
4462
|
+
* @param amount - the amount to render.
|
|
4463
|
+
* @param digits - significant digits to keep (default 3).
|
|
4464
|
+
* @returns the rendered amount, e.g. `¥9.58`, `¥0.507`, `¥1230`, `¥0`.
|
|
4465
|
+
*/
|
|
4466
|
+
function formatSpendSignificant(amount, digits = 3) {
|
|
4467
|
+
if (!Number.isFinite(amount) || amount === 0) return "¥0";
|
|
4468
|
+
return `¥${Number(Number(amount.toPrecision(digits)).toFixed(4))}`;
|
|
4469
|
+
}
|
|
4470
|
+
/**
|
|
4471
|
+
* A token count in DSH's own compact notation: `517` / `12.2K` / `517K` / `1.2M`.
|
|
4472
|
+
*
|
|
4473
|
+
* Mirrors ui-chat's `formatTokens` (`packages/client/ui-chat/src/client/chat/
|
|
4474
|
+
* token-format.ts`) rule for rule, so one shell never renders the same count two
|
|
4475
|
+
* ways. That rule reads: below 1e3 the plain integer (no digit grouping); below
|
|
4476
|
+
* 1e6 the shared `number.thousand` unit (`{value}K`); otherwise the shared
|
|
4477
|
+
* `number.million` unit (`{value}M`). A scaled value keeps one decimal while it
|
|
4478
|
+
* is below 100 and rounds to a whole number from 100 up (`12.2K`, but `517K`),
|
|
4479
|
+
* and there is no third unit, so 1.2e9 renders as `1200M` — exactly as DSH
|
|
4480
|
+
* renders it. The unit letters are identical in both DSH dictionaries, so they
|
|
4481
|
+
* are literals here rather than a locale lookup into the shared vocabulary.
|
|
4482
|
+
* @param count - the token count to render.
|
|
4483
|
+
* @returns the compact count, without the label's own ` tok` suffix.
|
|
4484
|
+
*/
|
|
4485
|
+
function formatTokens(count) {
|
|
4486
|
+
const scaled = (value) => value >= 100 ? String(Math.round(value)) : String(Math.round(value * 10) / 10);
|
|
4487
|
+
if (count < 1e3) return String(count);
|
|
4488
|
+
if (count < 1e6) return `${scaled(count / 1e3)}K`;
|
|
4489
|
+
return `${scaled(count / 1e6)}M`;
|
|
4490
|
+
}
|
|
4491
|
+
/** Round a cache-read ratio to exact percentage units, with positive ties rounded up. */
|
|
4492
|
+
function roundedPercentUnits(cacheReadTokens, denominator, decimalPlaces) {
|
|
4493
|
+
const scale = (decimalPlaces === 0 ? 1 : 10) * 100;
|
|
4494
|
+
const doubledScale = scale * 2;
|
|
4495
|
+
const denominatorQuotient = Math.floor(denominator / doubledScale);
|
|
4496
|
+
const denominatorRemainder = denominator % doubledScale;
|
|
4497
|
+
let lower = 0;
|
|
4498
|
+
let upper = scale;
|
|
4499
|
+
while (lower < upper) {
|
|
4500
|
+
const candidate = Math.floor((lower + upper + 1) / 2);
|
|
4501
|
+
const factor = candidate * 2 - 1;
|
|
4502
|
+
if (cacheReadTokens >= factor * denominatorQuotient + Math.ceil(factor * denominatorRemainder / doubledScale)) lower = candidate;
|
|
4503
|
+
else upper = candidate - 1;
|
|
4504
|
+
}
|
|
4505
|
+
return lower;
|
|
4506
|
+
}
|
|
4507
|
+
/** Percentage units back to text, dropping a redundant trailing `.0`. */
|
|
4508
|
+
function displayPercentUnits(units, decimalPlaces) {
|
|
4509
|
+
if (decimalPlaces === 0) return String(units);
|
|
4510
|
+
const whole = Math.floor(units / 10);
|
|
4511
|
+
const tenths = units % 10;
|
|
4512
|
+
return tenths === 0 ? String(whole) : `${whole}.${tenths}`;
|
|
4513
|
+
}
|
|
4514
|
+
/**
|
|
4515
|
+
* The cache-hit share of one prompt, in DSH's own percentage rule.
|
|
4516
|
+
*
|
|
4517
|
+
* Mirrors ui-chat's `formatCacheHitPercent`
|
|
4518
|
+
* (`packages/client/ui-chat/src/client/chat/token-format.ts`) rule for rule, so
|
|
4519
|
+
* one shell never prints the same ratio two ways: an integer percentage by
|
|
4520
|
+
* default, and — because a partial hit must never round up to a full one — just
|
|
4521
|
+
* enough extra decimals to stay below 100 when integer rounding would reach it
|
|
4522
|
+
* (`99`, `99.5`, `99.95`, …). The rounding runs in integer arithmetic with
|
|
4523
|
+
* positive ties going up, so it does not ride on binary-float precision.
|
|
4524
|
+
*
|
|
4525
|
+
* The ratio is over PROMPT-side tokens only (cache read over cache read plus
|
|
4526
|
+
* uncached input, the split DSH's own `billedInputTokens` makes); output tokens
|
|
4527
|
+
* never enter the denominator.
|
|
4528
|
+
* @param cacheReadTokens - exact prompt tokens served from cache.
|
|
4529
|
+
* @param promptTokens - exact aggregate prompt-side tokens.
|
|
4530
|
+
* @param decimalPlaces - ordinary-ratio precision; a partial hit that would
|
|
4531
|
+
* round to 100 automatically uses enough additional precision to stay honest.
|
|
4532
|
+
* @returns percentage text without its `%`, or null when there was no prompt input.
|
|
4533
|
+
*/
|
|
4534
|
+
function formatCacheHitPercent(cacheReadTokens, promptTokens, decimalPlaces = 0) {
|
|
4535
|
+
if (promptTokens === 0) return null;
|
|
4536
|
+
const missedInputTokens = promptTokens - cacheReadTokens;
|
|
4537
|
+
if (missedInputTokens === 0) return "100";
|
|
4538
|
+
const roundedUnits = roundedPercentUnits(cacheReadTokens, promptTokens, decimalPlaces);
|
|
4539
|
+
if (roundedUnits < (decimalPlaces === 0 ? 100 : 1e3)) return displayPercentUnits(roundedUnits, decimalPlaces);
|
|
4540
|
+
let distinguishingPlaces = 1;
|
|
4541
|
+
let scaledDoubleGap = missedInputTokens * 200;
|
|
4542
|
+
const denominatorTens = Math.floor(promptTokens / 10);
|
|
4543
|
+
while (scaledDoubleGap <= denominatorTens) {
|
|
4544
|
+
scaledDoubleGap *= 10;
|
|
4545
|
+
distinguishingPlaces += 1;
|
|
4546
|
+
}
|
|
4547
|
+
const denominatorOnes = promptTokens % 10;
|
|
4548
|
+
let roundedLoss = 5;
|
|
4549
|
+
for (let loss = 1; loss < 5; loss += 1) {
|
|
4550
|
+
const factor = loss * 2 + 1;
|
|
4551
|
+
const threshold = factor * denominatorTens + Math.floor(factor * denominatorOnes / 10);
|
|
4552
|
+
if (scaledDoubleGap <= threshold) {
|
|
4553
|
+
roundedLoss = loss;
|
|
4554
|
+
break;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
return `99.${"9".repeat(distinguishingPlaces - 1)}${10 - roundedLoss}`;
|
|
4558
|
+
}
|
|
4559
|
+
/**
|
|
4560
|
+
* The total billed tokens of a priced row: the three buckets summed. Tokens are
|
|
4561
|
+
* already counted per bucket when they were priced, so a cache-hit input token
|
|
4562
|
+
* and an output token are both one token here — the number answers "how many
|
|
4563
|
+
* tokens did this cost", not "how many characters were sent".
|
|
4564
|
+
* @param row - one priced model row.
|
|
4565
|
+
* @returns the row's total token count.
|
|
4566
|
+
*/
|
|
4567
|
+
function rowTokens(row) {
|
|
4568
|
+
return row.cacheHitInputTokens + row.cacheMissInputTokens + row.outputTokens;
|
|
4569
|
+
}
|
|
4570
|
+
//#endregion
|
|
4571
|
+
//#region lib/types/client/spendBuckets.js
|
|
4572
|
+
/**
|
|
4573
|
+
* The composer spend card's three bucket amounts, derived from the pushed
|
|
4574
|
+
* `billingTodaySpend` projection. The host fold already prices every sample
|
|
4575
|
+
* into the three disjoint billing buckets (cache-hit input, cache-miss input —
|
|
4576
|
+
* which includes cache writes, output including reasoning), so the card sums
|
|
4577
|
+
* the session's priced model rows instead of adding a Remote call or a second
|
|
4578
|
+
* fold. Keeping the derivation here (pure, no React) lets the sum and its
|
|
4579
|
+
* float reconciliation be tested on their own.
|
|
4580
|
+
* @module @rayadesu/dsh-client-ui-billing/spendBuckets
|
|
4581
|
+
*/
|
|
4582
|
+
/** Sum one model row's three bucket costs. */
|
|
4583
|
+
function bucketsOf(row) {
|
|
4584
|
+
return [
|
|
4585
|
+
row.cacheMissInputCost,
|
|
4586
|
+
row.cacheHitInputCost,
|
|
4587
|
+
row.outputCost
|
|
4588
|
+
];
|
|
4589
|
+
}
|
|
4590
|
+
/**
|
|
4591
|
+
* Fold one spend's model rows into the card's three bucket amounts.
|
|
4592
|
+
*
|
|
4593
|
+
* The rows carry float costs, so the three independently rendered values can
|
|
4594
|
+
* miss the displayed total by one unit in the last rendered decimal after each
|
|
4595
|
+
* is formatted to four decimals. The residual is absorbed by the largest
|
|
4596
|
+
* bucket — the only one where a 1e-4 nudge cannot be seen — so the card's rows
|
|
4597
|
+
* always add up to the total it shows in its header.
|
|
4598
|
+
* @param spend - the session bucket of the `billingTodaySpend` projection
|
|
4599
|
+
* (the session's own events, every Beijing day).
|
|
4600
|
+
* @returns the three bucket totals plus the billed total.
|
|
4601
|
+
*/
|
|
4602
|
+
function spendBucketsOf(spend) {
|
|
4603
|
+
let uncachedInput = 0;
|
|
4604
|
+
let cacheRead = 0;
|
|
4605
|
+
let output = 0;
|
|
4606
|
+
for (const row of spend.models) {
|
|
4607
|
+
const [miss, hit, out] = bucketsOf(row);
|
|
4608
|
+
uncachedInput += miss;
|
|
4609
|
+
cacheRead += hit;
|
|
4610
|
+
output += out;
|
|
4611
|
+
}
|
|
4612
|
+
const total = spend.total;
|
|
4613
|
+
const residual = total - (uncachedInput + cacheRead + output);
|
|
4614
|
+
if (residual !== 0) {
|
|
4615
|
+
if (uncachedInput >= cacheRead && uncachedInput >= output) uncachedInput += residual;
|
|
4616
|
+
else if (cacheRead >= output) cacheRead += residual;
|
|
4617
|
+
else output += residual;
|
|
4618
|
+
}
|
|
4619
|
+
return {
|
|
4620
|
+
uncachedInput,
|
|
4621
|
+
cacheRead,
|
|
4622
|
+
output,
|
|
4623
|
+
total
|
|
4624
|
+
};
|
|
4625
|
+
}
|
|
4626
|
+
/**
|
|
4627
|
+
* Fold one spend's model rows into the three bucket TOKEN counts — the token
|
|
4628
|
+
* side of {@link spendBucketsOf}, so a surface that shows both (the panel's
|
|
4629
|
+
* today rows) reads one bucket's tokens and its cost from the same rows.
|
|
4630
|
+
*
|
|
4631
|
+
* No reconciliation is needed here: tokens are integers, so the three counts
|
|
4632
|
+
* always add up to the total the token line shows.
|
|
4633
|
+
* @param spend - the day's (or one session's) priced rows.
|
|
4634
|
+
* @returns the three bucket token counts.
|
|
4635
|
+
*/
|
|
4636
|
+
function tokenBucketsOf(spend) {
|
|
4637
|
+
let uncachedInput = 0;
|
|
4638
|
+
let cacheRead = 0;
|
|
4639
|
+
let output = 0;
|
|
4640
|
+
for (const row of spend.models) {
|
|
4641
|
+
uncachedInput += row.cacheMissInputTokens;
|
|
4642
|
+
cacheRead += row.cacheHitInputTokens;
|
|
4643
|
+
output += row.outputTokens;
|
|
4644
|
+
}
|
|
4645
|
+
return {
|
|
4646
|
+
uncachedInput,
|
|
4647
|
+
cacheRead,
|
|
4648
|
+
output
|
|
4649
|
+
};
|
|
4650
|
+
}
|
|
4651
|
+
/**
|
|
4652
|
+
* The cache-hit share of one spend, in DSH's own percentage rule — the ratio of
|
|
4653
|
+
* the cache-read bucket to every PROMPT-side bucket (uncached input with cache
|
|
4654
|
+
* writes folded in, plus cache read), output excluded, exactly the split DSH's
|
|
4655
|
+
* `billedInputTokens` makes. Rendered by {@link formatCacheHitPercent}, i.e. an
|
|
4656
|
+
* integer percent that grows decimals only to keep a partial hit below 100.
|
|
4657
|
+
* @param spend - the day's priced rows.
|
|
4658
|
+
* @returns the percentage text without its `%`, or null when the spend billed no prompt input.
|
|
4659
|
+
*/
|
|
4660
|
+
function cacheHitPercentOf(spend) {
|
|
4661
|
+
const tokens = tokenBucketsOf(spend);
|
|
4662
|
+
return formatCacheHitPercent(tokens.cacheRead, tokens.cacheRead + tokens.uncachedInput);
|
|
4663
|
+
}
|
|
4367
4664
|
//#endregion
|
|
4368
4665
|
//#region lib/types/client/version.js
|
|
4369
4666
|
/**
|
|
@@ -4380,10 +4677,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4380
4677
|
* @module @rayadesu/dsh-client-ui-billing/version
|
|
4381
4678
|
*/
|
|
4382
4679
|
/** The installed plugin version, e.g. `0.3.10`; `dev` when nothing stamped one. */
|
|
4383
|
-
const PLUGIN_VERSION = "0.3.
|
|
4680
|
+
const PLUGIN_VERSION = "0.3.13";
|
|
4384
4681
|
//#endregion
|
|
4385
4682
|
//#region \0dsh-css:C:\Users\admin\Desktop\me\code\DeepSeek-Harness-chat-billing\packages\ui-billing\src\client\BalanceBadge.module.css.mjs
|
|
4386
|
-
const css$1 = "._4_Wqcq_root{position:relative}._4_Wqcq_trigger{background:var(--dsw-alias-fill-l2);min-height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:0;border-radius:8px;align-items:center;gap:4px;padding:4px 8px;display:inline-flex}._4_Wqcq_trigger:hover,._4_Wqcq_trigger:focus-visible{color:var(--dsw-alias-label-primary)}._4_Wqcq_trigger svg{transition:transform .12s}._4_Wqcq_chevronOpen{transform:rotate(180deg)}._4_Wqcq_triggerLines{text-align:left;flex-direction:column;align-items:flex-start;gap:0;display:flex}._4_Wqcq_linePrimary{font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}._4_Wqcq_lineSecondary{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px;line-height:15px}._4_Wqcq_unavailable{color:var(--dsw-alias-label-tertiary)}._4_Wqcq_inlineIcon{color:var(--dsw-alias-label-tertiary);flex:none}._4_Wqcq_spinning{color:var(--dsw-alias-label-tertiary);flex:none;animation:.8s linear infinite _4_Wqcq_spin}@keyframes _4_Wqcq_spin{to{transform:rotate(360deg)}}._4_Wqcq_panel{z-index:100;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);width:336px;max-width:min(360px,100vw - 32px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:2px;padding:6px;display:flex;position:absolute;top:calc(100% + 6px);right:0}._4_Wqcq_amountRow{border-radius:8px;justify-content:space-between;align-items:center;gap:8px;padding:6px 8px;display:flex}._4_Wqcq_amountLabel{color:var(--
|
|
4683
|
+
const css$1 = "._4_Wqcq_root{position:relative}._4_Wqcq_trigger{background:var(--dsw-alias-fill-l2);min-height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;border:0;border-radius:8px;align-items:center;gap:4px;padding:4px 8px;display:inline-flex}._4_Wqcq_trigger:hover,._4_Wqcq_trigger:focus-visible{color:var(--dsw-alias-label-primary)}._4_Wqcq_trigger svg{transition:transform .12s}._4_Wqcq_chevronOpen{transform:rotate(180deg)}._4_Wqcq_triggerLines{text-align:left;flex-direction:column;align-items:flex-start;gap:0;display:flex}._4_Wqcq_linePrimary{font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}._4_Wqcq_lineSecondary{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px;line-height:15px}._4_Wqcq_unavailable{color:var(--dsw-alias-label-tertiary)}._4_Wqcq_inlineIcon{color:var(--dsw-alias-label-tertiary);flex:none}._4_Wqcq_spinning{color:var(--dsw-alias-label-tertiary);flex:none;animation:.8s linear infinite _4_Wqcq_spin}@keyframes _4_Wqcq_spin{to{transform:rotate(360deg)}}._4_Wqcq_panel{--billing-type-1-size:11px;--billing-type-1-line:16px;--billing-type-1-tone:var(--dsw-alias-label-tertiary);--billing-type-2-size:12px;--billing-type-2-line:18px;--billing-type-2-tone:var(--dsw-alias-label-secondary);--billing-type-2-number-tone:var(--dsw-alias-label-tertiary);--billing-type-3-size:13px;--billing-type-3-line:18px;--billing-type-3-tone:var(--dsw-alias-label-primary);z-index:100;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);width:336px;max-width:min(360px,100vw - 32px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:2px;padding:6px;display:flex;position:absolute;top:calc(100% + 6px);right:0}._4_Wqcq_amountRow{border-radius:8px;justify-content:space-between;align-items:center;gap:8px;padding:6px 8px;display:flex}._4_Wqcq_amountLabel{color:var(--billing-type-3-tone);font-size:var(--billing-type-3-size);line-height:var(--billing-type-3-line);font-variant-numeric:tabular-nums}._4_Wqcq_amountRow>._4_Wqcq_amountLabel{font-size:15px;line-height:22px}._4_Wqcq_sessionToday,._4_Wqcq_todayHit{color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums;margin-left:5px}._4_Wqcq_spendRow{border-top:1px solid var(--dsw-alias-border-l2);border-radius:0;justify-content:space-between;align-items:center;gap:8px;padding:8px 8px 6px;display:flex}._4_Wqcq_costRow{align-items:center;padding:0 8px;display:flex}._4_Wqcq_costRow:last-child{padding-bottom:6px}._4_Wqcq_spendRow+._4_Wqcq_costRow{padding-top:2px}._4_Wqcq_dayBucketRow{align-items:center;padding:2px 8px;display:flex}._4_Wqcq_dayBucketRow+._4_Wqcq_dayBucketRow{padding-bottom:7px}._4_Wqcq_costBreakdown{color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums}._4_Wqcq_amountActions{align-items:center;gap:2px;display:inline-flex}._4_Wqcq_infoButton,._4_Wqcq_refreshButton{width:24px;height:24px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}._4_Wqcq_infoButton:hover,._4_Wqcq_infoButton:focus-visible,._4_Wqcq_refreshButton:hover,._4_Wqcq_refreshButton:focus-visible{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-l2)}._4_Wqcq_modelRow{border-radius:8px;justify-content:space-between;align-items:baseline;gap:8px;padding:4px 8px;display:flex}._4_Wqcq_spendRow+._4_Wqcq_modelRow{padding-top:2px}._4_Wqcq_modelName{color:var(--billing-type-2-tone);font-size:var(--billing-type-2-size);line-height:var(--billing-type-2-line);flex:none}._4_Wqcq_tasks{text-align:right;min-width:0;color:var(--billing-type-2-number-tone);font-size:var(--billing-type-2-size);line-height:var(--billing-type-2-line);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}._4_Wqcq_ranking{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:0;margin-top:7px;padding-top:2px;display:flex}._4_Wqcq_rankingTitle{color:var(--billing-type-2-tone);font-size:var(--billing-type-2-size);line-height:var(--billing-type-2-line);padding:6px 8px 2px}._4_Wqcq_rankingRow{border-radius:8px;align-items:baseline;gap:0;min-width:0;padding:3px 8px;display:flex}._4_Wqcq_rankingRow:hover{background:var(--dsw-alias-fill-l2)}._4_Wqcq_rankingIndex{width:16px;color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums;text-align:right;flex:none}._4_Wqcq_rankingDot{color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums;white-space:pre;flex:none}._4_Wqcq_rankingName{min-width:0;color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._4_Wqcq_rankingAmount{color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);font-variant-numeric:tabular-nums;flex:none;margin-left:8px}._4_Wqcq_rankingMore{color:var(--billing-type-1-tone);font-size:var(--billing-type-1-size);line-height:var(--billing-type-1-line);padding:2px 8px 4px}";
|
|
4387
4684
|
const tagId$1 = "@rayadesu/dsh-client-ui-billing/BalanceBadge.module.css";
|
|
4388
4685
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
4389
4686
|
const tag = document.createElement("style");
|
|
@@ -4399,6 +4696,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4399
4696
|
"chevronOpen": "_4_Wqcq_chevronOpen",
|
|
4400
4697
|
"costBreakdown": "_4_Wqcq_costBreakdown",
|
|
4401
4698
|
"costRow": "_4_Wqcq_costRow",
|
|
4699
|
+
"dayBucketRow": "_4_Wqcq_dayBucketRow",
|
|
4402
4700
|
"infoButton": "_4_Wqcq_infoButton",
|
|
4403
4701
|
"inlineIcon": "_4_Wqcq_inlineIcon",
|
|
4404
4702
|
"linePrimary": "_4_Wqcq_linePrimary",
|
|
@@ -4416,18 +4714,56 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4416
4714
|
"rankingTitle": "_4_Wqcq_rankingTitle",
|
|
4417
4715
|
"refreshButton": "_4_Wqcq_refreshButton",
|
|
4418
4716
|
"root": "_4_Wqcq_root",
|
|
4717
|
+
"sessionToday": "_4_Wqcq_sessionToday",
|
|
4419
4718
|
"spendRow": "_4_Wqcq_spendRow",
|
|
4420
|
-
"spendToday": "_4_Wqcq_spendToday",
|
|
4421
4719
|
"spin": "_4_Wqcq_spin",
|
|
4422
4720
|
"spinning": "_4_Wqcq_spinning",
|
|
4423
4721
|
"tasks": "_4_Wqcq_tasks",
|
|
4722
|
+
"todayHit": "_4_Wqcq_todayHit",
|
|
4424
4723
|
"trigger": "_4_Wqcq_trigger",
|
|
4425
4724
|
"triggerLines": "_4_Wqcq_triggerLines",
|
|
4426
4725
|
"unavailable": "_4_Wqcq_unavailable"
|
|
4427
4726
|
};
|
|
4727
|
+
/**
|
|
4728
|
+
* Today's two bucket detail lines, rendered under the 今日 Token / 今日花费 row:
|
|
4729
|
+
* the three buckets' token counts, then their costs — DSH's own bucket wording
|
|
4730
|
+
* and row order in both lines, so they read like the per-model breakdown line
|
|
4731
|
+
* further down and keep its own row rhythm. Each line stands on its own (no
|
|
4732
|
+
* column alignment between them): the middots keep the natural " · " spacing of
|
|
4733
|
+
* every other breakdown line in the panel.
|
|
4734
|
+
*
|
|
4735
|
+
* Tokens and costs come from the SAME day row set (`todaySpend.models`) the row
|
|
4736
|
+
* above is built from: the three token counts add up to the token figure, and
|
|
4737
|
+
* the three costs (with `spendBucketsOf`'s residual absorbed into the largest
|
|
4738
|
+
* bucket) to the cost figure. Costs render at three significant digits, like the
|
|
4739
|
+
* day figure above them, and never finer than four decimals — their last digits
|
|
4740
|
+
* move with every request and carry no meaning.
|
|
4741
|
+
*/
|
|
4742
|
+
function todayBucketLines(t, spend) {
|
|
4743
|
+
const tokens = tokenBucketsOf(spend);
|
|
4744
|
+
const costs = spendBucketsOf(spend);
|
|
4745
|
+
return {
|
|
4746
|
+
tokenLine: [
|
|
4747
|
+
`${t("label.bucket.input")} ${t("unit.tokens", { count: formatTokens(tokens.uncachedInput) })}`,
|
|
4748
|
+
`${t("label.bucket.cacheRead")} ${t("unit.tokens", { count: formatTokens(tokens.cacheRead) })}`,
|
|
4749
|
+
`${t("label.bucket.output")} ${t("unit.tokens", { count: formatTokens(tokens.output) })}`
|
|
4750
|
+
].join(" · "),
|
|
4751
|
+
costLine: [
|
|
4752
|
+
t("label.cost.input", { amount: formatSpendSignificant(costs.uncachedInput) }),
|
|
4753
|
+
t("label.cost.cacheRead", { amount: formatSpendSignificant(costs.cacheRead) }),
|
|
4754
|
+
t("label.cost.output", { amount: formatSpendSignificant(costs.output) })
|
|
4755
|
+
].join(" · ")
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4428
4758
|
/** The detail box opened from the badge trigger. */
|
|
4429
|
-
function BalancePanel({ amount, sessionId, spend, todaySpend, sessionsSpend, refreshing, onRefresh, t }) {
|
|
4430
|
-
const
|
|
4759
|
+
function BalancePanel({ amount, sessionId, spend, todaySpend, sessionsSpend, isSubagent, crossedDay, refreshing, onRefresh, t }) {
|
|
4760
|
+
const row = sessionsSpend === null ? void 0 : sessionsSpend.sessions.find((entry) => entry.sessionId === sessionId);
|
|
4761
|
+
const sessionToday = spend !== null && !isSubagent && crossedDay && sessionsSpend !== null ? row?.total ?? 0 : null;
|
|
4762
|
+
const sessionAmount = spend === null ? "—" : spend.models.length === 0 ? t("stat.none") : formatSpendSignificant(spend.total);
|
|
4763
|
+
const todayTokens = todaySpend === null ? "—" : todaySpend.models.length === 0 ? t("stat.none") : t("unit.tokens", { count: formatTokens(todaySpend.models.reduce((sum, row) => sum + rowTokens(row), 0)) });
|
|
4764
|
+
const todayAmount = todaySpend === null ? "—" : todaySpend.models.length === 0 ? t("stat.none") : formatSpendSignificant(todaySpend.total);
|
|
4765
|
+
const todayHit = todaySpend === null || todaySpend.models.length === 0 ? null : cacheHitPercentOf(todaySpend);
|
|
4766
|
+
const modelCount = spend === null ? 0 : spend.models.length;
|
|
4431
4767
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
4432
4768
|
className: BalanceBadge_module_css_default.panel,
|
|
4433
4769
|
role: "dialog",
|
|
@@ -4465,34 +4801,57 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4465
4801
|
className: BalanceBadge_module_css_default.spendRow,
|
|
4466
4802
|
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
4467
4803
|
className: BalanceBadge_module_css_default.amountLabel,
|
|
4468
|
-
children: [t("label.
|
|
4469
|
-
className: BalanceBadge_module_css_default.
|
|
4470
|
-
children: t("label.
|
|
4471
|
-
})]
|
|
4804
|
+
children: [t("label.todayTokens", { count: todayTokens }), todayHit !== null ? (0, react_jsx_runtime.jsx)("span", {
|
|
4805
|
+
className: BalanceBadge_module_css_default.todayHit,
|
|
4806
|
+
children: t("label.todayTokens.hit", { percent: todayHit })
|
|
4807
|
+
}) : null]
|
|
4472
4808
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
4473
4809
|
className: BalanceBadge_module_css_default.amountLabel,
|
|
4474
|
-
children: t("label.todaySpend", { amount:
|
|
4810
|
+
children: t("label.todaySpend", { amount: todayAmount })
|
|
4475
4811
|
})]
|
|
4476
4812
|
}),
|
|
4477
|
-
|
|
4813
|
+
todaySpend !== null && todaySpend.models.length > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
|
|
4814
|
+
className: BalanceBadge_module_css_default.dayBucketRow,
|
|
4815
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
4816
|
+
className: BalanceBadge_module_css_default.costBreakdown,
|
|
4817
|
+
children: todayBucketLines(t, todaySpend).tokenLine
|
|
4818
|
+
})
|
|
4819
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
4820
|
+
className: BalanceBadge_module_css_default.dayBucketRow,
|
|
4821
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
4822
|
+
className: BalanceBadge_module_css_default.costBreakdown,
|
|
4823
|
+
children: todayBucketLines(t, todaySpend).costLine
|
|
4824
|
+
})
|
|
4825
|
+
})] }),
|
|
4826
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
4827
|
+
className: BalanceBadge_module_css_default.spendRow,
|
|
4828
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
4829
|
+
className: BalanceBadge_module_css_default.amountLabel,
|
|
4830
|
+
children: [t("label.sessionSpend", { amount: sessionAmount }), sessionToday !== null ? (0, react_jsx_runtime.jsx)("span", {
|
|
4831
|
+
className: BalanceBadge_module_css_default.sessionToday,
|
|
4832
|
+
children: t("label.sessionSpend.today", { amount: formatSpendSignificant(sessionToday) })
|
|
4833
|
+
}) : null]
|
|
4834
|
+
})
|
|
4835
|
+
}),
|
|
4836
|
+
spend?.models.map((model) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [modelCount > 1 && (0, react_jsx_runtime.jsxs)("div", {
|
|
4478
4837
|
className: BalanceBadge_module_css_default.modelRow,
|
|
4479
4838
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
4480
4839
|
className: BalanceBadge_module_css_default.modelName,
|
|
4481
4840
|
children: model.displayName
|
|
4482
4841
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
4483
4842
|
className: BalanceBadge_module_css_default.tasks,
|
|
4484
|
-
children:
|
|
4843
|
+
children: formatSpendSignificant(model.cost)
|
|
4485
4844
|
})]
|
|
4486
4845
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
4487
4846
|
className: BalanceBadge_module_css_default.costRow,
|
|
4488
4847
|
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
4489
4848
|
className: BalanceBadge_module_css_default.costBreakdown,
|
|
4490
4849
|
children: [
|
|
4491
|
-
t("label.cost.
|
|
4850
|
+
t("label.cost.input", { amount: formatSpendSignificant(model.cacheMissInputCost) }),
|
|
4492
4851
|
" · ",
|
|
4493
|
-
t("label.cost.
|
|
4852
|
+
t("label.cost.cacheRead", { amount: formatSpendSignificant(model.cacheHitInputCost) }),
|
|
4494
4853
|
" · ",
|
|
4495
|
-
t("label.cost.output", { amount:
|
|
4854
|
+
t("label.cost.output", { amount: formatSpendSignificant(model.outputCost) })
|
|
4496
4855
|
]
|
|
4497
4856
|
})
|
|
4498
4857
|
})] }, model.model)),
|
|
@@ -4522,7 +4881,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4522
4881
|
}),
|
|
4523
4882
|
(0, react_jsx_runtime.jsx)("span", {
|
|
4524
4883
|
className: BalanceBadge_module_css_default.rankingAmount,
|
|
4525
|
-
children:
|
|
4884
|
+
children: formatSpendSignificant(row.total)
|
|
4526
4885
|
})
|
|
4527
4886
|
]
|
|
4528
4887
|
}, row.sessionId)),
|
|
@@ -4539,7 +4898,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4539
4898
|
//#region lib/types/client/BalanceTrigger.js
|
|
4540
4899
|
/**
|
|
4541
4900
|
* Session-header billing trigger: the balance plus the conversation-spend
|
|
4542
|
-
* line. Pure view over the data hook's values — no state, no effects.
|
|
4901
|
+
* line. Pure view over the data hook's values — no state, no effects. The
|
|
4902
|
+
* balance line uses the trigger's own `trigger.balance` (the panel headline
|
|
4903
|
+
* without its "API" prefix, since the chip is narrow); the spend line arrives
|
|
4904
|
+
* precomputed from the parent carrying the PANEL's `label.sessionSpend`.
|
|
4543
4905
|
*/
|
|
4544
4906
|
/** The badge button: balance line, spend line, and the open-state chevron. */
|
|
4545
4907
|
function BalanceTrigger({ amount, spendLine, open, onToggle, t }) {
|
|
@@ -4562,9 +4924,57 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4562
4924
|
});
|
|
4563
4925
|
}
|
|
4564
4926
|
//#endregion
|
|
4927
|
+
//#region lib/types/client/spends.js
|
|
4928
|
+
/**
|
|
4929
|
+
* Additive merge of a conversation's two spend halves: the session's OWN billed
|
|
4930
|
+
* spend (live, from the pushed `billingTodaySpend` projection or the
|
|
4931
|
+
* `billing/getSessionSpend` fallback) and the delegated-subagent subtotal
|
|
4932
|
+
* (`billing/getDelegatedSpend`). The panel shows one amount for the whole
|
|
4933
|
+
* conversation, so the two must be summed before rendering — and the per-model
|
|
4934
|
+
* rows must be summed the same way, or the breakdown would no longer add up to
|
|
4935
|
+
* the amount above it.
|
|
4936
|
+
*
|
|
4937
|
+
* Pure addition only: no pricing, no timezone, no fork-boundary knowledge lives
|
|
4938
|
+
* here (the host owns all of that), so this cannot drift from the host's own
|
|
4939
|
+
* sums.
|
|
4940
|
+
*/
|
|
4941
|
+
/** Sum two model rows of the same wire model (display name taken from the first). */
|
|
4942
|
+
function addRows(left, right) {
|
|
4943
|
+
return {
|
|
4944
|
+
...left,
|
|
4945
|
+
cost: left.cost + right.cost,
|
|
4946
|
+
peakCost: left.peakCost + right.peakCost,
|
|
4947
|
+
offPeakCost: left.offPeakCost + right.offPeakCost,
|
|
4948
|
+
cacheHitInputTokens: left.cacheHitInputTokens + right.cacheHitInputTokens,
|
|
4949
|
+
cacheMissInputTokens: left.cacheMissInputTokens + right.cacheMissInputTokens,
|
|
4950
|
+
outputTokens: left.outputTokens + right.outputTokens,
|
|
4951
|
+
cacheHitInputCost: left.cacheHitInputCost + right.cacheHitInputCost,
|
|
4952
|
+
cacheMissInputCost: left.cacheMissInputCost + right.cacheMissInputCost,
|
|
4953
|
+
outputCost: left.outputCost + right.outputCost
|
|
4954
|
+
};
|
|
4955
|
+
}
|
|
4956
|
+
/**
|
|
4957
|
+
* Sum one conversation's own spend and its delegated-subagent subtotal.
|
|
4958
|
+
* @param own - the session's own billed spend.
|
|
4959
|
+
* @param delegated - the delegated subtotal from the last `getDelegatedSpend` read.
|
|
4960
|
+
* @returns the merged spend (own model order first, then newly seen models).
|
|
4961
|
+
*/
|
|
4962
|
+
function sumSpends(own, delegated) {
|
|
4963
|
+
const rows = /* @__PURE__ */ new Map();
|
|
4964
|
+
for (const row of own.models) rows.set(row.model, row);
|
|
4965
|
+
for (const row of delegated.models) {
|
|
4966
|
+
const existing = rows.get(row.model);
|
|
4967
|
+
rows.set(row.model, existing === void 0 ? row : addRows(existing, row));
|
|
4968
|
+
}
|
|
4969
|
+
return {
|
|
4970
|
+
total: own.total + delegated.total,
|
|
4971
|
+
models: [...rows.values()]
|
|
4972
|
+
};
|
|
4973
|
+
}
|
|
4974
|
+
//#endregion
|
|
4565
4975
|
//#region lib/types/client/useBillingData.js
|
|
4566
4976
|
/**
|
|
4567
|
-
* Billing badge data hook: owns the balance/session/today states, the
|
|
4977
|
+
* Billing badge data hook: owns the balance/session/today/delegated states, the
|
|
4568
4978
|
* mount+refresh fetch, the turn-settled recompute, and the click-outside
|
|
4569
4979
|
* close. The trigger and the panel are pure views over the returned values,
|
|
4570
4980
|
* so the concurrency/race handling lives in exactly one file.
|
|
@@ -4587,18 +4997,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4587
4997
|
}
|
|
4588
4998
|
/**
|
|
4589
4999
|
* Start the badge's data lifecycle for one session. The spend follows the
|
|
4590
|
-
* conversation: the host-pushed `billingTodaySpend` projection drives
|
|
4591
|
-
* session
|
|
4592
|
-
* bootstrap/fallback when the projection key is absent;
|
|
4593
|
-
*
|
|
4594
|
-
*
|
|
5000
|
+
* conversation: the host-pushed `billingTodaySpend` projection drives this
|
|
5001
|
+
* session's own part live (zero Remote calls), with `getSessionSpend` as the
|
|
5002
|
+
* bootstrap/fallback when the projection key is absent; the delegated-subagent
|
|
5003
|
+
* subtotal comes from `getDelegatedSpend` on mount, on refresh, and when a turn
|
|
5004
|
+
* settles; today's spend is recomputed through `getTodaySpend` on the same
|
|
5005
|
+
* events; the balance stays a manual-refresh snapshot and is never refetched on
|
|
5006
|
+
* its own.
|
|
4595
5007
|
* @param props - the badge's injected face and session runtime share.
|
|
4596
5008
|
*/
|
|
4597
|
-
function useBillingData({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, sessionId, useSession, useProjection }) {
|
|
5009
|
+
function useBillingData({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, getDelegatedSpend, sessionId, useSession, useProjection }) {
|
|
4598
5010
|
const [balance, setBalance] = (0, react.useState)(getCachedBalance);
|
|
4599
5011
|
const [spend, setSpend] = (0, react.useState)(null);
|
|
4600
5012
|
const [todaySpend, setTodaySpend] = (0, react.useState)(null);
|
|
4601
5013
|
const [sessionsSpend, setSessionsSpend] = (0, react.useState)(null);
|
|
5014
|
+
const [delegated, setDelegated] = (0, react.useState)(null);
|
|
4602
5015
|
const [error, setError] = (0, react.useState)(null);
|
|
4603
5016
|
const [refreshing, setRefreshing] = (0, react.useState)(false);
|
|
4604
5017
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -4624,11 +5037,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4624
5037
|
});
|
|
4625
5038
|
const sessionSpendRequest = fetchLine(isCurrent, () => getSessionSpend(sessionId), setSpend);
|
|
4626
5039
|
const todaySpendRequest = fetchLine(isCurrent, () => getTodaySpend(request > 0), setTodaySpend);
|
|
5040
|
+
const delegatedRequest = fetchLine(isCurrent, () => getDelegatedSpend(sessionId, request > 0), setDelegated);
|
|
4627
5041
|
const sessionsSpendRequest = openRef.current ? fetchLine(isCurrent, () => getTodaySessionsSpend(request > 0), setSessionsSpend) : Promise.resolve();
|
|
4628
5042
|
Promise.allSettled([
|
|
4629
5043
|
balanceRequest,
|
|
4630
5044
|
sessionSpendRequest,
|
|
4631
5045
|
todaySpendRequest,
|
|
5046
|
+
delegatedRequest,
|
|
4632
5047
|
sessionsSpendRequest
|
|
4633
5048
|
]).then(() => {
|
|
4634
5049
|
if (current) setRefreshing(false);
|
|
@@ -4642,6 +5057,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4642
5057
|
getSessionSpend,
|
|
4643
5058
|
getTodaySpend,
|
|
4644
5059
|
getTodaySessionsSpend,
|
|
5060
|
+
getDelegatedSpend,
|
|
4645
5061
|
sessionId,
|
|
4646
5062
|
request
|
|
4647
5063
|
]);
|
|
@@ -4661,6 +5077,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4661
5077
|
const isCurrent = () => current;
|
|
4662
5078
|
const timer = setTimeout(() => {
|
|
4663
5079
|
fetchLine(isCurrent, () => getSessionSpend(sessionId), setSpend);
|
|
5080
|
+
fetchLine(isCurrent, () => getDelegatedSpend(sessionId), setDelegated);
|
|
4664
5081
|
fetchLine(isCurrent, () => getTodaySpend(), setTodaySpend);
|
|
4665
5082
|
if (openRef.current) fetchLine(isCurrent, () => getTodaySessionsSpend(), setSessionsSpend);
|
|
4666
5083
|
}, TURN_SETTLE_DEBOUNCE_MS);
|
|
@@ -4670,6 +5087,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4670
5087
|
};
|
|
4671
5088
|
}, [
|
|
4672
5089
|
getSessionSpend,
|
|
5090
|
+
getDelegatedSpend,
|
|
4673
5091
|
getTodaySpend,
|
|
4674
5092
|
getTodaySessionsSpend,
|
|
4675
5093
|
sessionId,
|
|
@@ -4685,11 +5103,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4685
5103
|
document.removeEventListener("pointerdown", closeOutside);
|
|
4686
5104
|
};
|
|
4687
5105
|
}, [open]);
|
|
5106
|
+
const own = projected === void 0 ? spend : projected.session;
|
|
4688
5107
|
return {
|
|
4689
5108
|
balance,
|
|
4690
|
-
spend:
|
|
5109
|
+
spend: own === null ? null : delegated === null ? own : sumSpends(own, delegated),
|
|
4691
5110
|
todaySpend,
|
|
4692
5111
|
sessionsSpend,
|
|
5112
|
+
isSubagent: delegated?.isSubagent ?? false,
|
|
5113
|
+
crossedDay: delegated?.crossedDay ?? false,
|
|
4693
5114
|
error,
|
|
4694
5115
|
refreshing,
|
|
4695
5116
|
open,
|
|
@@ -4712,13 +5133,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4712
5133
|
* @param props - Remote face, locale, and the standard session-header runtime share.
|
|
4713
5134
|
* @returns the badge, or null until the first balance fetch settles.
|
|
4714
5135
|
*/
|
|
4715
|
-
function BalanceBadge({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, sessionId, useSession, useProjection, t }) {
|
|
4716
|
-
const { balance, spend, todaySpend, sessionsSpend, error, refreshing, open, rootRef, refresh, toggleOpen } = useBillingData({
|
|
5136
|
+
function BalanceBadge({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, getDelegatedSpend, sessionId, useSession, useProjection, t }) {
|
|
5137
|
+
const { balance, spend, todaySpend, sessionsSpend, isSubagent, crossedDay, error, refreshing, open, rootRef, refresh, toggleOpen } = useBillingData({
|
|
4717
5138
|
getBalance,
|
|
4718
5139
|
getCachedBalance,
|
|
4719
5140
|
getSessionSpend,
|
|
4720
5141
|
getTodaySpend,
|
|
4721
5142
|
getTodaySessionsSpend,
|
|
5143
|
+
getDelegatedSpend,
|
|
4722
5144
|
sessionId,
|
|
4723
5145
|
useSession,
|
|
4724
5146
|
useProjection
|
|
@@ -4742,7 +5164,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4742
5164
|
}
|
|
4743
5165
|
const line = primaryLine(balance);
|
|
4744
5166
|
const amount = line === void 0 ? "—" : `${line.symbol}${line.total}`;
|
|
4745
|
-
const spendLine = spend !== null && spend.models.length > 0 ? t("
|
|
5167
|
+
const spendLine = spend !== null && spend.models.length > 0 ? t("label.sessionSpend", { amount: formatSpendSignificant(spend.total) }) : void 0;
|
|
4746
5168
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
4747
5169
|
ref: rootRef,
|
|
4748
5170
|
className: BalanceBadge_module_css_default.root,
|
|
@@ -4758,6 +5180,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4758
5180
|
spend,
|
|
4759
5181
|
todaySpend,
|
|
4760
5182
|
sessionsSpend,
|
|
5183
|
+
isSubagent,
|
|
5184
|
+
crossedDay,
|
|
4761
5185
|
refreshing,
|
|
4762
5186
|
onRefresh: refresh,
|
|
4763
5187
|
t
|
|
@@ -4879,21 +5303,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4879
5303
|
const NS = "billing";
|
|
4880
5304
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
4881
5305
|
const zh = {
|
|
4882
|
-
"trigger.balance": "
|
|
4883
|
-
"trigger.conversationSpend": "本轮对话花费:{amount}",
|
|
5306
|
+
"trigger.balance": "剩余金额:{amount}",
|
|
4884
5307
|
"label.amount": "API 剩余金额:{amount}",
|
|
4885
5308
|
"label.sessionSpend": "本会话花费:{amount}",
|
|
4886
|
-
"label.sessionSpend.today": "
|
|
4887
|
-
"label.todaySpend": "
|
|
4888
|
-
"label.
|
|
4889
|
-
"label.
|
|
5309
|
+
"label.sessionSpend.today": " {amount}",
|
|
5310
|
+
"label.todaySpend": "今日花费:{amount}",
|
|
5311
|
+
"label.todayTokens": "今日 Token:{count}",
|
|
5312
|
+
"label.todayTokens.hit": " {percent}%",
|
|
5313
|
+
"unit.tokens": "{count} tok",
|
|
5314
|
+
"label.cost.input": "未缓存输入 {amount}",
|
|
5315
|
+
"label.cost.cacheRead": "缓存读取 {amount}",
|
|
4890
5316
|
"label.cost.output": "输出 {amount}",
|
|
5317
|
+
"card.title": "花费金额",
|
|
5318
|
+
"card.aria": "本轮对话花费:{amount}",
|
|
5319
|
+
"label.bucket.input": "未缓存输入",
|
|
5320
|
+
"label.bucket.cacheRead": "缓存读取",
|
|
5321
|
+
"label.bucket.output": "输出",
|
|
4891
5322
|
"stat.none": "暂无消耗记录",
|
|
4892
5323
|
"stat.untitled": "未命名",
|
|
4893
5324
|
"state.unavailable": "额度不可用",
|
|
4894
5325
|
"action.refresh": "刷新",
|
|
4895
5326
|
"info.aria": "花费说明",
|
|
4896
|
-
"info.hint": "估算:仅 DeepSeek 与 MiMo 模型,按每条消息自身时刻的峰谷官方单价计价(高峰:工作日 9:00–12:00、14:00–18:00)。\nv{version}",
|
|
5327
|
+
"info.hint": "估算:仅 DeepSeek 与 MiMo 模型,按每条消息自身时刻的峰谷官方单价计价(高峰:工作日 9:00–12:00、14:00–18:00)。\n金额含本会话委派的子代理会话。\n紧跟的数字为本会话今日花费。\nv{version}",
|
|
4897
5328
|
"badge.aria": "DeepSeek 额度:{amount}",
|
|
4898
5329
|
"panel.aria": "DeepSeek 额度详情",
|
|
4899
5330
|
"label.sessionRanking": "今日会话花费",
|
|
@@ -4902,20 +5333,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4902
5333
|
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
4903
5334
|
const en = {
|
|
4904
5335
|
"trigger.balance": "Balance: {amount}",
|
|
4905
|
-
"trigger.conversationSpend": "This conversation: {amount}",
|
|
4906
5336
|
"label.amount": "API balance: {amount}",
|
|
4907
5337
|
"label.sessionSpend": "This session: {amount}",
|
|
4908
|
-
"label.sessionSpend.today": "
|
|
4909
|
-
"label.todaySpend": "Today: {amount}",
|
|
4910
|
-
"label.
|
|
4911
|
-
"label.
|
|
5338
|
+
"label.sessionSpend.today": " {amount}",
|
|
5339
|
+
"label.todaySpend": "Today spend: {amount}",
|
|
5340
|
+
"label.todayTokens": "Today tokens: {count}",
|
|
5341
|
+
"label.todayTokens.hit": " {percent}%",
|
|
5342
|
+
"unit.tokens": "{count} tok",
|
|
5343
|
+
"label.cost.input": "Uncached input {amount}",
|
|
5344
|
+
"label.cost.cacheRead": "Cached input {amount}",
|
|
4912
5345
|
"label.cost.output": "Output {amount}",
|
|
5346
|
+
"card.title": "Spend",
|
|
5347
|
+
"card.aria": "This conversation’s spend: {amount}",
|
|
5348
|
+
"label.bucket.input": "Uncached input",
|
|
5349
|
+
"label.bucket.cacheRead": "Cached input",
|
|
5350
|
+
"label.bucket.output": "Output",
|
|
4913
5351
|
"stat.none": "No usage recorded",
|
|
4914
5352
|
"stat.untitled": "Untitled",
|
|
4915
5353
|
"state.unavailable": "Balance unavailable",
|
|
4916
5354
|
"action.refresh": "Refresh",
|
|
4917
5355
|
"info.aria": "About this spend",
|
|
4918
|
-
"info.hint": "Estimate: DeepSeek and MiMo models only, each message priced at the official peak/off-peak rate of its own time (peak: weekdays 09:00–12:00, 14:00–18:00).\nv{version}",
|
|
5356
|
+
"info.hint": "Estimate: DeepSeek and MiMo models only, each message priced at the official peak/off-peak rate of its own time (peak: weekdays 09:00–12:00, 14:00–18:00).\nThe amounts include the subagent sessions this session delegated.\nThe figure after it is this session's spend today.\nv{version}",
|
|
4919
5357
|
"badge.aria": "DeepSeek balance {amount}",
|
|
4920
5358
|
"panel.aria": "DeepSeek balance details",
|
|
4921
5359
|
"label.sessionRanking": "Today session spend",
|
|
@@ -4958,7 +5396,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4958
5396
|
getCachedBalance: () => lastBalance,
|
|
4959
5397
|
getSessionSpend: async (sessionId) => unwrap("billing.getSessionSpend", await billing.getSessionSpend(sessionId)),
|
|
4960
5398
|
getTodaySpend: async (force) => unwrap("billing.getTodaySpend", await billing.getTodaySpend(force)),
|
|
4961
|
-
getTodaySessionsSpend: async (force) => unwrap("billing.getTodaySessionsSpend", await billing.getTodaySessionsSpend(force))
|
|
5399
|
+
getTodaySessionsSpend: async (force) => unwrap("billing.getTodaySessionsSpend", await billing.getTodaySessionsSpend(force)),
|
|
5400
|
+
getDelegatedSpend: async (sessionId, force) => unwrap("billing.getDelegatedSpend", await billing.getDelegatedSpend(sessionId, force))
|
|
4962
5401
|
};
|
|
4963
5402
|
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
4964
5403
|
name: "conversation.session.header.utilities",
|