@narumitw/pi-usage 0.58.0 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.ts CHANGED
@@ -109,7 +109,7 @@ var UsageCache = class {
109
109
  this.sweepExpired(now);
110
110
  return this.entries.get(cacheKey(providerId, fingerprint))?.report;
111
111
  }
112
- set(providerId, fingerprint, report, now = Date.now()) {
112
+ set(providerId, fingerprint, report2, now = Date.now()) {
113
113
  this.sweepExpired(now);
114
114
  const key = cacheKey(providerId, fingerprint);
115
115
  this.entries.delete(key);
@@ -118,7 +118,7 @@ var UsageCache = class {
118
118
  if (oldest === void 0) break;
119
119
  this.entries.delete(oldest);
120
120
  }
121
- this.entries.set(key, { createdAt: now, report });
121
+ this.entries.set(key, { createdAt: now, report: report2 });
122
122
  }
123
123
  clearProvider(providerId) {
124
124
  for (const key of this.entries.keys()) {
@@ -328,13 +328,56 @@ function cloneOAuthCredential(value) {
328
328
  import { randomBytes } from "node:crypto";
329
329
  import { readStoredCredential as readStoredCredential2 } from "@earendil-works/pi-coding-agent";
330
330
 
331
+ // src/providers/baseten.ts
332
+ var DECIMAL_AMOUNT = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u;
333
+ function normalizeBasetenBillingUsagePayload(payload, capturedAt) {
334
+ if (payload.model_apis_usage === void 0 || payload.model_apis_usage === null) {
335
+ return report(capturedAt, [], ["Baseten returned no Model APIs usage for the last 30 days."]);
336
+ }
337
+ const usage = asObject(payload.model_apis_usage);
338
+ if (!usage) throw new Error("Baseten Model APIs usage was not an object.");
339
+ const metrics = [
340
+ metric("gross-usage", "Gross usage", usage.total),
341
+ metric("credits-used", "Credits used", usage.credits_used),
342
+ metric("net-subtotal", "Net subtotal", usage.subtotal)
343
+ ];
344
+ return report(capturedAt, metrics);
345
+ }
346
+ function report(capturedAt, metrics, notes) {
347
+ return {
348
+ providerId: "baseten",
349
+ providerName: "Baseten",
350
+ capturedAt,
351
+ source: "baseten-billing-usage-summary",
352
+ semantics: { kind: "api-key", label: "Organization Model APIs spend" },
353
+ buckets: [],
354
+ metrics,
355
+ ...notes ? { notes } : {}
356
+ };
357
+ }
358
+ function metric(id, label, value) {
359
+ const amount2 = decimalAmount(value, label);
360
+ return { id, label, value: amount2, unit: "currency", currency: "USD" };
361
+ }
362
+ function decimalAmount(value, label) {
363
+ const normalized = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
364
+ if (typeof normalized !== "string" || normalized.length > 64 || !DECIMAL_AMOUNT.test(normalized)) {
365
+ throw new Error(`Baseten ${label.toLowerCase()} was not a valid nonnegative amount.`);
366
+ }
367
+ return normalized;
368
+ }
369
+ function asObject(value) {
370
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
371
+ return value;
372
+ }
373
+
331
374
  // src/providers/codex.ts
332
375
  function normalizeCodexBackendPayload(payload, capturedAt) {
333
376
  const buckets = [];
334
377
  normalizeRateLimitGroup(buckets, "codex", "Codex", payload.rate_limit, false);
335
378
  const additional = Array.isArray(payload.additional_rate_limits) ? payload.additional_rate_limits : [];
336
379
  for (const item of additional) {
337
- const value = asObject(item);
380
+ const value = asObject2(item);
338
381
  const id = asString(value?.metered_feature) ?? asString(value?.limit_name);
339
382
  if (!value || !id) continue;
340
383
  try {
@@ -349,7 +392,7 @@ function normalizeCodexBackendPayload(payload, capturedAt) {
349
392
  }
350
393
  }
351
394
  const metrics = [];
352
- const credits = asObject(payload.credits);
395
+ const credits = asObject2(payload.credits);
353
396
  if (credits?.has_credits === true) {
354
397
  if (credits.unlimited === true) {
355
398
  metrics.push({ id: "credits", label: "Credits", value: "unlimited" });
@@ -364,7 +407,7 @@ function normalizeCodexBackendPayload(payload, capturedAt) {
364
407
  } else if (credits?.has_credits === false) {
365
408
  metrics.push({ id: "credits", label: "Credits", value: "none" });
366
409
  }
367
- const resetCredits = asObject(payload.rate_limit_reset_credits);
410
+ const resetCredits = asObject2(payload.rate_limit_reset_credits);
368
411
  const resetCount = asNonnegativeInteger(resetCredits?.available_count);
369
412
  if (resetCount !== void 0) {
370
413
  metrics.push({
@@ -394,7 +437,7 @@ function normalizeCodexBackendPayload(payload, capturedAt) {
394
437
  }
395
438
  function normalizeRateLimitGroup(buckets, groupId, groupLabel, raw, optional) {
396
439
  if (raw === void 0 || raw === null) return;
397
- const details = asObject(raw);
440
+ const details = asObject2(raw);
398
441
  if (!details) {
399
442
  if (optional) return;
400
443
  throw new Error("Codex rate limit was not an object.");
@@ -404,7 +447,7 @@ function normalizeRateLimitGroup(buckets, groupId, groupLabel, raw, optional) {
404
447
  }
405
448
  function addWindow(buckets, groupId, groupLabel, position, raw) {
406
449
  if (raw === void 0 || raw === null) return;
407
- const value = asObject(raw);
450
+ const value = asObject2(raw);
408
451
  if (!value) throw new Error("Codex rate-limit window was not an object.");
409
452
  const used = asNumber(value.used_percent);
410
453
  if (used === void 0) return;
@@ -424,7 +467,7 @@ function addWindow(buckets, groupId, groupLabel, position, raw) {
424
467
  ...resetsAt !== void 0 ? { resetsAt } : {}
425
468
  });
426
469
  }
427
- function asObject(value) {
470
+ function asObject2(value) {
428
471
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
429
472
  return value;
430
473
  }
@@ -465,7 +508,7 @@ function normalizeDeepSeekBalancePayload(payload, capturedAt) {
465
508
  }
466
509
  const balances = /* @__PURE__ */ new Map();
467
510
  for (const raw of payload.balance_infos) {
468
- const balance = asObject2(raw);
511
+ const balance = asObject3(raw);
469
512
  if (!balance) throw new Error("DeepSeek API balance row was not an object.");
470
513
  const currency = deepSeekCurrency(balance.currency);
471
514
  if (!currency) throw new Error("DeepSeek API balance row returned an unsupported currency.");
@@ -473,7 +516,7 @@ function normalizeDeepSeekBalancePayload(payload, capturedAt) {
473
516
  throw new Error(`DeepSeek API balance response repeated ${currency}.`);
474
517
  }
475
518
  for (const [, label, field] of BALANCE_FIELDS) {
476
- if (!decimalAmount(balance[field])) {
519
+ if (!decimalAmount2(balance[field])) {
477
520
  throw new Error(`DeepSeek API balance ${label.toLowerCase()} was not a valid amount.`);
478
521
  }
479
522
  }
@@ -509,14 +552,14 @@ function normalizeDeepSeekBalancePayload(payload, capturedAt) {
509
552
  metrics
510
553
  };
511
554
  }
512
- function asObject2(value) {
555
+ function asObject3(value) {
513
556
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
514
557
  return value;
515
558
  }
516
559
  function deepSeekCurrency(value) {
517
560
  return CURRENCIES.find((currency) => currency === value);
518
561
  }
519
- function decimalAmount(value) {
562
+ function decimalAmount2(value) {
520
563
  return typeof value === "string" && value.length <= 64 && /^(?:0|[1-9]\d*)(?:\.\d+)?$/u.test(value);
521
564
  }
522
565
 
@@ -545,7 +588,7 @@ function normalizeFireworksAccountsPayload(payload) {
545
588
  }
546
589
  const accounts = [];
547
590
  for (const raw of payload.accounts) {
548
- const account = asObject3(raw);
591
+ const account = asObject4(raw);
549
592
  if (!account) throw new Error("Fireworks accounts response row was not an object.");
550
593
  if (typeof account.name !== "string") {
551
594
  throw new Error("Fireworks accounts response omitted the account resource name.");
@@ -571,7 +614,7 @@ function normalizeFireworksBillingSummaryPayload(payload, accountId, capturedAt)
571
614
  }
572
615
  const totals = /* @__PURE__ */ new Map();
573
616
  for (const raw of payload.lineItems ?? []) {
574
- const lineItem = asObject3(raw);
617
+ const lineItem = asObject4(raw);
575
618
  if (!lineItem) throw new Error("Fireworks billing line item was not an object.");
576
619
  const cost = moneyAmount(lineItem.totalCost, "line item total cost");
577
620
  const series = seriesKey(lineItem.series);
@@ -592,12 +635,12 @@ function normalizeFireworksBillingSummaryPayload(payload, accountId, capturedAt)
592
635
  currency
593
636
  });
594
637
  for (const series of SERIES_KEYS) {
595
- const amount = amounts.get(series);
596
- if (amount === void 0) continue;
638
+ const amount2 = amounts.get(series);
639
+ if (amount2 === void 0) continue;
597
640
  metrics.push({
598
641
  id: `${currency.toLowerCase()}-${series}`,
599
642
  label: SERIES_LABELS[series],
600
- value: formatMoneyAmount(amount),
643
+ value: formatMoneyAmount(amount2),
601
644
  unit: "currency",
602
645
  currency
603
646
  });
@@ -622,7 +665,7 @@ function normalizeFireworksBillingSummaryPayload(payload, accountId, capturedAt)
622
665
  };
623
666
  }
624
667
  function moneyAmount(value, description) {
625
- const money = asObject3(value);
668
+ const money = asObject4(value);
626
669
  if (!money) throw new Error(`Fireworks billing ${description} was not a money object.`);
627
670
  const currency = typeof money.currencyCode === "string" ? money.currencyCode : void 0;
628
671
  if (!currency || !CURRENCY_PATTERN.test(currency)) {
@@ -658,25 +701,25 @@ function seriesKey(value) {
658
701
  }
659
702
  function sumSeries(amounts) {
660
703
  let total = 0n;
661
- for (const amount of amounts.values()) total += amount;
704
+ for (const amount2 of amounts.values()) total += amount2;
662
705
  return total;
663
706
  }
664
- function formatMoneyAmount(amount) {
665
- const negative = amount < 0n;
666
- const magnitude = negative ? -amount : amount;
707
+ function formatMoneyAmount(amount2) {
708
+ const negative = amount2 < 0n;
709
+ const magnitude = negative ? -amount2 : amount2;
667
710
  const units = magnitude / NANOS_PER_UNIT;
668
711
  const nanos = (magnitude % NANOS_PER_UNIT).toString().padStart(9, "0").replace(/0+$/u, "");
669
712
  return `${negative ? "-" : ""}${units.toString()}${nanos ? `.${nanos}` : ""}`;
670
713
  }
671
- function asObject3(value) {
714
+ function asObject4(value) {
672
715
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
673
716
  return value;
674
717
  }
675
718
 
676
719
  // src/providers/github-copilot.ts
677
720
  function normalizeGitHubCopilotUsagePayload(payload, capturedAt) {
678
- const snapshots = asObject4(payload.quota_snapshots);
679
- const premium = asObject4(snapshots?.premium_interactions);
721
+ const snapshots = asObject5(payload.quota_snapshots);
722
+ const premium = asObject5(snapshots?.premium_interactions);
680
723
  const metrics = [];
681
724
  let semanticsLabel;
682
725
  let bucket;
@@ -717,8 +760,8 @@ function normalizeGitHubCopilotUsagePayload(payload, capturedAt) {
717
760
  };
718
761
  }
719
762
  } else {
720
- const limited = asObject4(payload.limited_user_quotas);
721
- const monthly = asObject4(payload.monthly_quotas);
763
+ const limited = asObject5(payload.limited_user_quotas);
764
+ const monthly = asObject5(payload.monthly_quotas);
722
765
  const remaining = asNonnegativeNumber(limited?.chat);
723
766
  const entitlement = asNonnegativeNumber(monthly?.chat);
724
767
  if (remaining === void 0 || entitlement === void 0) {
@@ -757,7 +800,7 @@ function resetTimestamp(payload) {
757
800
  const milliseconds = Date.parse(raw);
758
801
  return Number.isNaN(milliseconds) ? {} : { resetsAt: Math.floor(milliseconds / 1e3) };
759
802
  }
760
- function asObject4(value) {
803
+ function asObject5(value) {
761
804
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
762
805
  return value;
763
806
  }
@@ -780,7 +823,7 @@ var DAILY_WINDOW_MINUTES = 1440;
780
823
  var WEEKLY_WINDOW_MINUTES = 10080;
781
824
  var FIXED_POINT_UNITS_PER_CENT = 1e6;
782
825
  function normalizeKimiCodingUsagePayload(payload, capturedAt) {
783
- const root = asObject5(payload);
826
+ const root = asObject6(payload);
784
827
  if (!root) throw new Error("Kimi Coding usage response was not an object.");
785
828
  const candidates = [];
786
829
  let omittedWindow = false;
@@ -789,7 +832,7 @@ function normalizeKimiCodingUsagePayload(payload, capturedAt) {
789
832
  else if (root.usage !== void 0) omittedWindow = true;
790
833
  if (Array.isArray(root.limits)) {
791
834
  for (const raw of root.limits) {
792
- const item = asObject5(raw);
835
+ const item = asObject6(raw);
793
836
  const windowMinutes = parseWindowMinutes(item?.window);
794
837
  const label = sanitizedLabel(item?.name);
795
838
  const bucket = windowMinutes === void 0 ? void 0 : parseUsageRow(item?.detail, windowMinutes, label ?? defaultWindowLabel(windowMinutes));
@@ -826,7 +869,7 @@ function normalizeKimiCodingUsagePayload(payload, capturedAt) {
826
869
  };
827
870
  }
828
871
  function parseUsageRow(value, windowMinutes, label) {
829
- const row = asObject5(value);
872
+ const row = asObject6(value);
830
873
  if (!row) return void 0;
831
874
  const used = asNonnegativeInteger2(row.used);
832
875
  const limit = asNonnegativeInteger2(row.limit);
@@ -844,7 +887,7 @@ function parseUsageRow(value, windowMinutes, label) {
844
887
  };
845
888
  }
846
889
  function parseWindowMinutes(value) {
847
- const window = asObject5(value);
890
+ const window = asObject6(value);
848
891
  if (!window) return void 0;
849
892
  const duration = asPositiveInteger(window.duration);
850
893
  if (duration === void 0) return void 0;
@@ -854,8 +897,8 @@ function parseWindowMinutes(value) {
854
897
  return Number.isSafeInteger(minutes) ? minutes : void 0;
855
898
  }
856
899
  function parseBoosterWallet(value) {
857
- const wallet = asObject5(value);
858
- const balance = asObject5(wallet?.balance);
900
+ const wallet = asObject6(value);
901
+ const balance = asObject6(wallet?.balance);
859
902
  if (!wallet || !balance || balance.type !== "BOOSTER") return [];
860
903
  const totalRaw = asPositiveInteger(balance.amount);
861
904
  if (totalRaw === void 0) return [];
@@ -906,7 +949,7 @@ function parseBoosterWallet(value) {
906
949
  return metrics;
907
950
  }
908
951
  function parseMoney(value) {
909
- const money = asObject5(value);
952
+ const money = asObject6(value);
910
953
  if (!money) return void 0;
911
954
  const cents = asNonnegativeInteger2(money.priceInCents);
912
955
  if (cents === void 0) return void 0;
@@ -920,7 +963,7 @@ function fixedPointToMajor(value) {
920
963
  const major = roundedCents / 100;
921
964
  return Number.isSafeInteger(roundedCents) && Number.isFinite(major) ? major : void 0;
922
965
  }
923
- function asObject5(value) {
966
+ function asObject6(value) {
924
967
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
925
968
  return value;
926
969
  }
@@ -987,6 +1030,246 @@ function defaultWindowLabel(minutes) {
987
1030
  return `${minutes}m window`;
988
1031
  }
989
1032
 
1033
+ // src/providers/minimax.ts
1034
+ var PROVIDERS = {
1035
+ minimax: { name: "MiniMax", currency: "USD" },
1036
+ "minimax-cn": { name: "MiniMax CN", currency: "CNY" }
1037
+ };
1038
+ var DECIMAL_AMOUNT2 = /^-?(?:0|[1-9]\d*)(?:\.\d+)?$/u;
1039
+ var PERCENT_TOLERANCE = 1;
1040
+ function miniMaxUsageKind(apiKey) {
1041
+ return apiKey.startsWith("sk-api-") ? "account-balance" : "token-plan";
1042
+ }
1043
+ function normalizeMiniMaxUsagePayload(providerId, kind, payload, capturedAt) {
1044
+ return kind === "account-balance" ? normalizeBalance(providerId, payload, capturedAt) : normalizeTokenPlan(providerId, payload, capturedAt);
1045
+ }
1046
+ function normalizeBalance(providerId, payload, capturedAt) {
1047
+ assertSuccess(payload);
1048
+ const provider = PROVIDERS[providerId];
1049
+ const metrics = [
1050
+ balanceMetric(
1051
+ "available-balance",
1052
+ "Available balance",
1053
+ payload.available_amount,
1054
+ provider.currency
1055
+ ),
1056
+ balanceMetric("cash-balance", "Cash balance", payload.cash_balance, provider.currency, true),
1057
+ balanceMetric("voucher-balance", "Voucher balance", payload.voucher_balance, provider.currency),
1058
+ balanceMetric("credit-balance", "Credit balance", payload.credit_balance, provider.currency),
1059
+ balanceMetric("owed-amount", "Owed amount", payload.owed_amount, provider.currency)
1060
+ ];
1061
+ return {
1062
+ providerId,
1063
+ providerName: provider.name,
1064
+ capturedAt,
1065
+ source: "minimax-account-balance",
1066
+ semantics: { kind: "api-key", label: "MiniMax pay-as-you-go account balance" },
1067
+ buckets: [],
1068
+ metrics
1069
+ };
1070
+ }
1071
+ function normalizeTokenPlan(providerId, payload, capturedAt) {
1072
+ assertSuccess(payload);
1073
+ if (!Array.isArray(payload.model_remains) || payload.model_remains.length === 0) {
1074
+ throw new Error("MiniMax Token Plan returned no quota rows.");
1075
+ }
1076
+ const provider = PROVIDERS[providerId];
1077
+ const buckets = [];
1078
+ const groups = /* @__PURE__ */ new Set();
1079
+ for (const [index, raw] of payload.model_remains.entries()) {
1080
+ const row = asObject7(raw);
1081
+ if (!row) throw new Error("MiniMax Token Plan quota row was not an object.");
1082
+ const groupLabel = safeLabel(row.model_name, `Quota ${index + 1}`);
1083
+ const groupId = uniqueGroupId(groupLabel, index, groups);
1084
+ buckets.push(
1085
+ normalizeWindow(row, {
1086
+ id: `${groupId}:interval`,
1087
+ label: "Rolling window",
1088
+ groupId,
1089
+ groupLabel,
1090
+ countField: "current_interval_usage_count",
1091
+ totalField: "current_interval_total_count",
1092
+ percentField: "current_interval_remaining_percent",
1093
+ statusField: "current_interval_status",
1094
+ startField: "start_time",
1095
+ endField: "end_time"
1096
+ }),
1097
+ normalizeWindow(row, {
1098
+ id: `${groupId}:weekly`,
1099
+ label: "Weekly window",
1100
+ groupId,
1101
+ groupLabel,
1102
+ countField: "current_weekly_usage_count",
1103
+ totalField: "current_weekly_total_count",
1104
+ percentField: "current_weekly_remaining_percent",
1105
+ statusField: "current_weekly_status",
1106
+ startField: "weekly_start_time",
1107
+ endField: "weekly_end_time",
1108
+ boostPermille: row.weekly_boost_permille
1109
+ })
1110
+ );
1111
+ }
1112
+ return {
1113
+ providerId,
1114
+ providerName: provider.name,
1115
+ capturedAt,
1116
+ source: "minimax-token-plan",
1117
+ semantics: { kind: "consumer-subscription", label: "MiniMax Token Plan quota" },
1118
+ buckets,
1119
+ metrics: []
1120
+ };
1121
+ }
1122
+ function normalizeWindow(row, fields) {
1123
+ const status = optionalInteger(row[fields.statusField], fields.statusField);
1124
+ if (status !== void 0 && ![1, 2, 3].includes(status)) {
1125
+ throw new Error(`MiniMax Token Plan ${fields.label} status was unsupported.`);
1126
+ }
1127
+ const percent = optionalPercent(row[fields.percentField], fields.percentField);
1128
+ validateBoost(fields.boostPermille);
1129
+ const start = timestamp(row[fields.startField], fields.startField);
1130
+ const end = timestamp(row[fields.endField], fields.endField);
1131
+ if (end < start) throw new Error(`MiniMax Token Plan ${fields.label} timestamps were reversed.`);
1132
+ const resetsAt = Math.floor(end / 1e3);
1133
+ const windowMinutes = Math.max(1, Math.round((end - start) / 6e4));
1134
+ if (status === 3) {
1135
+ return {
1136
+ id: fields.id,
1137
+ label: fields.label,
1138
+ groupId: fields.groupId,
1139
+ groupLabel: fields.groupLabel,
1140
+ remaining: 100,
1141
+ unit: "percent",
1142
+ period: "unlimited",
1143
+ windowMinutes
1144
+ };
1145
+ }
1146
+ const total = nonnegativeInteger(row[fields.totalField], fields.totalField);
1147
+ const count = nonnegativeInteger(row[fields.countField], fields.countField);
1148
+ const resolved = resolveQuotaCounts(count, total, percent);
1149
+ if (!resolved) throw new Error(`MiniMax Token Plan ${fields.label} counts were inconsistent.`);
1150
+ return {
1151
+ id: fields.id,
1152
+ label: fields.label,
1153
+ groupId: fields.groupId,
1154
+ groupLabel: fields.groupLabel,
1155
+ ...resolved,
1156
+ unit: "count",
1157
+ windowMinutes,
1158
+ resetsAt
1159
+ };
1160
+ }
1161
+ function resolveQuotaCounts(reportedCount, total, remainingPercent) {
1162
+ if (total <= 0 || reportedCount > total) return void 0;
1163
+ let remaining = reportedCount;
1164
+ if (remainingPercent !== void 0) {
1165
+ const asRemaining = reportedCount / total * 100;
1166
+ const asUsed = (total - reportedCount) / total * 100;
1167
+ const remainingDistance = Math.abs(asRemaining - remainingPercent);
1168
+ const usedDistance = Math.abs(asUsed - remainingPercent);
1169
+ if (Math.min(remainingDistance, usedDistance) > PERCENT_TOLERANCE) return void 0;
1170
+ if (usedDistance < remainingDistance) remaining = total - reportedCount;
1171
+ }
1172
+ return { used: total - remaining, remaining, limit: total };
1173
+ }
1174
+ function assertSuccess(payload) {
1175
+ const base = asObject7(payload.base_resp);
1176
+ if (base?.status_code !== 0) {
1177
+ throw new Error("MiniMax usage response did not report success.");
1178
+ }
1179
+ }
1180
+ function balanceMetric(id, label, value, currency, allowNegative = false) {
1181
+ if (typeof value !== "string" || value.length > 64 || !DECIMAL_AMOUNT2.test(value) || !allowNegative && value.startsWith("-")) {
1182
+ throw new Error(`MiniMax ${label.toLowerCase()} was not a valid amount.`);
1183
+ }
1184
+ return { id, label, value, unit: "currency", currency };
1185
+ }
1186
+ function asObject7(value) {
1187
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1188
+ return value;
1189
+ }
1190
+ function safeLabel(value, fallback) {
1191
+ if (typeof value !== "string") throw new Error("MiniMax Token Plan model name was not a string.");
1192
+ return sanitizeDisplayText(value, 80) || fallback;
1193
+ }
1194
+ function uniqueGroupId(label, index, groups) {
1195
+ const base = label.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-|-$/gu, "") || "quota";
1196
+ const id = groups.has(base) ? `${base}-${index + 1}` : base;
1197
+ groups.add(id);
1198
+ return id;
1199
+ }
1200
+ function nonnegativeInteger(value, field) {
1201
+ if (!Number.isSafeInteger(value) || value < 0) {
1202
+ throw new Error(`MiniMax Token Plan ${field} was not a nonnegative safe integer.`);
1203
+ }
1204
+ return value;
1205
+ }
1206
+ function optionalInteger(value, field) {
1207
+ if (value === void 0 || value === null) return void 0;
1208
+ return nonnegativeInteger(value, field);
1209
+ }
1210
+ function optionalPercent(value, field) {
1211
+ if (value === void 0 || value === null) return void 0;
1212
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 100) {
1213
+ throw new Error(`MiniMax Token Plan ${field} was not a percentage.`);
1214
+ }
1215
+ return value;
1216
+ }
1217
+ function validateBoost(boost) {
1218
+ if (boost === void 0 || boost === null) return;
1219
+ const permille = nonnegativeInteger(boost, "weekly_boost_permille");
1220
+ if (permille > 1e4) throw new Error("MiniMax Token Plan weekly boost was unreasonable.");
1221
+ }
1222
+ function timestamp(value, field) {
1223
+ if (!Number.isSafeInteger(value) || value <= 0) {
1224
+ throw new Error(`MiniMax Token Plan ${field} was not a valid timestamp.`);
1225
+ }
1226
+ return value;
1227
+ }
1228
+
1229
+ // src/providers/moonshot.ts
1230
+ var PROVIDERS2 = {
1231
+ moonshotai: { name: "Moonshot AI", currency: "USD" },
1232
+ "moonshotai-cn": { name: "Moonshot AI CN", currency: "CNY" }
1233
+ };
1234
+ function normalizeMoonshotBalancePayload(providerId, payload, capturedAt) {
1235
+ if (payload.code !== 0 || payload.status !== true) {
1236
+ throw new Error("Moonshot AI balance response did not report success.");
1237
+ }
1238
+ const data = asObject8(payload.data);
1239
+ if (!data) throw new Error("Moonshot AI balance response data was not an object.");
1240
+ const provider = PROVIDERS2[providerId];
1241
+ const available = amount(data.available_balance, "available balance", false);
1242
+ const voucher = amount(data.voucher_balance, "voucher balance", false);
1243
+ const cash = amount(data.cash_balance, "cash balance", true);
1244
+ const metrics = [
1245
+ currencyMetric("available-balance", "Available balance", available, provider.currency),
1246
+ currencyMetric("voucher-balance", "Voucher balance", voucher, provider.currency),
1247
+ currencyMetric("cash-balance", "Cash balance", cash, provider.currency)
1248
+ ];
1249
+ return {
1250
+ providerId,
1251
+ providerName: provider.name,
1252
+ capturedAt,
1253
+ source: "moonshot-balance",
1254
+ semantics: { kind: "api-key", label: "Moonshot API account balance" },
1255
+ buckets: [],
1256
+ metrics
1257
+ };
1258
+ }
1259
+ function currencyMetric(id, label, value, currency) {
1260
+ return { id, label, value, unit: "currency", currency };
1261
+ }
1262
+ function asObject8(value) {
1263
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1264
+ return value;
1265
+ }
1266
+ function amount(value, label, allowNegative) {
1267
+ if (typeof value !== "number" || !Number.isFinite(value) || !allowNegative && value < 0 || Math.abs(value) > Number.MAX_SAFE_INTEGER) {
1268
+ throw new Error(`Moonshot AI ${label} was not a valid amount.`);
1269
+ }
1270
+ return String(value);
1271
+ }
1272
+
990
1273
  // src/providers/opencode-zen.ts
991
1274
  var ZEN_WINDOWS = [
992
1275
  { key: "rolling", label: "Rolling" },
@@ -994,12 +1277,12 @@ var ZEN_WINDOWS = [
994
1277
  { key: "monthly", label: "Monthly" }
995
1278
  ];
996
1279
  function normalizeOpenCodeZenPayload(payload, capturedAt) {
997
- const usage = asObject6(payload.usage);
1280
+ const usage = asObject9(payload.usage);
998
1281
  if (!usage) throw new Error("OpenCode Zen usage response was not an object.");
999
1282
  const buckets = [];
1000
1283
  const notes = [];
1001
1284
  for (const window of ZEN_WINDOWS) {
1002
- const raw = asObject6(usage[window.key]);
1285
+ const raw = asObject9(usage[window.key]);
1003
1286
  if (!raw) continue;
1004
1287
  const status = asString3(raw.status);
1005
1288
  if (status !== "ok" && status !== "rate-limited") {
@@ -1036,7 +1319,7 @@ function normalizeOpenCodeZenPayload(payload, capturedAt) {
1036
1319
  ...notes.length > 0 ? { notes } : {}
1037
1320
  };
1038
1321
  }
1039
- function asObject6(value) {
1322
+ function asObject9(value) {
1040
1323
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1041
1324
  return value;
1042
1325
  }
@@ -1060,7 +1343,7 @@ function clampPercent2(value) {
1060
1343
 
1061
1344
  // src/providers/openrouter.ts
1062
1345
  function normalizeOpenRouterKeyPayload(payload, capturedAt) {
1063
- const data = asObject7(payload.data);
1346
+ const data = asObject10(payload.data);
1064
1347
  if (!data) throw new Error("OpenRouter key response data was not an object.");
1065
1348
  const limit = asNonnegativeNumber3(data.limit);
1066
1349
  const remaining = asNonnegativeNumber3(data.limit_remaining);
@@ -1102,11 +1385,11 @@ function normalizeOpenRouterKeyPayload(payload, capturedAt) {
1102
1385
  };
1103
1386
  }
1104
1387
  function addUsageMetric(metrics, id, label, value) {
1105
- const amount = typeof value === "number" ? asNonnegativeNumber3(value) : void 0;
1106
- if (amount === void 0) return;
1107
- metrics.push({ id, label, value: amount, unit: "usd" });
1388
+ const amount2 = typeof value === "number" ? asNonnegativeNumber3(value) : void 0;
1389
+ if (amount2 === void 0) return;
1390
+ metrics.push({ id, label, value: amount2, unit: "usd" });
1108
1391
  }
1109
- function asObject7(value) {
1392
+ function asObject10(value) {
1110
1393
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1111
1394
  return value;
1112
1395
  }
@@ -1119,6 +1402,44 @@ function asNonnegativeNumber3(value) {
1119
1402
  return value;
1120
1403
  }
1121
1404
 
1405
+ // src/providers/vercel-ai-gateway.ts
1406
+ var DECIMAL_AMOUNT3 = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u;
1407
+ function normalizeVercelAIGatewayCreditsPayload(payload, capturedAt) {
1408
+ const balance = decimalAmount3(payload.balance, "balance");
1409
+ const totalUsed = decimalAmount3(payload.total_used, "total used");
1410
+ const metrics = [
1411
+ {
1412
+ id: "credit-balance",
1413
+ label: "Credit balance",
1414
+ value: balance,
1415
+ unit: "currency",
1416
+ currency: "USD"
1417
+ },
1418
+ {
1419
+ id: "lifetime-spend",
1420
+ label: "Lifetime spend",
1421
+ value: totalUsed,
1422
+ unit: "currency",
1423
+ currency: "USD"
1424
+ }
1425
+ ];
1426
+ return {
1427
+ providerId: "vercel-ai-gateway",
1428
+ providerName: "Vercel AI Gateway",
1429
+ capturedAt,
1430
+ source: "vercel-ai-gateway-credits",
1431
+ semantics: { kind: "api-key", label: "AI Gateway credits and lifetime spend" },
1432
+ buckets: [],
1433
+ metrics
1434
+ };
1435
+ }
1436
+ function decimalAmount3(value, label) {
1437
+ if (typeof value !== "string" || value.length > 64 || !DECIMAL_AMOUNT3.test(value)) {
1438
+ throw new Error(`Vercel AI Gateway ${label} was not a valid nonnegative amount.`);
1439
+ }
1440
+ return value;
1441
+ }
1442
+
1122
1443
  // src/providers/xai.ts
1123
1444
  var MAX_SAFE_CENTS = Number.MAX_SAFE_INTEGER;
1124
1445
  function normalizeXaiBillingPayload(payload, subscriptionTier, capturedAt) {
@@ -1136,7 +1457,7 @@ function normalizeXaiBillingPayload(payload, subscriptionTier, capturedAt) {
1136
1457
  config.billingPeriodStart,
1137
1458
  config.billingPeriodEnd
1138
1459
  );
1139
- const preferredPercent = optionalPercent(config.creditUsagePercent, "creditUsagePercent");
1460
+ const preferredPercent = optionalPercent2(config.creditUsagePercent, "creditUsagePercent");
1140
1461
  if (preferredPercent !== void 0) {
1141
1462
  buckets.push({
1142
1463
  id: "included-allowance",
@@ -1246,7 +1567,7 @@ function optionalUsd(value, field) {
1246
1567
  }
1247
1568
  return cents / 100;
1248
1569
  }
1249
- function optionalPercent(value, field) {
1570
+ function optionalPercent2(value, field) {
1250
1571
  if (value === void 0 || value === null) return void 0;
1251
1572
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 100) {
1252
1573
  throw new Error(`xAI billing ${field} was outside 0\u2013100.`);
@@ -1284,13 +1605,13 @@ function isRecord2(value) {
1284
1605
  var FIVE_HOUR_WINDOW_MINUTES2 = 300;
1285
1606
  var WEEKLY_WINDOW_MINUTES2 = 10080;
1286
1607
  function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt) {
1287
- const data = asObject8(payload.data);
1608
+ const data = asObject11(payload.data);
1288
1609
  if (!data) throw new Error("Z.AI quota response data was not an object.");
1289
1610
  const limits = Array.isArray(data.limits) ? data.limits : [];
1290
1611
  const buckets = [];
1291
1612
  const metrics = [];
1292
1613
  for (const raw of limits) {
1293
- const limit = asObject8(raw);
1614
+ const limit = asObject11(raw);
1294
1615
  if (!limit) continue;
1295
1616
  const type = asString5(limit.type);
1296
1617
  const unit = asNonnegativeNumber4(limit.unit);
@@ -1362,7 +1683,7 @@ function addCountBucket(buckets, limit, id, label, windowMinutes) {
1362
1683
  function addUsageDetailMetrics(metrics, value) {
1363
1684
  if (!Array.isArray(value)) return;
1364
1685
  for (const raw of value) {
1365
- const detail = asObject8(raw);
1686
+ const detail = asObject11(raw);
1366
1687
  if (!detail) continue;
1367
1688
  const label = asString5(detail.modelCode);
1368
1689
  const usage = asNonnegativeNumber4(detail.usage);
@@ -1370,7 +1691,7 @@ function addUsageDetailMetrics(metrics, value) {
1370
1691
  metrics.push({ id: `mcp-${kebabCase(label)}`, label, value: usage, unit: "count" });
1371
1692
  }
1372
1693
  }
1373
- function asObject8(value) {
1694
+ function asObject11(value) {
1374
1695
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1375
1696
  return value;
1376
1697
  }
@@ -1395,6 +1716,8 @@ function clampPercent3(value) {
1395
1716
  }
1396
1717
 
1397
1718
  // src/query.ts
1719
+ var BASETEN_BILLING_USAGE_URL = "https://api.baseten.co/v1/billing/usage_summary";
1720
+ var BASETEN_USAGE_WINDOW_DAYS = 30;
1398
1721
  var CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
1399
1722
  var DEEPSEEK_BALANCE_URL = "https://api.deepseek.com/user/balance";
1400
1723
  var FIREWORKS_BILLING_SUMMARY_ORIGIN = "https://api.fireworks.ai";
@@ -1402,8 +1725,18 @@ var FIREWORKS_SPEND_WINDOW_DAYS = 30;
1402
1725
  var FIREWORKS_MAX_ACCOUNT_PAGES = 5;
1403
1726
  var GITHUB_COPILOT_USAGE_URL = "https://api.github.com/copilot_internal/user";
1404
1727
  var OPENROUTER_KEY_URL = "https://openrouter.ai/api/v1/key";
1728
+ var VERCEL_AI_GATEWAY_CREDITS_URL = "https://ai-gateway.vercel.sh/v1/credits";
1405
1729
  var OPENCODE_GO_USAGE_URL = "https://opencode.ai/zen/go/v1/usage";
1406
1730
  var KIMI_CODING_USAGE_URL = "https://api.kimi.com/coding/v1/usages";
1731
+ var MINIMAX_API_ROOTS = Object.freeze({
1732
+ minimax: "https://api.minimax.io",
1733
+ "minimax-cn": "https://api.minimaxi.com"
1734
+ });
1735
+ var MOONSHOT_BALANCE_URLS = Object.freeze({
1736
+ moonshotai: "https://api.moonshot.ai/v1/users/me/balance",
1737
+ "moonshotai-cn": "https://api.moonshot.cn/v1/users/me/balance"
1738
+ });
1739
+ var SHARED_MOONSHOT_ENV_VAR = "MOONSHOT_API_KEY";
1407
1740
  var XAI_USER_URL = "https://cli-chat-proxy.grok.com/v1/user?include=subscription";
1408
1741
  var XAI_BILLING_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
1409
1742
  var XAI_CLIENT_HEADERS = Object.freeze({
@@ -1415,6 +1748,27 @@ var MAX_SUCCESS_BODY_BYTES = 64 * 1024;
1415
1748
  var MAX_ERROR_BODY_BYTES = 4 * 1024;
1416
1749
  var AUTH_FINGERPRINT_SALT = randomBytes(32);
1417
1750
  var SUPPORTED_ADAPTERS = [
1751
+ {
1752
+ id: "baseten",
1753
+ displayName: "Baseten",
1754
+ semantics: { kind: "api-key", label: "Organization Model APIs spend" },
1755
+ async query(auth, signal, timeoutMs, guard) {
1756
+ if (!guard) throw new Error("Baseten billing usage requires request-boundary revalidation.");
1757
+ const startedAt = Date.now();
1758
+ await guard();
1759
+ const windowAt = Date.now();
1760
+ const payload = await fetchProviderJson(
1761
+ basetenBillingUsageUrl(windowAt),
1762
+ auth,
1763
+ signal,
1764
+ remainingTimeout(timeoutMs, startedAt, "fetching Baseten billing usage"),
1765
+ "Baseten billing usage endpoint",
1766
+ { redirect: "error" }
1767
+ );
1768
+ await guard();
1769
+ return normalizeBasetenBillingUsagePayload(payload, Date.now());
1770
+ }
1771
+ },
1418
1772
  {
1419
1773
  id: "openai-codex",
1420
1774
  displayName: "OpenAI Codex",
@@ -1487,6 +1841,27 @@ var SUPPORTED_ADAPTERS = [
1487
1841
  return normalizeOpenRouterKeyPayload(payload, Date.now());
1488
1842
  }
1489
1843
  },
1844
+ {
1845
+ id: "vercel-ai-gateway",
1846
+ displayName: "Vercel AI Gateway",
1847
+ semantics: { kind: "api-key", label: "AI Gateway credits and lifetime spend" },
1848
+ async query(auth, signal, timeoutMs, guard) {
1849
+ if (!guard)
1850
+ throw new Error("Vercel AI Gateway usage requires request-boundary revalidation.");
1851
+ const startedAt = Date.now();
1852
+ await guard();
1853
+ const payload = await fetchProviderJson(
1854
+ VERCEL_AI_GATEWAY_CREDITS_URL,
1855
+ auth,
1856
+ signal,
1857
+ remainingTimeout(timeoutMs, startedAt, "fetching Vercel AI Gateway credits"),
1858
+ "Vercel AI Gateway credits endpoint",
1859
+ { redirect: "error" }
1860
+ );
1861
+ await guard();
1862
+ return normalizeVercelAIGatewayCreditsPayload(payload, Date.now());
1863
+ }
1864
+ },
1490
1865
  {
1491
1866
  id: "fireworks",
1492
1867
  displayName: "Fireworks",
@@ -1547,6 +1922,38 @@ var SUPPORTED_ADAPTERS = [
1547
1922
  return normalizeKimiCodingUsagePayload(payload, Date.now());
1548
1923
  }
1549
1924
  },
1925
+ {
1926
+ id: "minimax",
1927
+ displayName: "MiniMax",
1928
+ semantics: { kind: "consumer-subscription", label: "MiniMax usage" },
1929
+ async query(auth, signal, timeoutMs, guard) {
1930
+ return queryMiniMaxUsage("minimax", auth, signal, timeoutMs, guard);
1931
+ }
1932
+ },
1933
+ {
1934
+ id: "minimax-cn",
1935
+ displayName: "MiniMax CN",
1936
+ semantics: { kind: "consumer-subscription", label: "MiniMax usage" },
1937
+ async query(auth, signal, timeoutMs, guard) {
1938
+ return queryMiniMaxUsage("minimax-cn", auth, signal, timeoutMs, guard);
1939
+ }
1940
+ },
1941
+ {
1942
+ id: "moonshotai",
1943
+ displayName: "Moonshot AI",
1944
+ semantics: { kind: "api-key", label: "Moonshot API account balance" },
1945
+ async query(auth, signal, timeoutMs, guard) {
1946
+ return queryMoonshotBalance("moonshotai", auth, signal, timeoutMs, guard);
1947
+ }
1948
+ },
1949
+ {
1950
+ id: "moonshotai-cn",
1951
+ displayName: "Moonshot AI CN",
1952
+ semantics: { kind: "api-key", label: "Moonshot API account balance" },
1953
+ async query(auth, signal, timeoutMs, guard) {
1954
+ return queryMoonshotBalance("moonshotai-cn", auth, signal, timeoutMs, guard);
1955
+ }
1956
+ },
1550
1957
  {
1551
1958
  id: "zai",
1552
1959
  displayName: "Z.AI",
@@ -1655,17 +2062,20 @@ async function resolveUsageAuth(ctx, adapter, salt = AUTH_FINGERPRINT_SALT, cred
1655
2062
  if (!result.ok) throw new Error(redactUsageError(result.error));
1656
2063
  return authorizationFrom(result) ? result : void 0;
1657
2064
  };
1658
- if (adapter.id !== "deepseek") modelAuth = await resolveCurrentModelAuth();
2065
+ const resolveSelectedAuthLast = ["deepseek", "minimax", "minimax-cn"].includes(adapter.id);
2066
+ if (!resolveSelectedAuthLast) modelAuth = await resolveCurrentModelAuth();
1659
2067
  if (typeof registry.getProviderAuth !== "function") {
1660
2068
  throw new Error("pi-usage requires Pi 0.81.0 or newer to validate resolved provider auth.");
1661
2069
  }
2070
+ if (!moonshotProviderAuthIsAllowed(ctx, adapter.id)) return void 0;
1662
2071
  const providerResult = await registry.getProviderAuth(adapter.id);
2072
+ if (!moonshotProviderAuthIsAllowed(ctx, adapter.id)) return void 0;
1663
2073
  if (providerResult?.auth.baseUrl && !hasOfficialUrlOrigin(providerResult.auth.baseUrl, adapter.id)) {
1664
2074
  throw new Error(
1665
2075
  `${adapter.displayName} usage cannot send a proxy-resolved credential to the official usage endpoint.`
1666
2076
  );
1667
2077
  }
1668
- if (adapter.id === "deepseek") modelAuth = await resolveCurrentModelAuth();
2078
+ if (resolveSelectedAuthLast) modelAuth = await resolveCurrentModelAuth();
1669
2079
  const auth = modelAuth ?? providerResult?.auth;
1670
2080
  if (!auth) return void 0;
1671
2081
  if (adapter.id === "github-copilot") {
@@ -1730,11 +2140,30 @@ async function queryProviderUsage(adapter, auth, signal, timeoutMs, guard, setti
1730
2140
  }
1731
2141
  function providerIsConfigured(ctx, providerId) {
1732
2142
  try {
1733
- return ctx.modelRegistry.getProviderAuthStatus(providerId).configured;
2143
+ const status = ctx.modelRegistry.getProviderAuthStatus(providerId);
2144
+ return status.configured && moonshotProviderAuthSourceIsAllowed(ctx, providerId, status.source, status.label);
1734
2145
  } catch {
1735
- return candidateModels(ctx, providerId).length > 0;
2146
+ return !isMoonshotSiblingProvider(ctx, providerId) && candidateModels(ctx, providerId).length > 0;
1736
2147
  }
1737
2148
  }
2149
+ function moonshotProviderAuthIsAllowed(ctx, providerId) {
2150
+ if (!isMoonshotSiblingProvider(ctx, providerId)) return true;
2151
+ try {
2152
+ const status = ctx.modelRegistry.getProviderAuthStatus(providerId);
2153
+ return moonshotProviderAuthSourceIsAllowed(ctx, providerId, status.source, status.label);
2154
+ } catch {
2155
+ return false;
2156
+ }
2157
+ }
2158
+ function moonshotProviderAuthSourceIsAllowed(ctx, providerId, source, label) {
2159
+ if (!isMoonshotSiblingProvider(ctx, providerId)) return true;
2160
+ if (source === void 0) return false;
2161
+ if (source !== "environment") return true;
2162
+ return label !== void 0 && !label.split(",").map((name) => name.trim()).includes(SHARED_MOONSHOT_ENV_VAR);
2163
+ }
2164
+ function isMoonshotSiblingProvider(ctx, providerId) {
2165
+ return (providerId === "moonshotai" || providerId === "moonshotai-cn") && ctx.model?.provider !== providerId;
2166
+ }
1738
2167
  function candidateModels(ctx, providerId) {
1739
2168
  const candidates = [];
1740
2169
  const seen = /* @__PURE__ */ new Set();
@@ -1863,7 +2292,7 @@ function resolveXaiUsageAuth(auth, model, salt, candidates) {
1863
2292
  const matches = [];
1864
2293
  for (const candidate of candidates) {
1865
2294
  try {
1866
- const credential = asObject9(candidate);
2295
+ const credential = asObject12(candidate);
1867
2296
  if (credential?.type !== "oauth") continue;
1868
2297
  sawOAuth = true;
1869
2298
  if (credential.access !== resolvedAccess) continue;
@@ -1917,7 +2346,7 @@ function resolveGitHubCopilotUsageAuth(auth, model, salt, candidates, standalone
1917
2346
  const matches = /* @__PURE__ */ new Map();
1918
2347
  for (const candidate of candidates) {
1919
2348
  try {
1920
- const credential = asObject9(candidate);
2349
+ const credential = asObject12(candidate);
1921
2350
  if (credential?.type !== "oauth") continue;
1922
2351
  sawOAuth = true;
1923
2352
  const storedAccess2 = typeof credential.access === "string" && credential.access ? credential.access : void 0;
@@ -1979,7 +2408,7 @@ function bearerToken(authorization) {
1979
2408
  const match = /^Bearer\s+(.+)$/iu.exec(authorization ?? "");
1980
2409
  return match?.[1];
1981
2410
  }
1982
- function asObject9(value) {
2411
+ function asObject12(value) {
1983
2412
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1984
2413
  return value;
1985
2414
  }
@@ -1997,12 +2426,20 @@ function hasOfficialOrigin(model, providerId) {
1997
2426
  function hasOfficialUrlOrigin(value, providerId) {
1998
2427
  try {
1999
2428
  const url = new URL(value);
2429
+ if (providerId === "baseten") {
2430
+ return ["https://inference.baseten.co", "https://api.baseten.co"].includes(url.origin);
2431
+ }
2000
2432
  if (providerId === "openai-codex") return url.origin === "https://chatgpt.com";
2001
2433
  if (providerId === "deepseek") return url.origin === "https://api.deepseek.com";
2002
2434
  if (providerId === "fireworks") return url.origin === FIREWORKS_BILLING_SUMMARY_ORIGIN;
2003
2435
  if (providerId === "openrouter") return url.origin === "https://openrouter.ai";
2436
+ if (providerId === "vercel-ai-gateway") return url.origin === "https://ai-gateway.vercel.sh";
2004
2437
  if (providerId === "opencode-go") return url.origin === "https://opencode.ai";
2005
2438
  if (providerId === "kimi-coding") return url.origin === "https://api.kimi.com";
2439
+ if (providerId === "minimax") return url.origin === "https://api.minimax.io";
2440
+ if (providerId === "minimax-cn") return url.origin === "https://api.minimaxi.com";
2441
+ if (providerId === "moonshotai") return url.origin === "https://api.moonshot.ai";
2442
+ if (providerId === "moonshotai-cn") return url.origin === "https://api.moonshot.cn";
2006
2443
  if (providerId === "xai") return url.origin === "https://api.x.ai";
2007
2444
  if (providerId === "zai") return url.origin === "https://api.z.ai";
2008
2445
  if (providerId === "zai-coding-cn") return url.origin === "https://open.bigmodel.cn";
@@ -2029,6 +2466,49 @@ function validatedXaiUserId(value) {
2029
2466
  }
2030
2467
  return value;
2031
2468
  }
2469
+ function basetenBillingUsageUrl(windowAt) {
2470
+ const url = new URL(BASETEN_BILLING_USAGE_URL);
2471
+ url.searchParams.set(
2472
+ "start_date",
2473
+ new Date(windowAt - BASETEN_USAGE_WINDOW_DAYS * 24 * 60 * 60 * 1e3).toISOString()
2474
+ );
2475
+ url.searchParams.set("end_date", new Date(windowAt).toISOString());
2476
+ return url.toString();
2477
+ }
2478
+ async function queryMiniMaxUsage(providerId, auth, signal, timeoutMs, guard) {
2479
+ if (!guard) throw new Error("MiniMax usage requires request-boundary revalidation.");
2480
+ const apiKey = bearerToken(headerValue(auth.headers, "Authorization")) ?? auth.apiKey;
2481
+ if (!apiKey) throw new Error("MiniMax runtime API key was unavailable.");
2482
+ const kind = miniMaxUsageKind(apiKey);
2483
+ const path = kind === "account-balance" ? "/account/query_balance" : "/v1/token_plan/remains";
2484
+ const startedAt = Date.now();
2485
+ await guard();
2486
+ const payload = await fetchProviderJson(
2487
+ `${MINIMAX_API_ROOTS[providerId]}${path}`,
2488
+ auth,
2489
+ signal,
2490
+ remainingTimeout(timeoutMs, startedAt, "fetching MiniMax usage"),
2491
+ "MiniMax usage endpoint",
2492
+ { redirect: "error" }
2493
+ );
2494
+ await guard();
2495
+ return normalizeMiniMaxUsagePayload(providerId, kind, payload, Date.now());
2496
+ }
2497
+ async function queryMoonshotBalance(providerId, auth, signal, timeoutMs, guard) {
2498
+ if (!guard) throw new Error("Moonshot AI balance requires request-boundary revalidation.");
2499
+ const startedAt = Date.now();
2500
+ await guard();
2501
+ const payload = await fetchProviderJson(
2502
+ MOONSHOT_BALANCE_URLS[providerId],
2503
+ auth,
2504
+ signal,
2505
+ remainingTimeout(timeoutMs, startedAt, "fetching Moonshot AI balance"),
2506
+ "Moonshot AI balance endpoint",
2507
+ { redirect: "error" }
2508
+ );
2509
+ await guard();
2510
+ return normalizeMoonshotBalancePayload(providerId, payload, Date.now());
2511
+ }
2032
2512
  function remainingTimeout(timeoutMs, startedAt, description = "fetching xAI consumer usage") {
2033
2513
  const remaining = timeoutMs - (Date.now() - startedAt);
2034
2514
  if (remaining <= 0) throw new Error(`Timed out while ${description}.`);
@@ -2130,12 +2610,12 @@ var CODEX_RESET_CREDITS_URL = "https://chatgpt.com/backend-api/wham/rate-limit-r
2130
2610
  var CODEX_RESET_CONSUME_URL = `${CODEX_RESET_CREDITS_URL}/consume`;
2131
2611
  var MAX_RESET_OPTIONS = 32;
2132
2612
  var MAX_CREDIT_ID_CHARS = 1024;
2133
- function codexResetCount(report) {
2134
- const value = report.metrics.find((metric) => metric.id === "reset-credits")?.value;
2613
+ function codexResetCount(report2) {
2614
+ const value = report2.metrics.find((metric2) => metric2.id === "reset-credits")?.value;
2135
2615
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
2136
2616
  }
2137
- function codexResetActionDescription(report) {
2138
- const count = codexResetCount(report);
2617
+ function codexResetActionDescription(report2) {
2618
+ const count = codexResetCount(report2);
2139
2619
  if (count === void 0) return "Check reset availability.";
2140
2620
  if (count === 0) return "No usage limit resets available.";
2141
2621
  return `You have ${count} ${resetLabel(count)} available.`;
@@ -2248,14 +2728,14 @@ async function consumeCodexResetCredit(auth, option, redeemRequestId, signal, ti
2248
2728
  if (!isCodexResetOutcomeCode(code)) {
2249
2729
  throw new Error("Codex reset consume endpoint returned an unknown outcome code.");
2250
2730
  }
2251
- const windowsReset = payload.windows_reset === void 0 ? 0 : nonnegativeInteger(payload.windows_reset);
2731
+ const windowsReset = payload.windows_reset === void 0 ? 0 : nonnegativeInteger2(payload.windows_reset);
2252
2732
  if (windowsReset === void 0) {
2253
2733
  throw new Error("Codex reset consume endpoint returned an invalid windows_reset value.");
2254
2734
  }
2255
2735
  return { code, windowsReset };
2256
2736
  }
2257
2737
  function normalizeCodexResetCreditsPayload(payload) {
2258
- const availableCount = nonnegativeInteger(payload.available_count);
2738
+ const availableCount = nonnegativeInteger2(payload.available_count);
2259
2739
  if (availableCount === void 0) {
2260
2740
  throw new Error("Codex reset credits response returned an invalid available_count.");
2261
2741
  }
@@ -2263,7 +2743,7 @@ function normalizeCodexResetCreditsPayload(payload) {
2263
2743
  if (rawCredits !== void 0 && !Array.isArray(rawCredits)) {
2264
2744
  throw new Error("Codex reset credits response returned invalid credits.");
2265
2745
  }
2266
- const options = (rawCredits ?? []).map(asObject10).filter((credit) => Boolean(credit)).filter((credit) => credit.status === "available" && credit.reset_type === "codex_rate_limits").map(normalizeResetOption).sort(
2746
+ const options = (rawCredits ?? []).map(asObject13).filter((credit) => Boolean(credit)).filter((credit) => credit.status === "available" && credit.reset_type === "codex_rate_limits").map(normalizeResetOption).sort(
2267
2747
  (left, right) => (left.expiresAt ?? Number.MAX_SAFE_INTEGER) - (right.expiresAt ?? Number.MAX_SAFE_INTEGER)
2268
2748
  ).slice(0, Math.min(availableCount, MAX_RESET_OPTIONS));
2269
2749
  if (availableCount > 0 && options.length === 0) {
@@ -2278,7 +2758,7 @@ function selectCodexResetCredential(candidates, resolvedAccess, resolvedAccountI
2278
2758
  const matches = /* @__PURE__ */ new Map();
2279
2759
  for (const candidate of candidates) {
2280
2760
  try {
2281
- const credential = asObject10(candidate);
2761
+ const credential = asObject13(candidate);
2282
2762
  if (credential?.type !== "oauth") continue;
2283
2763
  sawOAuth = true;
2284
2764
  const storedAccess = asNonemptyString(credential.access);
@@ -2317,7 +2797,7 @@ function codexAccountIdFromAccessToken(access) {
2317
2797
  const parts = access.split(".");
2318
2798
  if (parts.length !== 3 || !parts[1]) return void 0;
2319
2799
  const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
2320
- const claims = asObject10(asObject10(payload)?.["https://api.openai.com/auth"]);
2800
+ const claims = asObject13(asObject13(payload)?.["https://api.openai.com/auth"]);
2321
2801
  return validHeaderValue(claims?.chatgpt_account_id);
2322
2802
  } catch {
2323
2803
  return void 0;
@@ -2349,7 +2829,7 @@ function normalizeResetOption(credit) {
2349
2829
  function isCodexResetOutcomeCode(value) {
2350
2830
  return value === "reset" || value === "nothing_to_reset" || value === "no_credit" || value === "already_redeemed";
2351
2831
  }
2352
- function asObject10(value) {
2832
+ function asObject13(value) {
2353
2833
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
2354
2834
  return value;
2355
2835
  }
@@ -2371,7 +2851,7 @@ function validHeaderValue(value) {
2371
2851
  if (/[^\x20-\x7e]/u.test(value)) return void 0;
2372
2852
  return value;
2373
2853
  }
2374
- function nonnegativeInteger(value) {
2854
+ function nonnegativeInteger2(value) {
2375
2855
  const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;
2376
2856
  if (!Number.isSafeInteger(parsed) || parsed < 0) return void 0;
2377
2857
  return parsed;
@@ -2388,45 +2868,59 @@ function headerValue2(headers, name) {
2388
2868
  // src/format.ts
2389
2869
  var BAR_SEGMENTS = 20;
2390
2870
  var VALUE_COLUMN = 29;
2391
- function formatUsageReport(report, displayState) {
2871
+ function formatUsageReport(report2, displayState) {
2392
2872
  const stateLabel = displayState === "current" ? "Current" : "Configured";
2393
- const title = report.providerId === "deepseek" ? "DeepSeek API Balance" : report.providerId === "fireworks" ? "Fireworks API Spend" : `${report.providerName} Usage`;
2873
+ const title = report2.providerId === "baseten" ? "Baseten Model APIs Spend" : report2.providerId === "deepseek" ? "DeepSeek API Balance" : report2.providerId === "fireworks" ? "Fireworks API Spend" : report2.providerId === "vercel-ai-gateway" ? "Vercel AI Gateway Credits" : report2.providerId === "moonshotai" || report2.providerId === "moonshotai-cn" ? `${report2.providerName} Balance` : report2.providerId === "minimax" || report2.providerId === "minimax-cn" ? report2.source === "minimax-account-balance" ? `${report2.providerName} API Balance` : `${report2.providerName} Token Plan` : `${report2.providerName} Usage`;
2394
2874
  const lines = [`${title} \xB7 ${stateLabel}`];
2395
- if (report.accountLabel) lines.push(`Account: ${report.accountLabel}`);
2396
- lines.push(`Semantics: ${report.semantics.label}`, "");
2397
- if (report.providerId === "openai-codex") formatCodexReport(lines, report);
2398
- else if (report.providerId === "deepseek") formatDeepSeekReport(lines, report);
2399
- else if (report.providerId === "fireworks") formatFireworksReport(lines, report);
2400
- else if (report.providerId === "github-copilot") formatGitHubCopilotReport(lines, report);
2401
- else if (report.providerId === "openrouter") formatOpenRouterReport(lines, report);
2402
- else if (report.providerId === "opencode-go") formatOpenCodeZenReport(lines, report);
2403
- else if (report.providerId === "kimi-coding") formatKimiCodingReport(lines, report);
2404
- else if (report.providerId === "xai") formatXaiReport(lines, report);
2405
- else if (report.providerId === "zai" || report.providerId === "zai-coding-cn") {
2406
- formatZaiReport(lines, report);
2407
- } else formatGenericReport(lines, report);
2408
- if (report.notes) {
2409
- for (const note of report.notes) lines.push(note);
2875
+ if (report2.accountLabel) lines.push(`Account: ${report2.accountLabel}`);
2876
+ lines.push(`Semantics: ${report2.semantics.label}`, "");
2877
+ if (report2.providerId === "baseten") formatBasetenReport(lines, report2);
2878
+ else if (report2.providerId === "openai-codex") formatCodexReport(lines, report2);
2879
+ else if (report2.providerId === "deepseek") formatDeepSeekReport(lines, report2);
2880
+ else if (report2.providerId === "fireworks") formatFireworksReport(lines, report2);
2881
+ else if (report2.providerId === "vercel-ai-gateway") formatVercelAIGatewayReport(lines, report2);
2882
+ else if (report2.providerId === "github-copilot") formatGitHubCopilotReport(lines, report2);
2883
+ else if (report2.providerId === "openrouter") formatOpenRouterReport(lines, report2);
2884
+ else if (report2.providerId === "opencode-go") formatOpenCodeZenReport(lines, report2);
2885
+ else if (report2.providerId === "kimi-coding") formatKimiCodingReport(lines, report2);
2886
+ else if (report2.providerId === "moonshotai" || report2.providerId === "moonshotai-cn") {
2887
+ formatMoonshotReport(lines, report2);
2888
+ } else if (report2.providerId === "minimax" || report2.providerId === "minimax-cn") {
2889
+ formatMiniMaxReport(lines, report2);
2890
+ } else if (report2.providerId === "xai") formatXaiReport(lines, report2);
2891
+ else if (report2.providerId === "zai" || report2.providerId === "zai-coding-cn") {
2892
+ formatZaiReport(lines, report2);
2893
+ } else formatGenericReport(lines, report2);
2894
+ if (report2.notes) {
2895
+ for (const note of report2.notes) lines.push(note);
2410
2896
  }
2411
2897
  return lines.join("\n").trimEnd();
2412
2898
  }
2413
- function formatUsageStatusline(report, model, now = Date.now(), showCodexResetCountdown = true) {
2414
- if (report.providerId === "openai-codex") {
2415
- return formatCodexStatusline(report, model, now, showCodexResetCountdown);
2416
- }
2417
- if (report.providerId === "deepseek") return formatDeepSeekStatusline(report);
2418
- if (report.providerId === "fireworks") return formatFireworksStatusline(report);
2419
- if (report.providerId === "github-copilot") return formatGitHubCopilotStatusline(report);
2420
- if (report.providerId === "openrouter") {
2421
- const limit = report.buckets.find((bucket) => bucket.id === "key-limit");
2899
+ function formatUsageStatusline(report2, model, now = Date.now(), showCodexResetCountdown = true) {
2900
+ if (report2.providerId === "baseten") return formatBasetenStatusline(report2);
2901
+ if (report2.providerId === "openai-codex") {
2902
+ return formatCodexStatusline(report2, model, now, showCodexResetCountdown);
2903
+ }
2904
+ if (report2.providerId === "deepseek") return formatDeepSeekStatusline(report2);
2905
+ if (report2.providerId === "fireworks") return formatFireworksStatusline(report2);
2906
+ if (report2.providerId === "vercel-ai-gateway") return formatVercelAIGatewayStatusline(report2);
2907
+ if (report2.providerId === "github-copilot") return formatGitHubCopilotStatusline(report2);
2908
+ if (report2.providerId === "openrouter") {
2909
+ const limit = report2.buckets.find((bucket) => bucket.id === "key-limit");
2422
2910
  if (limit?.remaining !== void 0) return `openrouter ${formatUsd(limit.remaining)} left`;
2423
- const total = report.metrics.find((metric) => metric.id === "usage-total");
2911
+ const total = report2.metrics.find((metric2) => metric2.id === "usage-total");
2424
2912
  if (typeof total?.value === "number") return `openrouter ${formatUsd(total.value)} used`;
2425
2913
  }
2426
- if (report.providerId === "opencode-go") return formatOpenCodeZenStatusline(report);
2427
- if (report.providerId === "kimi-coding") return formatKimiCodingStatusline(report);
2428
- if (report.providerId === "zai" || report.providerId === "zai-coding-cn") {
2429
- return formatZaiStatusline(report);
2914
+ if (report2.providerId === "opencode-go") return formatOpenCodeZenStatusline(report2);
2915
+ if (report2.providerId === "kimi-coding") return formatKimiCodingStatusline(report2);
2916
+ if (report2.providerId === "moonshotai" || report2.providerId === "moonshotai-cn") {
2917
+ return formatMoonshotStatusline(report2);
2918
+ }
2919
+ if (report2.providerId === "minimax" || report2.providerId === "minimax-cn") {
2920
+ return formatMiniMaxStatusline(report2, model);
2921
+ }
2922
+ if (report2.providerId === "zai" || report2.providerId === "zai-coding-cn") {
2923
+ return formatZaiStatusline(report2);
2430
2924
  }
2431
2925
  return void 0;
2432
2926
  }
@@ -2439,9 +2933,19 @@ function formatProviderStates(states) {
2439
2933
  ${status}: ${state.message}`;
2440
2934
  }).join("\n\n");
2441
2935
  }
2442
- function formatCodexReport(lines, report) {
2936
+ function formatBasetenReport(lines, report2) {
2937
+ lines.push(`${"Spend window:".padEnd(VALUE_COLUMN)}Last 30 days`);
2938
+ for (const metric2 of report2.metrics) {
2939
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}USD ${metric2.value}`);
2940
+ }
2941
+ }
2942
+ function formatBasetenStatusline(report2) {
2943
+ const subtotal = report2.metrics.find((metric2) => metric2.id === "net-subtotal");
2944
+ return subtotal ? `baseten USD ${subtotal.value} net` : "baseten no Model APIs usage";
2945
+ }
2946
+ function formatCodexReport(lines, report2) {
2443
2947
  let previousGroup;
2444
- for (const bucket of report.buckets) {
2948
+ for (const bucket of report2.buckets) {
2445
2949
  const group = bucket.groupId ?? bucket.id;
2446
2950
  if (group !== previousGroup && group !== "codex") {
2447
2951
  lines.push(`${bucket.groupLabel ?? group} limit:`);
@@ -2451,66 +2955,75 @@ function formatCodexReport(lines, report) {
2451
2955
  const label = `${formatWindowLabel(bucket.windowMinutes, fallback, false)} limit:`;
2452
2956
  lines.push(`${label.padEnd(VALUE_COLUMN)}${formatPercentBucket(bucket)}`);
2453
2957
  }
2454
- for (const metric of report.metrics) {
2455
- if (metric.id === "reset-credits") {
2456
- lines.push(`${"Usage limit resets:".padEnd(VALUE_COLUMN)}${metric.value} available`);
2457
- } else if (metric.id === "credits") {
2958
+ for (const metric2 of report2.metrics) {
2959
+ if (metric2.id === "reset-credits") {
2960
+ lines.push(`${"Usage limit resets:".padEnd(VALUE_COLUMN)}${metric2.value} available`);
2961
+ } else if (metric2.id === "credits") {
2458
2962
  lines.push(
2459
- `${"Credits:".padEnd(VALUE_COLUMN)}${formatMetricValue(metric.value, metric.unit)}`
2963
+ `${"Credits:".padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`
2460
2964
  );
2461
2965
  }
2462
2966
  }
2463
2967
  }
2464
- function formatDeepSeekReport(lines, report) {
2465
- const availability = report.metrics.find((metric) => metric.id === "api-availability");
2968
+ function formatDeepSeekReport(lines, report2) {
2969
+ const availability = report2.metrics.find((metric2) => metric2.id === "api-availability");
2466
2970
  lines.push(
2467
2971
  `${"API calls:".padEnd(VALUE_COLUMN)}${availability?.value === "available" ? "Available" : "Unavailable"}`
2468
2972
  );
2469
2973
  for (const currency of ["CNY", "USD"]) {
2470
- const metrics = report.metrics.filter((metric) => metric.currency === currency);
2974
+ const metrics = report2.metrics.filter((metric2) => metric2.currency === currency);
2471
2975
  if (metrics.length === 0) continue;
2472
2976
  lines.push("", `${currency} balance:`);
2473
- for (const metric of metrics) {
2474
- lines.push(`${`${metric.label}:`.padEnd(VALUE_COLUMN)}${currency} ${metric.value}`);
2977
+ for (const metric2 of metrics) {
2978
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${currency} ${metric2.value}`);
2475
2979
  }
2476
2980
  }
2477
2981
  }
2478
- function formatDeepSeekStatusline(report) {
2479
- const availability = report.metrics.find((metric) => metric.id === "api-availability");
2982
+ function formatDeepSeekStatusline(report2) {
2983
+ const availability = report2.metrics.find((metric2) => metric2.id === "api-availability");
2480
2984
  if (availability?.value !== "available") return "deepseek API unavailable";
2481
2985
  const totals = ["CNY", "USD"].flatMap((currency) => {
2482
- const metric = report.metrics.find(
2986
+ const metric2 = report2.metrics.find(
2483
2987
  (candidate) => candidate.id === `${currency.toLowerCase()}-total`
2484
2988
  );
2485
- return metric ? [`${currency} ${metric.value}`] : [];
2989
+ return metric2 ? [`${currency} ${metric2.value}`] : [];
2486
2990
  });
2487
2991
  return totals.length > 0 ? `deepseek ${totals.join(" \xB7 ")}` : "deepseek balance unavailable";
2488
2992
  }
2489
- function formatFireworksReport(lines, report) {
2993
+ function formatFireworksReport(lines, report2) {
2490
2994
  lines.push(`${"Spend window:".padEnd(VALUE_COLUMN)}Last 30 days (rated)`);
2491
- for (const currency of fireworksCurrencies(report)) {
2995
+ for (const currency of fireworksCurrencies(report2)) {
2492
2996
  lines.push("", `${currency} rated spend:`);
2493
- for (const metric of report.metrics) {
2494
- if (metric.currency !== currency) continue;
2495
- lines.push(`${`${metric.label}:`.padEnd(VALUE_COLUMN)}${currency} ${metric.value}`);
2997
+ for (const metric2 of report2.metrics) {
2998
+ if (metric2.currency !== currency) continue;
2999
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${currency} ${metric2.value}`);
2496
3000
  }
2497
3001
  }
2498
3002
  }
2499
- function formatFireworksStatusline(report) {
2500
- const totals = report.metrics.filter((metric) => metric.id.endsWith("-total"));
3003
+ function formatFireworksStatusline(report2) {
3004
+ const totals = report2.metrics.filter((metric2) => metric2.id.endsWith("-total"));
2501
3005
  if (totals.length === 0) return "fireworks no rated usage";
2502
- return `fireworks ${totals.map((metric) => `${metric.currency} ${metric.value}`).join(" \xB7 ")}`;
3006
+ return `fireworks ${totals.map((metric2) => `${metric2.currency} ${metric2.value}`).join(" \xB7 ")}`;
2503
3007
  }
2504
- function fireworksCurrencies(report) {
3008
+ function fireworksCurrencies(report2) {
2505
3009
  const currencies = [];
2506
- for (const metric of report.metrics) {
2507
- if (!metric.currency || currencies.includes(metric.currency)) continue;
2508
- currencies.push(metric.currency);
3010
+ for (const metric2 of report2.metrics) {
3011
+ if (!metric2.currency || currencies.includes(metric2.currency)) continue;
3012
+ currencies.push(metric2.currency);
2509
3013
  }
2510
3014
  return currencies;
2511
3015
  }
2512
- function formatGitHubCopilotReport(lines, report) {
2513
- const quota = findGitHubCopilotQuota(report);
3016
+ function formatVercelAIGatewayReport(lines, report2) {
3017
+ for (const metric2 of report2.metrics) {
3018
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}USD ${metric2.value}`);
3019
+ }
3020
+ }
3021
+ function formatVercelAIGatewayStatusline(report2) {
3022
+ const balance = report2.metrics.find((metric2) => metric2.id === "credit-balance");
3023
+ return balance ? `vercel USD ${balance.value} left` : "vercel credits unavailable";
3024
+ }
3025
+ function formatGitHubCopilotReport(lines, report2) {
3026
+ const quota = findGitHubCopilotQuota(report2);
2514
3027
  if (!quota || quota.limit === void 0 || quota.remaining === void 0) {
2515
3028
  lines.push(`${`${quota?.label ?? "Copilot quota"}:`.padEnd(VALUE_COLUMN)}unlimited`);
2516
3029
  return;
@@ -2520,23 +3033,23 @@ function formatGitHubCopilotReport(lines, report) {
2520
3033
  lines.push(
2521
3034
  `${`${quota.label}:`.padEnd(VALUE_COLUMN)}${quota.remaining} of ${quota.limit} left \xB7 ${percent}%${reset}`
2522
3035
  );
2523
- const overage = report.metrics.find((metric) => metric.id === "overage-used");
3036
+ const overage = report2.metrics.find((metric2) => metric2.id === "overage-used");
2524
3037
  if (typeof overage?.value === "number" && overage.value > 0) {
2525
3038
  lines.push(`${"Additional usage:".padEnd(VALUE_COLUMN)}${overage.value} ${quota.label}`);
2526
3039
  }
2527
3040
  }
2528
- function formatGitHubCopilotStatusline(report) {
2529
- const quota = findGitHubCopilotQuota(report);
3041
+ function formatGitHubCopilotStatusline(report2) {
3042
+ const quota = findGitHubCopilotQuota(report2);
2530
3043
  const kind = compactGitHubCopilotQuotaKind(quota);
2531
3044
  if (!quota || quota.limit === void 0 || quota.remaining === void 0) {
2532
3045
  return `copilot ${kind} unlimited`;
2533
3046
  }
2534
- const overage = report.metrics.find((metric) => metric.id === "overage-used");
3047
+ const overage = report2.metrics.find((metric2) => metric2.id === "overage-used");
2535
3048
  const overageSuffix = typeof overage?.value === "number" && overage.value > 0 ? ` +${overage.value} over` : "";
2536
3049
  return `copilot ${kind === "premium" ? "" : `${kind} `}${quota.remaining}/${quota.limit} ${percentRemaining(quota)}%${overageSuffix}`;
2537
3050
  }
2538
- function findGitHubCopilotQuota(report) {
2539
- return report.buckets.find(
3051
+ function findGitHubCopilotQuota(report2) {
3052
+ return report2.buckets.find(
2540
3053
  (bucket) => ["ai-credits", "premium-requests", "chat-requests"].includes(bucket.id)
2541
3054
  );
2542
3055
  }
@@ -2549,37 +3062,37 @@ function percentRemaining(bucket) {
2549
3062
  if (!bucket.limit || bucket.remaining === void 0) return 0;
2550
3063
  return Math.round(clampPercent4(bucket.remaining / bucket.limit * 100));
2551
3064
  }
2552
- function formatOpenRouterReport(lines, report) {
2553
- const limit = report.buckets.find((bucket) => bucket.id === "key-limit");
3065
+ function formatOpenRouterReport(lines, report2) {
3066
+ const limit = report2.buckets.find((bucket) => bucket.id === "key-limit");
2554
3067
  if (limit) {
2555
3068
  const period = limit.period ? ` (${limit.period})` : "";
2556
3069
  const value = limit.remaining === void 0 ? `${formatUsd(limit.limit ?? 0)} cap; remaining unavailable` : `${formatUsd(limit.remaining)} of ${formatUsd(limit.limit ?? 0)} left`;
2557
3070
  lines.push(`${`Key limit${period}:`.padEnd(VALUE_COLUMN)}${value}`);
2558
3071
  }
2559
- for (const metric of report.metrics) {
3072
+ for (const metric2 of report2.metrics) {
2560
3073
  lines.push(
2561
- `${`${metric.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric.value, metric.unit)}`
3074
+ `${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`
2562
3075
  );
2563
3076
  }
2564
3077
  }
2565
- function formatOpenCodeZenReport(lines, report) {
2566
- for (const bucket of report.buckets) {
3078
+ function formatOpenCodeZenReport(lines, report2) {
3079
+ for (const bucket of report2.buckets) {
2567
3080
  const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
2568
3081
  const used = bucket.used ?? "unavailable";
2569
3082
  lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${used}% used${reset}`);
2570
3083
  }
2571
3084
  }
2572
- function formatOpenCodeZenStatusline(report) {
3085
+ function formatOpenCodeZenStatusline(report2) {
2573
3086
  const parts = ["zen"];
2574
- for (const bucket of report.buckets) {
3087
+ for (const bucket of report2.buckets) {
2575
3088
  if (bucket.used === void 0) continue;
2576
3089
  const compact = bucket.id === "rolling" ? "r" : bucket.id === "weekly" ? "w" : "m";
2577
3090
  parts.push(`${clampPercent4(bucket.used).toFixed(0)}% ${compact}`);
2578
3091
  }
2579
3092
  return parts.length > 1 ? parts.join(" ") : void 0;
2580
3093
  }
2581
- function formatKimiCodingReport(lines, report) {
2582
- for (const bucket of report.buckets) {
3094
+ function formatKimiCodingReport(lines, report2) {
3095
+ for (const bucket of report2.buckets) {
2583
3096
  const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
2584
3097
  if (bucket.used === void 0 || bucket.limit === void 0) {
2585
3098
  lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}unavailable${reset}`);
@@ -2589,10 +3102,10 @@ function formatKimiCodingReport(lines, report) {
2589
3102
  `${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${bucket.used} of ${bucket.limit} used \xB7 ${percentRemaining(bucket)}% left${reset}`
2590
3103
  );
2591
3104
  }
2592
- const balance = report.metrics.find((metric) => metric.id === "booster-balance");
2593
- const total = report.metrics.find((metric) => metric.id === "booster-total");
2594
- const monthlyUsed = report.metrics.find((metric) => metric.id === "booster-monthly-used");
2595
- const monthlyLimit = report.metrics.find((metric) => metric.id === "booster-monthly-limit");
3105
+ const balance = report2.metrics.find((metric2) => metric2.id === "booster-balance");
3106
+ const total = report2.metrics.find((metric2) => metric2.id === "booster-total");
3107
+ const monthlyUsed = report2.metrics.find((metric2) => metric2.id === "booster-monthly-used");
3108
+ const monthlyLimit = report2.metrics.find((metric2) => metric2.id === "booster-monthly-limit");
2596
3109
  if (!balance && !monthlyUsed && !monthlyLimit) return;
2597
3110
  lines.push("", "Extra usage wallet:");
2598
3111
  if (balance) {
@@ -2606,10 +3119,10 @@ function formatKimiCodingReport(lines, report) {
2606
3119
  lines.push(`${"Monthly limit:".padEnd(VALUE_COLUMN)}${formatCurrencyMetric(monthlyLimit)}`);
2607
3120
  }
2608
3121
  }
2609
- function formatKimiCodingStatusline(report) {
2610
- const fiveHour = report.buckets.find((bucket) => bucket.id === "five-hour");
2611
- const weekly = report.buckets.find((bucket) => bucket.id === "weekly");
2612
- const subWindow = fiveHour ?? report.buckets.find((bucket) => bucket.id !== "weekly");
3122
+ function formatKimiCodingStatusline(report2) {
3123
+ const fiveHour = report2.buckets.find((bucket) => bucket.id === "five-hour");
3124
+ const weekly = report2.buckets.find((bucket) => bucket.id === "weekly");
3125
+ const subWindow = fiveHour ?? report2.buckets.find((bucket) => bucket.id !== "weekly");
2613
3126
  const selected = [subWindow, weekly].filter(
2614
3127
  (bucket, index, buckets) => bucket !== void 0 && buckets.indexOf(bucket) === index
2615
3128
  );
@@ -2623,10 +3136,98 @@ function formatKimiCodingStatusline(report) {
2623
3136
  }
2624
3137
  return parts.length > 1 ? parts.join(" ") : void 0;
2625
3138
  }
2626
- function formatZaiStatusline(report) {
3139
+ function formatMoonshotReport(lines, report2) {
3140
+ for (const metric2 of report2.metrics) {
3141
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${metric2.currency} ${metric2.value}`);
3142
+ }
3143
+ }
3144
+ function formatMoonshotStatusline(report2) {
3145
+ const available = report2.metrics.find((metric2) => metric2.id === "available-balance");
3146
+ if (!available) return "moonshot balance unavailable";
3147
+ return `moonshot ${available.currency ?? ""} ${available.value}`.replace(/\s+/gu, " ");
3148
+ }
3149
+ function formatMiniMaxReport(lines, report2) {
3150
+ if (report2.source === "minimax-account-balance") {
3151
+ for (const metric2 of report2.metrics) {
3152
+ lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${metric2.currency} ${metric2.value}`);
3153
+ }
3154
+ return;
3155
+ }
3156
+ let previousGroup;
3157
+ for (const bucket of report2.buckets) {
3158
+ if (bucket.groupId !== previousGroup) lines.push(`${bucket.groupLabel ?? "Token Plan"}:`);
3159
+ previousGroup = bucket.groupId;
3160
+ const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
3161
+ const value = bucket.period === "unlimited" ? "unlimited" : bucket.limit && bucket.remaining !== void 0 ? `${bucket.remaining} of ${bucket.limit} left \xB7 ${percentRemaining(bucket)}%${reset}` : "unavailable";
3162
+ lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${value}`);
3163
+ }
3164
+ }
3165
+ function formatMiniMaxStatusline(report2, model) {
3166
+ const prefix = report2.providerId === "minimax-cn" ? "minimax cn" : "minimax";
3167
+ if (report2.source === "minimax-account-balance") {
3168
+ const available = report2.metrics.find((metric2) => metric2.id === "available-balance");
3169
+ return available ? `${prefix} ${available.currency} ${available.value}` : void 0;
3170
+ }
3171
+ const selectedGroup = selectMiniMaxGroup(report2, model);
3172
+ if (!selectedGroup) return void 0;
3173
+ const selected = report2.buckets.filter((bucket) => bucket.groupId === selectedGroup);
3174
+ const parts = [prefix];
3175
+ for (const bucket of selected) {
3176
+ const fallback = bucket.id.endsWith(":weekly") ? "weekly" : "5h";
3177
+ const window = formatWindowLabel(bucket.windowMinutes, fallback, true);
3178
+ if (bucket.period === "unlimited") {
3179
+ parts.push(`unlimited ${window}`);
3180
+ continue;
3181
+ }
3182
+ if (!bucket.limit || bucket.remaining === void 0) continue;
3183
+ parts.push(`${percentRemaining(bucket)}% ${window}`);
3184
+ }
3185
+ return parts.length > 1 ? parts.join(" ") : void 0;
3186
+ }
3187
+ function selectMiniMaxGroup(report2, model) {
3188
+ const groups = [
3189
+ ...new Set(
3190
+ report2.buckets.map((bucket) => bucket.groupId).filter((group) => group !== void 0)
3191
+ )
3192
+ ];
3193
+ if (groups.length <= 1) return groups[0];
3194
+ if (model?.provider !== report2.providerId) return void 0;
3195
+ const modelKeys = [model.id, model.name].map(normalizeMiniMaxModelKey).filter((key) => key !== void 0);
3196
+ const candidates = groups.map((group) => {
3197
+ const bucket = report2.buckets.find((candidate) => candidate.groupId === group);
3198
+ const patterns = [bucket?.groupLabel, ...bucket?.modelKeys ?? [], group].map(normalizeMiniMaxModelKey).filter((key) => key !== void 0);
3199
+ return { group, patterns };
3200
+ });
3201
+ const exact = candidates.find(
3202
+ ({ patterns }) => patterns.some((pattern) => !pattern.includes("*") && modelKeys.includes(pattern))
3203
+ );
3204
+ if (exact) return exact.group;
3205
+ return candidates.find(
3206
+ ({ patterns }) => patterns.some(
3207
+ (pattern) => pattern.includes("*") && modelKeys.some((key) => wildcardKeyMatches(pattern, key))
3208
+ )
3209
+ )?.group;
3210
+ }
3211
+ function normalizeMiniMaxModelKey(value) {
3212
+ const key = value?.toLowerCase().replace(/[^a-z0-9*]+/gu, "");
3213
+ return key && /[a-z0-9]/u.test(key) ? key : void 0;
3214
+ }
3215
+ function wildcardKeyMatches(pattern, value) {
3216
+ if (!pattern.includes("*")) return pattern === value;
3217
+ const segments = pattern.split("*").filter(Boolean);
3218
+ let offset = 0;
3219
+ for (const [index, segment] of segments.entries()) {
3220
+ const found = value.indexOf(segment, offset);
3221
+ if (found < 0 || index === 0 && !pattern.startsWith("*") && found !== 0) return false;
3222
+ offset = found + segment.length;
3223
+ }
3224
+ const last = segments.at(-1);
3225
+ return pattern.endsWith("*") || last !== void 0 && value.endsWith(last);
3226
+ }
3227
+ function formatZaiStatusline(report2) {
2627
3228
  const selected = [
2628
- report.buckets.find((bucket) => bucket.id === "five-hour"),
2629
- report.buckets.find((bucket) => bucket.id === "weekly")
3229
+ report2.buckets.find((bucket) => bucket.id === "five-hour"),
3230
+ report2.buckets.find((bucket) => bucket.id === "weekly")
2630
3231
  ];
2631
3232
  const parts = ["zai"];
2632
3233
  for (const bucket of selected) {
@@ -2638,15 +3239,15 @@ function formatZaiStatusline(report) {
2638
3239
  }
2639
3240
  return parts.length > 1 ? parts.join(" ") : void 0;
2640
3241
  }
2641
- function formatCurrencyMetric(metric) {
2642
- if (typeof metric.value !== "number") return String(metric.value);
2643
- if (!metric.currency) return "unavailable";
2644
- if (metric.currency === "USD") return `$${metric.value.toFixed(2)}`;
2645
- if (metric.currency === "CNY") return `\xA5${metric.value.toFixed(2)}`;
2646
- return `${metric.value.toFixed(2)} ${metric.currency}`;
3242
+ function formatCurrencyMetric(metric2) {
3243
+ if (typeof metric2.value !== "number") return String(metric2.value);
3244
+ if (!metric2.currency) return "unavailable";
3245
+ if (metric2.currency === "USD") return `$${metric2.value.toFixed(2)}`;
3246
+ if (metric2.currency === "CNY") return `\xA5${metric2.value.toFixed(2)}`;
3247
+ return `${metric2.value.toFixed(2)} ${metric2.currency}`;
2647
3248
  }
2648
- function formatXaiReport(lines, report) {
2649
- const included = report.buckets.find((bucket) => bucket.id === "included-allowance");
3249
+ function formatXaiReport(lines, report2) {
3250
+ const included = report2.buckets.find((bucket) => bucket.id === "included-allowance");
2650
3251
  if (included) {
2651
3252
  let value = "unavailable";
2652
3253
  if (included.unit === "percent" && included.used !== void 0) {
@@ -2662,20 +3263,20 @@ function formatXaiReport(lines, report) {
2662
3263
  const reset = included.resetsAt ? ` (resets ${formatReset(included.resetsAt)})` : "";
2663
3264
  lines.push(`${"Included allowance:".padEnd(VALUE_COLUMN)}${value}${period}${reset}`);
2664
3265
  }
2665
- const onDemand = report.buckets.find((bucket) => bucket.id === "on-demand");
3266
+ const onDemand = report2.buckets.find((bucket) => bucket.id === "on-demand");
2666
3267
  if (onDemand) {
2667
3268
  let value = onDemand.used === void 0 ? "usage unavailable" : `${formatUsd(onDemand.used)} used`;
2668
3269
  if (onDemand.limit !== void 0) value += ` of ${formatUsd(onDemand.limit)} cap`;
2669
3270
  lines.push(`${"On-demand usage:".padEnd(VALUE_COLUMN)}${value}`);
2670
3271
  }
2671
- for (const metric of report.metrics) {
3272
+ for (const metric2 of report2.metrics) {
2672
3273
  lines.push(
2673
- `${`${metric.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric.value, metric.unit)}`
3274
+ `${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`
2674
3275
  );
2675
3276
  }
2676
3277
  }
2677
- function formatZaiReport(lines, report) {
2678
- for (const bucket of report.buckets) {
3278
+ function formatZaiReport(lines, report2) {
3279
+ for (const bucket of report2.buckets) {
2679
3280
  const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
2680
3281
  let value = "unavailable";
2681
3282
  if (bucket.unit === "percent" && bucket.used !== void 0) {
@@ -2691,28 +3292,28 @@ function formatZaiReport(lines, report) {
2691
3292
  }
2692
3293
  lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${value}${reset}`);
2693
3294
  }
2694
- for (const metric of report.metrics) {
3295
+ for (const metric2 of report2.metrics) {
2695
3296
  lines.push(
2696
- `${`${metric.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric.value, metric.unit)}`
3297
+ `${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`
2697
3298
  );
2698
3299
  }
2699
3300
  }
2700
- function formatGenericReport(lines, report) {
2701
- for (const bucket of report.buckets) {
3301
+ function formatGenericReport(lines, report2) {
3302
+ for (const bucket of report2.buckets) {
2702
3303
  lines.push(
2703
3304
  `${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(bucket.remaining ?? bucket.used ?? "unavailable", bucket.unit)}`
2704
3305
  );
2705
3306
  }
2706
- for (const metric of report.metrics) {
3307
+ for (const metric2 of report2.metrics) {
2707
3308
  lines.push(
2708
- `${`${metric.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric.value, metric.unit)}`
3309
+ `${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`
2709
3310
  );
2710
3311
  }
2711
3312
  }
2712
- function formatCodexStatusline(report, model, now = Date.now(), showResetCountdown = true) {
2713
- const group = selectCodexGroup(report, model);
2714
- if (!group) return formatCodexCreditsStatus(report);
2715
- const buckets = report.buckets.filter((bucket) => (bucket.groupId ?? bucket.id) === group);
3313
+ function formatCodexStatusline(report2, model, now = Date.now(), showResetCountdown = true) {
3314
+ const group = selectCodexGroup(report2, model);
3315
+ if (!group) return formatCodexCreditsStatus(report2);
3316
+ const buckets = report2.buckets.filter((bucket) => (bucket.groupId ?? bucket.id) === group);
2716
3317
  const labelBucket = buckets[0];
2717
3318
  const parts = [
2718
3319
  group === "codex" ? "codex" : `codex ${compactLimitLabel(labelBucket?.groupLabel ?? group)}`
@@ -2729,24 +3330,24 @@ function formatCodexStatusline(report, model, now = Date.now(), showResetCountdo
2729
3330
  const reset = formatResetCountdown(bucket.resetsAt, now);
2730
3331
  parts.push(`${percent} ${reset ? `\u21BB ${reset}` : window}`);
2731
3332
  }
2732
- return parts.length > 1 ? parts.join(" ") : formatCodexCreditsStatus(report);
3333
+ return parts.length > 1 ? parts.join(" ") : formatCodexCreditsStatus(report2);
2733
3334
  }
2734
- function formatCodexCreditsStatus(report) {
2735
- const credits = report.metrics.find((metric) => metric.id === "credits");
3335
+ function formatCodexCreditsStatus(report2) {
3336
+ const credits = report2.metrics.find((metric2) => metric2.id === "credits");
2736
3337
  if (!credits) return "codex usage unavailable";
2737
3338
  if (credits.value === "none") return "codex no credits";
2738
3339
  if (credits.value === "available") return "codex credits available";
2739
3340
  if (credits.value === "unlimited") return "codex credits unlimited";
2740
3341
  return `codex ${formatMetricValue(credits.value, "count")} credits`;
2741
3342
  }
2742
- function selectCodexGroup(report, model) {
2743
- const groups = [...new Set(report.buckets.map((bucket) => bucket.groupId ?? bucket.id))];
3343
+ function selectCodexGroup(report2, model) {
3344
+ const groups = [...new Set(report2.buckets.map((bucket) => bucket.groupId ?? bucket.id))];
2744
3345
  if (model?.provider !== "openai-codex") {
2745
3346
  return groups.includes("codex") ? "codex" : groups[0];
2746
3347
  }
2747
3348
  const modelKeys = normalizedModelKeys(model);
2748
3349
  for (const group of groups) {
2749
- const bucket = report.buckets.find(
3350
+ const bucket = report2.buckets.find(
2750
3351
  (candidate) => (candidate.groupId ?? candidate.id) === group
2751
3352
  );
2752
3353
  const keys = [group, bucket?.groupLabel, ...bucket?.modelKeys ?? []].map(normalizeKey).filter((key) => key !== void 0);
@@ -3492,9 +4093,7 @@ function usageExtension(pi, dependencies = {}) {
3492
4093
  const generation = statusGeneration;
3493
4094
  statusCountdownTimer = setTimeout(() => {
3494
4095
  statusCountdownTimer = void 0;
3495
- if (!sessionActive || generation !== statusGeneration || modelIdentity(ctx.model) !== modelIdentity(model)) {
3496
- return;
3497
- }
4096
+ if (!sessionActive || generation !== statusGeneration) return;
3498
4097
  publishStatus(ctx, outcome, model, false);
3499
4098
  }, STATUS_COUNTDOWN_REFRESH_MS);
3500
4099
  statusCountdownTimer.unref?.();
@@ -3549,7 +4148,17 @@ function usageExtension(pi, dependencies = {}) {
3549
4148
  }
3550
4149
  };
3551
4150
  }
3552
- const requiresRequestBoundaryGuard = ["deepseek", "fireworks", "xai"].includes(adapter.id);
4151
+ const requiresRequestBoundaryGuard = [
4152
+ "baseten",
4153
+ "deepseek",
4154
+ "fireworks",
4155
+ "minimax",
4156
+ "minimax-cn",
4157
+ "moonshotai",
4158
+ "moonshotai-cn",
4159
+ "vercel-ai-gateway",
4160
+ "xai"
4161
+ ].includes(adapter.id);
3553
4162
  const requestContextChanged = () => expectedSessionGeneration !== sessionGeneration || ctx.sessionManager.getSessionId() !== expectedSessionId || modelIdentity(ctx.model) !== expectedModelIdentity || adapter.id === "fireworks" && settingsRuntime.get().settings.fireworksAccountId !== expectedFireworksAccountId;
3554
4163
  if (requiresRequestBoundaryGuard && requestContextChanged()) throw abortError();
3555
4164
  if (!auth) {
@@ -3602,7 +4211,7 @@ function usageExtension(pi, dependencies = {}) {
3602
4211
  querySequence += 1;
3603
4212
  const queryId = querySequence;
3604
4213
  setBoundedMap(latestQueries, failureKey, queryId, MAX_ACCOUNT_STATES);
3605
- let deepSeekAuthChanged = false;
4214
+ let retryableAuthChanged = false;
3606
4215
  try {
3607
4216
  const remainingMs = Math.max(1, deadlineAt - Date.now());
3608
4217
  const guard = requiresRequestBoundaryGuard ? async () => {
@@ -3615,14 +4224,16 @@ function usageExtension(pi, dependencies = {}) {
3615
4224
  );
3616
4225
  if (signal.aborted || requestContextChanged()) throw abortError();
3617
4226
  if (revalidated?.fingerprint !== auth.fingerprint) {
3618
- if (adapter.id === "deepseek") {
3619
- deepSeekAuthChanged = true;
3620
- throw new Error("DeepSeek runtime credential changed during the balance query.");
4227
+ if (["deepseek", "minimax", "minimax-cn"].includes(adapter.id)) {
4228
+ retryableAuthChanged = true;
4229
+ throw new Error(
4230
+ `${adapter.displayName} runtime credential changed during the usage query.`
4231
+ );
3621
4232
  }
3622
4233
  throw abortError();
3623
4234
  }
3624
4235
  } : void 0;
3625
- const report = await queryProviderUsage(
4236
+ const report2 = await queryProviderUsage(
3626
4237
  adapter,
3627
4238
  auth,
3628
4239
  signal,
@@ -3632,7 +4243,7 @@ function usageExtension(pi, dependencies = {}) {
3632
4243
  );
3633
4244
  if (guard) await guard();
3634
4245
  if (latestQueries.get(failureKey) === queryId) {
3635
- cache.set(adapter.id, queryFingerprint, report);
4246
+ cache.set(adapter.id, queryFingerprint, report2);
3636
4247
  failureBackoff.delete(failureKey);
3637
4248
  }
3638
4249
  return {
@@ -3641,13 +4252,13 @@ function usageExtension(pi, dependencies = {}) {
3641
4252
  providerName: adapter.displayName,
3642
4253
  displayState,
3643
4254
  status: "ready",
3644
- report
4255
+ report: report2
3645
4256
  },
3646
4257
  fingerprint: auth.fingerprint
3647
4258
  };
3648
4259
  } catch (error) {
3649
4260
  if (isStaleExtensionContextError(error) || isAbortError3(error)) throw error;
3650
- if (deepSeekAuthChanged && authRetry === 0 && !signal.aborted && !requestContextChanged() && Date.now() < deadlineAt) {
4261
+ if (retryableAuthChanged && authRetry === 0 && !signal.aborted && !requestContextChanged() && Date.now() < deadlineAt) {
3651
4262
  if (latestQueries.get(failureKey) === queryId) latestQueries.delete(failureKey);
3652
4263
  return queryAdapterState(
3653
4264
  ctx,
@@ -4335,6 +4946,8 @@ export {
4335
4946
  isStaleExtensionContextError,
4336
4947
  listCodexResetCredits,
4337
4948
  loadUsageSettings,
4949
+ miniMaxUsageKind,
4950
+ normalizeBasetenBillingUsagePayload,
4338
4951
  normalizeCodexBackendPayload,
4339
4952
  normalizeCodexResetCreditsPayload,
4340
4953
  normalizeDeepSeekBalancePayload,
@@ -4342,9 +4955,12 @@ export {
4342
4955
  normalizeFireworksBillingSummaryPayload,
4343
4956
  normalizeGitHubCopilotUsagePayload,
4344
4957
  normalizeKimiCodingUsagePayload,
4958
+ normalizeMiniMaxUsagePayload,
4959
+ normalizeMoonshotBalancePayload,
4345
4960
  normalizeOpenCodeZenPayload,
4346
4961
  normalizeOpenRouterKeyPayload,
4347
4962
  normalizeUsageSettings,
4963
+ normalizeVercelAIGatewayCreditsPayload,
4348
4964
  normalizeXaiBillingPayload,
4349
4965
  normalizeZaiQuotaPayload,
4350
4966
  providerIsConfigured,