@narumitw/pi-usage 0.59.0 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -6
- package/dist/index.ts +136 -39
- package/dist/index.ts.map +2 -2
- package/package.json +1 -1
- package/src/format.ts +15 -8
- package/src/index.ts +1 -1
- package/src/providers/zai.ts +109 -5
- package/src/query.ts +62 -26
- package/src/types.ts +11 -0
- package/src/usage.ts +2 -0
package/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@narumitw/pi-usage) [](https://pi.dev) [](./LICENSE)
|
|
4
4
|
|
|
5
5
|
Inspect usage and DeepSeek API balance for Pi's active provider account, query other configured providers, and toggle Fast mode for supported OpenAI Codex models.
|
|
6
|
-
|
|
7
6
|
The extension keeps each provider's native quota, allowance, and spending semantics instead of treating unlike values as equivalent.
|
|
8
7
|
xAI OAuth subscription reporting follows the reviewed Grok Build contract and runs only after an explicit `/usage` action.
|
|
9
8
|
|
|
@@ -122,7 +121,6 @@ Submit a blank value from the TUI input, or remove the JSON field and run `/relo
|
|
|
122
121
|
### Codex Fast mode
|
|
123
122
|
|
|
124
123
|
Run `/fast` without arguments to toggle Fast for the active supported Codex model, or use **Turn Fast mode on/off** in `/usage`.
|
|
125
|
-
|
|
126
124
|
Fast is about 1.5× faster and uses more of your plan allowance.
|
|
127
125
|
The `codexFastMode` preference defaults to Off.
|
|
128
126
|
|
|
@@ -138,7 +136,6 @@ Repair or remove an invalid file, then run `/reload` before trying the toggle ag
|
|
|
138
136
|
### Codex statusline reset countdown
|
|
139
137
|
|
|
140
138
|
The `codexStatusResetCountdown` preference defaults to `true`. It replaces the window labels with the time remaining until each returned limit resets.
|
|
141
|
-
|
|
142
139
|
Turn **Codex reset countdown** Off in the TUI Settings screen, or set it to `false` in `pi-usage.json` and run `/reload`, to restore the legacy `5h` and `wk` labels:
|
|
143
140
|
|
|
144
141
|
```json
|
|
@@ -374,9 +371,9 @@ xAI identity and billing requests occur only after an explicit current, configur
|
|
|
374
371
|
|
|
375
372
|
- Provider ID: `zai` and `zai-coding-cn`
|
|
376
373
|
- Semantics: GLM Coding Plan quota windows—the rolling 5-hour and weekly plan-usage windows plus the monthly MCP allowance
|
|
377
|
-
- Source: the undocumented `GET {origin}/api/monitor/usage/quota/limit` endpoint also used by Z.AI's official coding plugin
|
|
374
|
+
- Source: the undocumented `GET {origin}/api/monitor/usage/quota/limit` endpoint also used by Z.AI's official coding plugin, plus the undocumented `GET {origin}/api/biz/subscription/list` plan endpoint
|
|
378
375
|
- Allowed origins: the model base URL must resolve to `https://api.z.ai` or `https://open.bigmodel.cn`
|
|
379
|
-
- Displayed data: explicit used and remaining values, reset times, provider-reported per-tool MCP details, and the
|
|
376
|
+
- Displayed data: explicit used and remaining values, reset times, provider-reported per-tool MCP details, and the plan name with its renewal date
|
|
380
377
|
- Percentage-only windows remain percent-based
|
|
381
378
|
- Statusline: publishes remaining plan percentages such as `zai 87% 5h 76% wk`; monthly MCP details remain available through `/usage`
|
|
382
379
|
|
|
@@ -385,6 +382,7 @@ The extension classifies both forms by the provider's window unit and does not l
|
|
|
385
382
|
The quota monitor expects a raw API key without a `Bearer` prefix.
|
|
386
383
|
The extension removes that prefix from resolved authorization before sending it to the monitor endpoint.
|
|
387
384
|
Fingerprinting and redaction keep using the original resolved credential.
|
|
385
|
+
The plan endpoint only contributes the plan name and renewal date; when it is unavailable or fails, the quota windows remain reported and the plan note falls back to the quota response's plan level.
|
|
388
386
|
Only the official `api.z.ai` and `open.bigmodel.cn` origins are queried; other origins fail before sending the credential.
|
|
389
387
|
|
|
390
388
|
## 🧭 Current and configured accounts
|
|
@@ -501,7 +499,6 @@ packages/pi-usage/
|
|
|
501
499
|
```
|
|
502
500
|
|
|
503
501
|
`index.ts` is the Pi entrypoint and forwards the default factory from `usage.ts` while retaining the package's named helper exports; other source modules are internal.
|
|
504
|
-
|
|
505
502
|
The generated runtime is built from the authoritative `src/index.ts` graph and does not import back into `src`.
|
|
506
503
|
|
|
507
504
|
## 🔎 Keywords
|
package/dist/index.ts
CHANGED
|
@@ -1604,7 +1604,7 @@ function isRecord2(value) {
|
|
|
1604
1604
|
// src/providers/zai.ts
|
|
1605
1605
|
var FIVE_HOUR_WINDOW_MINUTES2 = 300;
|
|
1606
1606
|
var WEEKLY_WINDOW_MINUTES2 = 10080;
|
|
1607
|
-
function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt) {
|
|
1607
|
+
function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt, plan) {
|
|
1608
1608
|
const data = asObject11(payload.data);
|
|
1609
1609
|
if (!data) throw new Error("Z.AI quota response data was not an object.");
|
|
1610
1610
|
const limits = Array.isArray(data.limits) ? data.limits : [];
|
|
@@ -1620,14 +1620,20 @@ function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt)
|
|
|
1620
1620
|
addCountBucket(buckets, limit, "mcp-monthly", "MCP monthly allowance");
|
|
1621
1621
|
addUsageDetailMetrics(metrics, limit.usageDetails);
|
|
1622
1622
|
} else if (isPlanUsage && unit === 3) {
|
|
1623
|
-
addPercentBucket(
|
|
1623
|
+
addPercentBucket(
|
|
1624
|
+
buckets,
|
|
1625
|
+
limit,
|
|
1626
|
+
"five-hour",
|
|
1627
|
+
sessionWindowLabel(limit),
|
|
1628
|
+
sessionWindowMinutes(limit)
|
|
1629
|
+
);
|
|
1624
1630
|
} else if (isPlanUsage && unit === 6) {
|
|
1625
1631
|
const used = asNonnegativeNumber4(limit.currentValue);
|
|
1626
1632
|
const quota = asNonnegativeNumber4(limit.usage);
|
|
1627
1633
|
if (used !== void 0 && quota !== void 0) {
|
|
1628
|
-
addCountBucket(buckets, limit, "weekly", "Weekly window",
|
|
1634
|
+
addCountBucket(buckets, limit, "weekly", "Weekly window", weeklyWindowMinutes(limit));
|
|
1629
1635
|
} else {
|
|
1630
|
-
addPercentBucket(buckets, limit, "weekly", "Weekly window",
|
|
1636
|
+
addPercentBucket(buckets, limit, "weekly", "Weekly window", weeklyWindowMinutes(limit));
|
|
1631
1637
|
}
|
|
1632
1638
|
}
|
|
1633
1639
|
}
|
|
@@ -1636,7 +1642,12 @@ function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt)
|
|
|
1636
1642
|
}
|
|
1637
1643
|
const notes = [];
|
|
1638
1644
|
const level = asString5(data.level);
|
|
1639
|
-
|
|
1645
|
+
const planLabel = plan?.name ?? level;
|
|
1646
|
+
if (planLabel) {
|
|
1647
|
+
notes.push(
|
|
1648
|
+
plan?.renewsAt ? `Plan: ${planLabel} \xB7 renews ${plan.renewsAt}` : `Plan: ${planLabel}`
|
|
1649
|
+
);
|
|
1650
|
+
}
|
|
1640
1651
|
return {
|
|
1641
1652
|
providerId,
|
|
1642
1653
|
providerName,
|
|
@@ -1648,6 +1659,57 @@ function normalizeZaiQuotaPayload(providerId, providerName, payload, capturedAt)
|
|
|
1648
1659
|
...notes.length > 0 ? { notes } : {}
|
|
1649
1660
|
};
|
|
1650
1661
|
}
|
|
1662
|
+
function normalizeZaiSubscriptionPayload(payload) {
|
|
1663
|
+
if (payload.success === false) return void 0;
|
|
1664
|
+
if (typeof payload.code === "number" && payload.code !== 0 && payload.code !== 200) {
|
|
1665
|
+
return void 0;
|
|
1666
|
+
}
|
|
1667
|
+
if (!Array.isArray(payload.data)) return void 0;
|
|
1668
|
+
const candidates = [];
|
|
1669
|
+
for (const raw of payload.data) {
|
|
1670
|
+
const entry = asObject11(raw);
|
|
1671
|
+
if (!entry) continue;
|
|
1672
|
+
const name = asString5(entry.productName);
|
|
1673
|
+
if (!name) continue;
|
|
1674
|
+
const renewsAt = planRenewalDate(entry.nextRenewTime);
|
|
1675
|
+
const status = asString5(entry.status)?.toUpperCase();
|
|
1676
|
+
const inCurrentPeriod = asBoolean(entry.inCurrentPeriod);
|
|
1677
|
+
candidates.push({
|
|
1678
|
+
plan: { name, ...renewsAt !== void 0 ? { renewsAt } : {} },
|
|
1679
|
+
...status !== void 0 ? { status } : {},
|
|
1680
|
+
...inCurrentPeriod !== void 0 ? { inCurrentPeriod } : {}
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
const hasStateMetadata = candidates.some(
|
|
1684
|
+
(candidate) => candidate.status !== void 0 || candidate.inCurrentPeriod !== void 0
|
|
1685
|
+
);
|
|
1686
|
+
if (!hasStateMetadata) return candidates[0]?.plan;
|
|
1687
|
+
return candidates.find(
|
|
1688
|
+
(candidate) => candidate.inCurrentPeriod === true && candidate.status === "VALID"
|
|
1689
|
+
)?.plan ?? candidates.find(
|
|
1690
|
+
(candidate) => candidate.inCurrentPeriod === true && candidate.status === void 0
|
|
1691
|
+
)?.plan ?? candidates.find(
|
|
1692
|
+
(candidate) => candidate.status === "VALID" && candidate.inCurrentPeriod === void 0
|
|
1693
|
+
)?.plan;
|
|
1694
|
+
}
|
|
1695
|
+
function planRenewalDate(value) {
|
|
1696
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}/u.test(value)) return value.slice(0, 10);
|
|
1697
|
+
const millis = asNonnegativeNumber4(value);
|
|
1698
|
+
if (millis === void 0 || millis === 0) return void 0;
|
|
1699
|
+
return new Date(millis).toISOString().slice(0, 10);
|
|
1700
|
+
}
|
|
1701
|
+
function sessionWindowMinutes(limit) {
|
|
1702
|
+
const hours = asPositiveNumber(limit.number);
|
|
1703
|
+
return hours === void 0 ? FIVE_HOUR_WINDOW_MINUTES2 : Math.round(hours * 60);
|
|
1704
|
+
}
|
|
1705
|
+
function sessionWindowLabel(limit) {
|
|
1706
|
+
const minutes = sessionWindowMinutes(limit);
|
|
1707
|
+
return minutes === FIVE_HOUR_WINDOW_MINUTES2 ? "5h window" : `${Math.round(minutes / 60)}h window`;
|
|
1708
|
+
}
|
|
1709
|
+
function weeklyWindowMinutes(limit) {
|
|
1710
|
+
const weeks = asPositiveNumber(limit.number);
|
|
1711
|
+
return weeks === void 0 ? WEEKLY_WINDOW_MINUTES2 : Math.round(weeks * WEEKLY_WINDOW_MINUTES2);
|
|
1712
|
+
}
|
|
1651
1713
|
function addPercentBucket(buckets, limit, id, label, windowMinutes) {
|
|
1652
1714
|
const used = asNonnegativeNumber4(limit.percentage);
|
|
1653
1715
|
if (used === void 0) return;
|
|
@@ -1703,6 +1765,16 @@ function asNonnegativeNumber4(value) {
|
|
|
1703
1765
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
|
|
1704
1766
|
return value;
|
|
1705
1767
|
}
|
|
1768
|
+
function asPositiveNumber(value) {
|
|
1769
|
+
const number = asNonnegativeNumber4(value);
|
|
1770
|
+
return number !== void 0 && number > 0 ? number : void 0;
|
|
1771
|
+
}
|
|
1772
|
+
function asBoolean(value) {
|
|
1773
|
+
if (typeof value === "boolean") return value;
|
|
1774
|
+
if (value === 1) return true;
|
|
1775
|
+
if (value === 0) return false;
|
|
1776
|
+
return void 0;
|
|
1777
|
+
}
|
|
1706
1778
|
function asEpochSeconds2(value) {
|
|
1707
1779
|
const millis = asNonnegativeNumber4(value);
|
|
1708
1780
|
if (millis === void 0) return void 0;
|
|
@@ -1958,35 +2030,16 @@ var SUPPORTED_ADAPTERS = [
|
|
|
1958
2030
|
id: "zai",
|
|
1959
2031
|
displayName: "Z.AI",
|
|
1960
2032
|
semantics: { kind: "consumer-subscription", label: "GLM Coding Plan usage" },
|
|
1961
|
-
async query(auth, signal, timeoutMs) {
|
|
1962
|
-
|
|
1963
|
-
zaiMonitorUrl(auth.model.baseUrl),
|
|
1964
|
-
zaiMonitorAuth(auth),
|
|
1965
|
-
signal,
|
|
1966
|
-
timeoutMs,
|
|
1967
|
-
"Z.AI quota endpoint"
|
|
1968
|
-
);
|
|
1969
|
-
return normalizeZaiQuotaPayload("zai", "Z.AI", payload, Date.now());
|
|
2033
|
+
async query(auth, signal, timeoutMs, guard) {
|
|
2034
|
+
return queryZaiUsage("zai", "Z.AI", auth, signal, timeoutMs, guard);
|
|
1970
2035
|
}
|
|
1971
2036
|
},
|
|
1972
2037
|
{
|
|
1973
2038
|
id: "zai-coding-cn",
|
|
1974
2039
|
displayName: "Z.AI Coding CN",
|
|
1975
2040
|
semantics: { kind: "consumer-subscription", label: "GLM Coding Plan usage" },
|
|
1976
|
-
async query(auth, signal, timeoutMs) {
|
|
1977
|
-
|
|
1978
|
-
zaiMonitorUrl(auth.model.baseUrl),
|
|
1979
|
-
zaiMonitorAuth(auth),
|
|
1980
|
-
signal,
|
|
1981
|
-
timeoutMs,
|
|
1982
|
-
"Z.AI Coding CN quota endpoint"
|
|
1983
|
-
);
|
|
1984
|
-
return normalizeZaiQuotaPayload(
|
|
1985
|
-
"zai-coding-cn",
|
|
1986
|
-
"Z.AI Coding CN",
|
|
1987
|
-
payload,
|
|
1988
|
-
Date.now()
|
|
1989
|
-
);
|
|
2041
|
+
async query(auth, signal, timeoutMs, guard) {
|
|
2042
|
+
return queryZaiUsage("zai-coding-cn", "Z.AI Coding CN", auth, signal, timeoutMs, guard);
|
|
1990
2043
|
}
|
|
1991
2044
|
}
|
|
1992
2045
|
];
|
|
@@ -2590,10 +2643,13 @@ function fireworksBillingSummaryUrl(accountId, startedAt) {
|
|
|
2590
2643
|
url.searchParams.set("endTime", dayFloor(startedAt + dayMs));
|
|
2591
2644
|
return url.toString();
|
|
2592
2645
|
}
|
|
2593
|
-
function
|
|
2646
|
+
function zaiOrigin(baseUrl) {
|
|
2594
2647
|
const base = baseUrl?.trim();
|
|
2595
2648
|
if (!base) throw new Error("Z.AI model base URL is unavailable.");
|
|
2596
|
-
return
|
|
2649
|
+
return new URL(base).origin;
|
|
2650
|
+
}
|
|
2651
|
+
function zaiMonitorUrl(baseUrl) {
|
|
2652
|
+
return `${zaiOrigin(baseUrl)}/api/monitor/usage/quota/limit`;
|
|
2597
2653
|
}
|
|
2598
2654
|
function zaiMonitorAuth(auth) {
|
|
2599
2655
|
const authorization = headerValue(auth.headers, "Authorization");
|
|
@@ -2601,6 +2657,38 @@ function zaiMonitorAuth(auth) {
|
|
|
2601
2657
|
if (token === void 0 || token === authorization) return auth;
|
|
2602
2658
|
return { ...auth, headers: { ...auth.headers, Authorization: token } };
|
|
2603
2659
|
}
|
|
2660
|
+
async function queryZaiUsage(providerId, providerName, auth, signal, timeoutMs, guard) {
|
|
2661
|
+
if (!guard) throw new Error("Z.AI usage requires request-boundary revalidation.");
|
|
2662
|
+
const startedAt = Date.now();
|
|
2663
|
+
await guard();
|
|
2664
|
+
const payload = await fetchProviderJson(
|
|
2665
|
+
zaiMonitorUrl(auth.model.baseUrl),
|
|
2666
|
+
zaiMonitorAuth(auth),
|
|
2667
|
+
signal,
|
|
2668
|
+
remainingTimeout(timeoutMs, startedAt, `fetching ${providerName} quota`),
|
|
2669
|
+
`${providerName} quota endpoint`
|
|
2670
|
+
);
|
|
2671
|
+
await guard();
|
|
2672
|
+
const planTimeoutMs = timeoutMs - (Date.now() - startedAt);
|
|
2673
|
+
const plan = await fetchZaiPlan(providerName, auth, signal, planTimeoutMs);
|
|
2674
|
+
return normalizeZaiQuotaPayload(providerId, providerName, payload, Date.now(), plan);
|
|
2675
|
+
}
|
|
2676
|
+
async function fetchZaiPlan(providerName, auth, signal, timeoutMs) {
|
|
2677
|
+
if (timeoutMs <= 0 || signal.aborted) return void 0;
|
|
2678
|
+
try {
|
|
2679
|
+
const payload = await fetchProviderJson(
|
|
2680
|
+
`${zaiOrigin(auth.model.baseUrl)}/api/biz/subscription/list`,
|
|
2681
|
+
zaiMonitorAuth(auth),
|
|
2682
|
+
signal,
|
|
2683
|
+
timeoutMs,
|
|
2684
|
+
`${providerName} plan endpoint`
|
|
2685
|
+
);
|
|
2686
|
+
return normalizeZaiSubscriptionPayload(payload);
|
|
2687
|
+
} catch (error) {
|
|
2688
|
+
if (isAbortError(error)) throw error;
|
|
2689
|
+
return void 0;
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2604
2692
|
function isAbortError(error) {
|
|
2605
2693
|
return error instanceof Error && error.name === "AbortError";
|
|
2606
2694
|
}
|
|
@@ -3077,6 +3165,10 @@ function formatOpenRouterReport(lines, report2) {
|
|
|
3077
3165
|
}
|
|
3078
3166
|
function formatOpenCodeZenReport(lines, report2) {
|
|
3079
3167
|
for (const bucket of report2.buckets) {
|
|
3168
|
+
if (bucket.unit === "percent" && bucket.used !== void 0) {
|
|
3169
|
+
lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${formatPercentBucket(bucket)}`);
|
|
3170
|
+
continue;
|
|
3171
|
+
}
|
|
3080
3172
|
const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
|
|
3081
3173
|
const used = bucket.used ?? "unavailable";
|
|
3082
3174
|
lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${used}% used${reset}`);
|
|
@@ -3251,8 +3343,7 @@ function formatXaiReport(lines, report2) {
|
|
|
3251
3343
|
if (included) {
|
|
3252
3344
|
let value = "unavailable";
|
|
3253
3345
|
if (included.unit === "percent" && included.used !== void 0) {
|
|
3254
|
-
value =
|
|
3255
|
-
if (included.remaining !== void 0) value += ` \xB7 ${included.remaining}% left`;
|
|
3346
|
+
value = formatPercentBar(included);
|
|
3256
3347
|
} else if (included.used !== void 0) {
|
|
3257
3348
|
value = `${formatUsd(included.used)} used`;
|
|
3258
3349
|
if (included.limit !== void 0) value += ` of ${formatUsd(included.limit)}`;
|
|
@@ -3277,12 +3368,13 @@ function formatXaiReport(lines, report2) {
|
|
|
3277
3368
|
}
|
|
3278
3369
|
function formatZaiReport(lines, report2) {
|
|
3279
3370
|
for (const bucket of report2.buckets) {
|
|
3371
|
+
if (bucket.unit === "percent" && bucket.used !== void 0) {
|
|
3372
|
+
lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${formatPercentBucket(bucket)}`);
|
|
3373
|
+
continue;
|
|
3374
|
+
}
|
|
3280
3375
|
const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
|
|
3281
3376
|
let value = "unavailable";
|
|
3282
|
-
if (bucket.
|
|
3283
|
-
value = `${bucket.used}% used`;
|
|
3284
|
-
if (bucket.remaining !== void 0) value += ` \xB7 ${bucket.remaining}% left`;
|
|
3285
|
-
} else if (bucket.used !== void 0 && bucket.limit !== void 0) {
|
|
3377
|
+
if (bucket.used !== void 0 && bucket.limit !== void 0) {
|
|
3286
3378
|
value = `${bucket.used} of ${bucket.limit} used`;
|
|
3287
3379
|
if (bucket.remaining !== void 0) value += ` \xB7 ${bucket.remaining} left`;
|
|
3288
3380
|
} else if (bucket.used !== void 0) {
|
|
@@ -3394,10 +3486,12 @@ function compactLimitLabel(label) {
|
|
|
3394
3486
|
return (suffix || normalized).toLowerCase().replace(/\s+/g, " ");
|
|
3395
3487
|
}
|
|
3396
3488
|
function formatPercentBucket(bucket) {
|
|
3489
|
+
return `${formatPercentBar(bucket)}${bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : ""}`;
|
|
3490
|
+
}
|
|
3491
|
+
function formatPercentBar(bucket) {
|
|
3397
3492
|
const remaining = clampPercent4(bucket.remaining ?? 0);
|
|
3398
3493
|
const filled = Math.round(remaining / 100 * BAR_SEGMENTS);
|
|
3399
|
-
|
|
3400
|
-
return `[${"\u2588".repeat(filled)}${"\u2591".repeat(BAR_SEGMENTS - filled)}] ${remaining.toFixed(0)}% left${reset}`;
|
|
3494
|
+
return `[${"\u2588".repeat(filled)}${"\u2591".repeat(BAR_SEGMENTS - filled)}] ${remaining.toFixed(0)}% left`;
|
|
3401
3495
|
}
|
|
3402
3496
|
function formatWindowLabel(minutes, fallback, compact) {
|
|
3403
3497
|
if (!minutes || !Number.isFinite(minutes) || minutes <= 0) {
|
|
@@ -4157,7 +4251,9 @@ function usageExtension(pi, dependencies = {}) {
|
|
|
4157
4251
|
"moonshotai",
|
|
4158
4252
|
"moonshotai-cn",
|
|
4159
4253
|
"vercel-ai-gateway",
|
|
4160
|
-
"xai"
|
|
4254
|
+
"xai",
|
|
4255
|
+
"zai",
|
|
4256
|
+
"zai-coding-cn"
|
|
4161
4257
|
].includes(adapter.id);
|
|
4162
4258
|
const requestContextChanged = () => expectedSessionGeneration !== sessionGeneration || ctx.sessionManager.getSessionId() !== expectedSessionId || modelIdentity(ctx.model) !== expectedModelIdentity || adapter.id === "fireworks" && settingsRuntime.get().settings.fireworksAccountId !== expectedFireworksAccountId;
|
|
4163
4259
|
if (requiresRequestBoundaryGuard && requestContextChanged()) throw abortError();
|
|
@@ -4963,6 +5059,7 @@ export {
|
|
|
4963
5059
|
normalizeVercelAIGatewayCreditsPayload,
|
|
4964
5060
|
normalizeXaiBillingPayload,
|
|
4965
5061
|
normalizeZaiQuotaPayload,
|
|
5062
|
+
normalizeZaiSubscriptionPayload,
|
|
4966
5063
|
providerIsConfigured,
|
|
4967
5064
|
queryProviderUsage,
|
|
4968
5065
|
redactUsageError,
|