authorgravatar for jakeleventhal@me.comJake Leventhal <jakeleventhal@me.com> 2026-09-24 21:38:21-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-24 18:38:21-07:00
log0cab7d5ab978a8adaee6827f81693249d0dfeee5
tree3c265af716cd15a5e1fd63be98b7bc40ada43b17
parentd23eab13d9d91697c5d4e7a458213b3f6473bc96
signature Signed by PGP key B5690EEEBB952194

fix(server): Grok accounts with no usage yet no longer vanish from Limits (#12799)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

2 files changed, 13 insertions(+), 2 deletions(-)

apps/server/src/provider/Layers/GrokProvider.test.ts+4-1
...@@ -564,7 +564,10 @@ describe("Grok usage limits", () => {...@@ -564,7 +564,10 @@ describe("Grok usage limits", () => {
564 for (const response of [{}, { config: {} }, { config: { creditUsagePercent: NaN } }]) {564 for (const response of [{}, { config: {} }, { config: { creditUsagePercent: NaN } }]) {
565 const limits = grokUsageResponseToLimits(response, checkedAt);565 const limits = grokUsageResponseToLimits(response, checkedAt);
566 expect(limits.windows).toEqual([]);566 expect(limits.windows).toEqual([]);
567 expect(limits.unavailable?.reason).toBe("unsupported");567 // Nothing metered yet, which xAI reports by omitting the field until
568 // usage registers. Marking it `unsupported` would drop the account from
569 // the Limits view for good; leaving the marker off keeps it listed.
570 expect(limits.unavailable).toBeUndefined();
568 }571 }
569 expect(572 expect(
570 grokUsageResponseToLimits({ config: { creditUsagePercent: 0 } }, checkedAt).windows,573 grokUsageResponseToLimits({ config: { creditUsagePercent: 0 } }, checkedAt).windows,
apps/server/src/provider/Layers/grokUsageLimits.ts+9-1
...@@ -41,7 +41,15 @@ export function grokUsageResponseToLimits(...@@ -41,7 +41,15 @@ export function grokUsageResponseToLimits(
41) {41) {
42 const usedPercent = response.config?.creditUsagePercent;42 const usedPercent = response.config?.creditUsagePercent;
43 if (usedPercent === undefined || !Number.isFinite(usedPercent)) {43 if (usedPercent === undefined || !Number.isFinite(usedPercent)) {
44 return makeUnavailableUsageLimits({ checkedAt, reason: "unsupported" });44 // A billing read that succeeded but carries no percentage is an account
45 // with nothing metered yet, not one that can never report: xAI omits the
46 // field entirely (rather than sending 0) until usage registers, then fills
47 // it in. Calling that `unsupported` would strand the account — the Limits
48 // view drops unsupported entries and deliberately mutes their notice, so a
49 // freshly signed-in Grok account would vanish with no explanation until it
50 // happened to be used, and `applyUsageLimitsUpdate` would refuse the
51 // mid-turn windows that could have recovered it.
52 return makeUsageLimits({ checkedAt, windows: [] });
45 }53 }
46 const period = response.config?.currentPeriod;54 const period = response.config?.currentPeriod;
47 const periodType = period?.type?.replace(/^USAGE_PERIOD_TYPE_/, "");55 const periodType = period?.type?.replace(/^USAGE_PERIOD_TYPE_/, "");