@rayadesu/dsh-client-ui-billing 0.3.12 → 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 +7 -6
- package/README.zh.md +8 -6
- package/lib/client.js +446 -71
- package/lib/types/client/BalanceBadge.d.ts +17 -7
- package/lib/types/client/BalancePanel.d.ts +6 -1
- package/lib/types/client/format.d.ts +47 -4
- package/lib/types/client/locales.d.ts +7 -7
- package/lib/types/client/spendBuckets.d.ts +30 -0
- package/lib/types/client/spends.d.ts +22 -0
- package/lib/types/client/useBillingData.d.ts +23 -6
- package/package.json +44 -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,11 +4438,36 @@ 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
|
}
|
|
4367
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
|
+
/**
|
|
4368
4471
|
* A token count in DSH's own compact notation: `517` / `12.2K` / `517K` / `1.2M`.
|
|
4369
4472
|
*
|
|
4370
4473
|
* Mirrors ui-chat's `formatTokens` (`packages/client/ui-chat/src/client/chat/
|
|
@@ -4385,6 +4488,74 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4385
4488
|
if (count < 1e6) return `${scaled(count / 1e3)}K`;
|
|
4386
4489
|
return `${scaled(count / 1e6)}M`;
|
|
4387
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
|
+
}
|
|
4388
4559
|
/**
|
|
4389
4560
|
* The total billed tokens of a priced row: the three buckets summed. Tokens are
|
|
4390
4561
|
* already counted per bucket when they were priced, so a cache-hit input token
|
|
@@ -4397,6 +4568,100 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4397
4568
|
return row.cacheHitInputTokens + row.cacheMissInputTokens + row.outputTokens;
|
|
4398
4569
|
}
|
|
4399
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
|
+
}
|
|
4664
|
+
//#endregion
|
|
4400
4665
|
//#region lib/types/client/version.js
|
|
4401
4666
|
/**
|
|
4402
4667
|
* The plugin's own version, reported in the spend-hint bubble so a report can
|
|
@@ -4412,10 +4677,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4412
4677
|
* @module @rayadesu/dsh-client-ui-billing/version
|
|
4413
4678
|
*/
|
|
4414
4679
|
/** The installed plugin version, e.g. `0.3.10`; `dev` when nothing stamped one. */
|
|
4415
|
-
const PLUGIN_VERSION = "0.3.
|
|
4680
|
+
const PLUGIN_VERSION = "0.3.13";
|
|
4416
4681
|
//#endregion
|
|
4417
4682
|
//#region \0dsh-css:C:\Users\admin\Desktop\me\code\DeepSeek-Harness-chat-billing\packages\ui-billing\src\client\BalanceBadge.module.css.mjs
|
|
4418
|
-
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}";
|
|
4419
4684
|
const tagId$1 = "@rayadesu/dsh-client-ui-billing/BalanceBadge.module.css";
|
|
4420
4685
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
4421
4686
|
const tag = document.createElement("style");
|
|
@@ -4431,6 +4696,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4431
4696
|
"chevronOpen": "_4_Wqcq_chevronOpen",
|
|
4432
4697
|
"costBreakdown": "_4_Wqcq_costBreakdown",
|
|
4433
4698
|
"costRow": "_4_Wqcq_costRow",
|
|
4699
|
+
"dayBucketRow": "_4_Wqcq_dayBucketRow",
|
|
4434
4700
|
"infoButton": "_4_Wqcq_infoButton",
|
|
4435
4701
|
"inlineIcon": "_4_Wqcq_inlineIcon",
|
|
4436
4702
|
"linePrimary": "_4_Wqcq_linePrimary",
|
|
@@ -4448,29 +4714,56 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4448
4714
|
"rankingTitle": "_4_Wqcq_rankingTitle",
|
|
4449
4715
|
"refreshButton": "_4_Wqcq_refreshButton",
|
|
4450
4716
|
"root": "_4_Wqcq_root",
|
|
4717
|
+
"sessionToday": "_4_Wqcq_sessionToday",
|
|
4451
4718
|
"spendRow": "_4_Wqcq_spendRow",
|
|
4452
|
-
"spendToday": "_4_Wqcq_spendToday",
|
|
4453
4719
|
"spin": "_4_Wqcq_spin",
|
|
4454
4720
|
"spinning": "_4_Wqcq_spinning",
|
|
4455
4721
|
"tasks": "_4_Wqcq_tasks",
|
|
4722
|
+
"todayHit": "_4_Wqcq_todayHit",
|
|
4456
4723
|
"trigger": "_4_Wqcq_trigger",
|
|
4457
4724
|
"triggerLines": "_4_Wqcq_triggerLines",
|
|
4458
4725
|
"unavailable": "_4_Wqcq_unavailable"
|
|
4459
4726
|
};
|
|
4460
4727
|
/**
|
|
4461
|
-
*
|
|
4462
|
-
*
|
|
4463
|
-
*
|
|
4464
|
-
*
|
|
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.
|
|
4465
4741
|
*/
|
|
4466
|
-
|
|
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
|
+
}
|
|
4467
4758
|
/** The detail box opened from the badge trigger. */
|
|
4468
|
-
function BalancePanel({ amount, sessionId, spend, todaySpend, sessionsSpend, refreshing, onRefresh, t }) {
|
|
4469
|
-
const
|
|
4470
|
-
const
|
|
4471
|
-
const sessionAmount = spend === null ? "—" : spend.models.length === 0 ? t("stat.none") :
|
|
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);
|
|
4472
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)) });
|
|
4473
|
-
const todayAmount = todaySpend === null ? "—" : todaySpend.models.length === 0 ? t("stat.none") :
|
|
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;
|
|
4474
4767
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
4475
4768
|
className: BalanceBadge_module_css_default.panel,
|
|
4476
4769
|
role: "dialog",
|
|
@@ -4506,43 +4799,59 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4506
4799
|
}),
|
|
4507
4800
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
4508
4801
|
className: BalanceBadge_module_css_default.spendRow,
|
|
4509
|
-
children: [(0, react_jsx_runtime.
|
|
4802
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
4510
4803
|
className: BalanceBadge_module_css_default.amountLabel,
|
|
4511
|
-
children: t("label.todayTokens", { count: todayTokens })
|
|
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]
|
|
4512
4808
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
4513
4809
|
className: BalanceBadge_module_css_default.amountLabel,
|
|
4514
4810
|
children: t("label.todaySpend", { amount: todayAmount })
|
|
4515
4811
|
})]
|
|
4516
4812
|
}),
|
|
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
|
+
})] }),
|
|
4517
4826
|
(0, react_jsx_runtime.jsx)("div", {
|
|
4518
4827
|
className: BalanceBadge_module_css_default.spendRow,
|
|
4519
4828
|
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
4520
4829
|
className: BalanceBadge_module_css_default.amountLabel,
|
|
4521
|
-
children: [t("label.sessionSpend", { amount: sessionAmount }),
|
|
4522
|
-
className: BalanceBadge_module_css_default.
|
|
4523
|
-
children: t("label.sessionSpend.today", { amount:
|
|
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) })
|
|
4524
4833
|
}) : null]
|
|
4525
4834
|
})
|
|
4526
4835
|
}),
|
|
4527
|
-
spend?.models.map((model) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
4836
|
+
spend?.models.map((model) => (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [modelCount > 1 && (0, react_jsx_runtime.jsxs)("div", {
|
|
4528
4837
|
className: BalanceBadge_module_css_default.modelRow,
|
|
4529
4838
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
4530
4839
|
className: BalanceBadge_module_css_default.modelName,
|
|
4531
4840
|
children: model.displayName
|
|
4532
4841
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
4533
4842
|
className: BalanceBadge_module_css_default.tasks,
|
|
4534
|
-
children:
|
|
4843
|
+
children: formatSpendSignificant(model.cost)
|
|
4535
4844
|
})]
|
|
4536
4845
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
4537
4846
|
className: BalanceBadge_module_css_default.costRow,
|
|
4538
4847
|
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
4539
4848
|
className: BalanceBadge_module_css_default.costBreakdown,
|
|
4540
4849
|
children: [
|
|
4541
|
-
t("label.cost.input", { amount:
|
|
4850
|
+
t("label.cost.input", { amount: formatSpendSignificant(model.cacheMissInputCost) }),
|
|
4542
4851
|
" · ",
|
|
4543
|
-
t("label.cost.cacheRead", { amount:
|
|
4852
|
+
t("label.cost.cacheRead", { amount: formatSpendSignificant(model.cacheHitInputCost) }),
|
|
4544
4853
|
" · ",
|
|
4545
|
-
t("label.cost.output", { amount:
|
|
4854
|
+
t("label.cost.output", { amount: formatSpendSignificant(model.outputCost) })
|
|
4546
4855
|
]
|
|
4547
4856
|
})
|
|
4548
4857
|
})] }, model.model)),
|
|
@@ -4572,7 +4881,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4572
4881
|
}),
|
|
4573
4882
|
(0, react_jsx_runtime.jsx)("span", {
|
|
4574
4883
|
className: BalanceBadge_module_css_default.rankingAmount,
|
|
4575
|
-
children:
|
|
4884
|
+
children: formatSpendSignificant(row.total)
|
|
4576
4885
|
})
|
|
4577
4886
|
]
|
|
4578
4887
|
}, row.sessionId)),
|
|
@@ -4589,7 +4898,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4589
4898
|
//#region lib/types/client/BalanceTrigger.js
|
|
4590
4899
|
/**
|
|
4591
4900
|
* Session-header billing trigger: the balance plus the conversation-spend
|
|
4592
|
-
* 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`.
|
|
4593
4905
|
*/
|
|
4594
4906
|
/** The badge button: balance line, spend line, and the open-state chevron. */
|
|
4595
4907
|
function BalanceTrigger({ amount, spendLine, open, onToggle, t }) {
|
|
@@ -4612,9 +4924,57 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4612
4924
|
});
|
|
4613
4925
|
}
|
|
4614
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
|
|
4615
4975
|
//#region lib/types/client/useBillingData.js
|
|
4616
4976
|
/**
|
|
4617
|
-
* Billing badge data hook: owns the balance/session/today states, the
|
|
4977
|
+
* Billing badge data hook: owns the balance/session/today/delegated states, the
|
|
4618
4978
|
* mount+refresh fetch, the turn-settled recompute, and the click-outside
|
|
4619
4979
|
* close. The trigger and the panel are pure views over the returned values,
|
|
4620
4980
|
* so the concurrency/race handling lives in exactly one file.
|
|
@@ -4637,18 +4997,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4637
4997
|
}
|
|
4638
4998
|
/**
|
|
4639
4999
|
* Start the badge's data lifecycle for one session. The spend follows the
|
|
4640
|
-
* conversation: the host-pushed `billingTodaySpend` projection drives
|
|
4641
|
-
* session
|
|
4642
|
-
* bootstrap/fallback when the projection key is absent;
|
|
4643
|
-
*
|
|
4644
|
-
*
|
|
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.
|
|
4645
5007
|
* @param props - the badge's injected face and session runtime share.
|
|
4646
5008
|
*/
|
|
4647
|
-
function useBillingData({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, sessionId, useSession, useProjection }) {
|
|
5009
|
+
function useBillingData({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, getDelegatedSpend, sessionId, useSession, useProjection }) {
|
|
4648
5010
|
const [balance, setBalance] = (0, react.useState)(getCachedBalance);
|
|
4649
5011
|
const [spend, setSpend] = (0, react.useState)(null);
|
|
4650
5012
|
const [todaySpend, setTodaySpend] = (0, react.useState)(null);
|
|
4651
5013
|
const [sessionsSpend, setSessionsSpend] = (0, react.useState)(null);
|
|
5014
|
+
const [delegated, setDelegated] = (0, react.useState)(null);
|
|
4652
5015
|
const [error, setError] = (0, react.useState)(null);
|
|
4653
5016
|
const [refreshing, setRefreshing] = (0, react.useState)(false);
|
|
4654
5017
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -4674,11 +5037,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4674
5037
|
});
|
|
4675
5038
|
const sessionSpendRequest = fetchLine(isCurrent, () => getSessionSpend(sessionId), setSpend);
|
|
4676
5039
|
const todaySpendRequest = fetchLine(isCurrent, () => getTodaySpend(request > 0), setTodaySpend);
|
|
5040
|
+
const delegatedRequest = fetchLine(isCurrent, () => getDelegatedSpend(sessionId, request > 0), setDelegated);
|
|
4677
5041
|
const sessionsSpendRequest = openRef.current ? fetchLine(isCurrent, () => getTodaySessionsSpend(request > 0), setSessionsSpend) : Promise.resolve();
|
|
4678
5042
|
Promise.allSettled([
|
|
4679
5043
|
balanceRequest,
|
|
4680
5044
|
sessionSpendRequest,
|
|
4681
5045
|
todaySpendRequest,
|
|
5046
|
+
delegatedRequest,
|
|
4682
5047
|
sessionsSpendRequest
|
|
4683
5048
|
]).then(() => {
|
|
4684
5049
|
if (current) setRefreshing(false);
|
|
@@ -4692,6 +5057,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4692
5057
|
getSessionSpend,
|
|
4693
5058
|
getTodaySpend,
|
|
4694
5059
|
getTodaySessionsSpend,
|
|
5060
|
+
getDelegatedSpend,
|
|
4695
5061
|
sessionId,
|
|
4696
5062
|
request
|
|
4697
5063
|
]);
|
|
@@ -4711,6 +5077,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4711
5077
|
const isCurrent = () => current;
|
|
4712
5078
|
const timer = setTimeout(() => {
|
|
4713
5079
|
fetchLine(isCurrent, () => getSessionSpend(sessionId), setSpend);
|
|
5080
|
+
fetchLine(isCurrent, () => getDelegatedSpend(sessionId), setDelegated);
|
|
4714
5081
|
fetchLine(isCurrent, () => getTodaySpend(), setTodaySpend);
|
|
4715
5082
|
if (openRef.current) fetchLine(isCurrent, () => getTodaySessionsSpend(), setSessionsSpend);
|
|
4716
5083
|
}, TURN_SETTLE_DEBOUNCE_MS);
|
|
@@ -4720,6 +5087,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4720
5087
|
};
|
|
4721
5088
|
}, [
|
|
4722
5089
|
getSessionSpend,
|
|
5090
|
+
getDelegatedSpend,
|
|
4723
5091
|
getTodaySpend,
|
|
4724
5092
|
getTodaySessionsSpend,
|
|
4725
5093
|
sessionId,
|
|
@@ -4735,11 +5103,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4735
5103
|
document.removeEventListener("pointerdown", closeOutside);
|
|
4736
5104
|
};
|
|
4737
5105
|
}, [open]);
|
|
5106
|
+
const own = projected === void 0 ? spend : projected.session;
|
|
4738
5107
|
return {
|
|
4739
5108
|
balance,
|
|
4740
|
-
spend:
|
|
5109
|
+
spend: own === null ? null : delegated === null ? own : sumSpends(own, delegated),
|
|
4741
5110
|
todaySpend,
|
|
4742
5111
|
sessionsSpend,
|
|
5112
|
+
isSubagent: delegated?.isSubagent ?? false,
|
|
5113
|
+
crossedDay: delegated?.crossedDay ?? false,
|
|
4743
5114
|
error,
|
|
4744
5115
|
refreshing,
|
|
4745
5116
|
open,
|
|
@@ -4762,13 +5133,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4762
5133
|
* @param props - Remote face, locale, and the standard session-header runtime share.
|
|
4763
5134
|
* @returns the badge, or null until the first balance fetch settles.
|
|
4764
5135
|
*/
|
|
4765
|
-
function BalanceBadge({ getBalance, getCachedBalance, getSessionSpend, getTodaySpend, getTodaySessionsSpend, sessionId, useSession, useProjection, t }) {
|
|
4766
|
-
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({
|
|
4767
5138
|
getBalance,
|
|
4768
5139
|
getCachedBalance,
|
|
4769
5140
|
getSessionSpend,
|
|
4770
5141
|
getTodaySpend,
|
|
4771
5142
|
getTodaySessionsSpend,
|
|
5143
|
+
getDelegatedSpend,
|
|
4772
5144
|
sessionId,
|
|
4773
5145
|
useSession,
|
|
4774
5146
|
useProjection
|
|
@@ -4792,7 +5164,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4792
5164
|
}
|
|
4793
5165
|
const line = primaryLine(balance);
|
|
4794
5166
|
const amount = line === void 0 ? "—" : `${line.symbol}${line.total}`;
|
|
4795
|
-
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;
|
|
4796
5168
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
4797
5169
|
ref: rootRef,
|
|
4798
5170
|
className: BalanceBadge_module_css_default.root,
|
|
@@ -4808,6 +5180,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4808
5180
|
spend,
|
|
4809
5181
|
todaySpend,
|
|
4810
5182
|
sessionsSpend,
|
|
5183
|
+
isSubagent,
|
|
5184
|
+
crossedDay,
|
|
4811
5185
|
refreshing,
|
|
4812
5186
|
onRefresh: refresh,
|
|
4813
5187
|
t
|
|
@@ -4929,28 +5303,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4929
5303
|
const NS = "billing";
|
|
4930
5304
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
4931
5305
|
const zh = {
|
|
4932
|
-
"trigger.balance": "
|
|
4933
|
-
"trigger.conversationSpend": "本轮对话花费:{amount}",
|
|
5306
|
+
"trigger.balance": "剩余金额:{amount}",
|
|
4934
5307
|
"label.amount": "API 剩余金额:{amount}",
|
|
4935
5308
|
"label.sessionSpend": "本会话花费:{amount}",
|
|
4936
|
-
"label.sessionSpend.today": "
|
|
5309
|
+
"label.sessionSpend.today": " {amount}",
|
|
4937
5310
|
"label.todaySpend": "今日花费:{amount}",
|
|
4938
5311
|
"label.todayTokens": "今日 Token:{count}",
|
|
5312
|
+
"label.todayTokens.hit": " {percent}%",
|
|
4939
5313
|
"unit.tokens": "{count} tok",
|
|
4940
5314
|
"label.cost.input": "未缓存输入 {amount}",
|
|
4941
5315
|
"label.cost.cacheRead": "缓存读取 {amount}",
|
|
4942
5316
|
"label.cost.output": "输出 {amount}",
|
|
4943
5317
|
"card.title": "花费金额",
|
|
4944
|
-
"card.input": "未缓存输入",
|
|
4945
|
-
"card.cacheRead": "缓存读取",
|
|
4946
|
-
"card.output": "输出",
|
|
4947
5318
|
"card.aria": "本轮对话花费:{amount}",
|
|
5319
|
+
"label.bucket.input": "未缓存输入",
|
|
5320
|
+
"label.bucket.cacheRead": "缓存读取",
|
|
5321
|
+
"label.bucket.output": "输出",
|
|
4948
5322
|
"stat.none": "暂无消耗记录",
|
|
4949
5323
|
"stat.untitled": "未命名",
|
|
4950
5324
|
"state.unavailable": "额度不可用",
|
|
4951
5325
|
"action.refresh": "刷新",
|
|
4952
5326
|
"info.aria": "花费说明",
|
|
4953
|
-
"info.hint": "估算:仅 DeepSeek 与 MiMo 模型,按每条消息自身时刻的峰谷官方单价计价(高峰:工作日 9:00–12:00、14:00–18:00)。\n
|
|
5327
|
+
"info.hint": "估算:仅 DeepSeek 与 MiMo 模型,按每条消息自身时刻的峰谷官方单价计价(高峰:工作日 9:00–12:00、14:00–18:00)。\n金额含本会话委派的子代理会话。\n紧跟的数字为本会话今日花费。\nv{version}",
|
|
4954
5328
|
"badge.aria": "DeepSeek 额度:{amount}",
|
|
4955
5329
|
"panel.aria": "DeepSeek 额度详情",
|
|
4956
5330
|
"label.sessionRanking": "今日会话花费",
|
|
@@ -4959,27 +5333,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4959
5333
|
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
4960
5334
|
const en = {
|
|
4961
5335
|
"trigger.balance": "Balance: {amount}",
|
|
4962
|
-
"trigger.conversationSpend": "This conversation: {amount}",
|
|
4963
5336
|
"label.amount": "API balance: {amount}",
|
|
4964
5337
|
"label.sessionSpend": "This session: {amount}",
|
|
4965
|
-
"label.sessionSpend.today": "
|
|
5338
|
+
"label.sessionSpend.today": " {amount}",
|
|
4966
5339
|
"label.todaySpend": "Today spend: {amount}",
|
|
4967
5340
|
"label.todayTokens": "Today tokens: {count}",
|
|
5341
|
+
"label.todayTokens.hit": " {percent}%",
|
|
4968
5342
|
"unit.tokens": "{count} tok",
|
|
4969
5343
|
"label.cost.input": "Uncached input {amount}",
|
|
4970
5344
|
"label.cost.cacheRead": "Cached input {amount}",
|
|
4971
5345
|
"label.cost.output": "Output {amount}",
|
|
4972
5346
|
"card.title": "Spend",
|
|
4973
|
-
"card.input": "Uncached input",
|
|
4974
|
-
"card.cacheRead": "Cached input",
|
|
4975
|
-
"card.output": "Output",
|
|
4976
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",
|
|
4977
5351
|
"stat.none": "No usage recorded",
|
|
4978
5352
|
"stat.untitled": "Untitled",
|
|
4979
5353
|
"state.unavailable": "Balance unavailable",
|
|
4980
5354
|
"action.refresh": "Refresh",
|
|
4981
5355
|
"info.aria": "About this spend",
|
|
4982
|
-
"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
|
|
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}",
|
|
4983
5357
|
"badge.aria": "DeepSeek balance {amount}",
|
|
4984
5358
|
"panel.aria": "DeepSeek balance details",
|
|
4985
5359
|
"label.sessionRanking": "Today session spend",
|
|
@@ -5022,7 +5396,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5022
5396
|
getCachedBalance: () => lastBalance,
|
|
5023
5397
|
getSessionSpend: async (sessionId) => unwrap("billing.getSessionSpend", await billing.getSessionSpend(sessionId)),
|
|
5024
5398
|
getTodaySpend: async (force) => unwrap("billing.getTodaySpend", await billing.getTodaySpend(force)),
|
|
5025
|
-
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))
|
|
5026
5401
|
};
|
|
5027
5402
|
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
5028
5403
|
name: "conversation.session.header.utilities",
|