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