diff --git a/packages/ai/src/usage/xai-oauth.ts b/packages/ai/src/usage/xai-oauth.ts index c024f2fea..63bb8006f 100644 --- a/packages/ai/src/usage/xai-oauth.ts +++ b/packages/ai/src/usage/xai-oauth.ts @@ -373,10 +373,21 @@ export const xaiOauthUsageProvider: UsageProvider = { : null; } - // When an account has an explicit monthly included quota and weekly credits - // were only inferred from an omitted percentage field, prefer the monthly quota - // so pure monthly unified accounts do not render a phantom weekly credit. - const effectiveWeekly = weekly && (!monthly || !weekly.inferredPercent) ? weekly : null; + // When an account is marked unified billing and weekly credits were only inferred + // from an omitted percentage field: + // - If a positive monthly quota is returned, use the monthly quota alone. + // - If the monthly endpoint returned a valid config without positive monthly quota, + // confirm that this account relies on the weekly reset cycle and use weekly. + // - If the monthly fetch failed (transient network error), reject inferred weekly + // so AuthStorage's retain-last-good cache preserves the previous valid snapshot. + let effectiveWeekly = weekly; + if (weekly?.inferredPercent && creditsLooksUnified) { + if (monthly) { + effectiveWeekly = null; + } else if (!monthlyPayload || !isRecord(monthlyPayload) || !isRecord(monthlyPayload.config)) { + effectiveWeekly = null; + } + } if (!effectiveWeekly && !monthly) return null; const limits: UsageLimit[] = []; diff --git a/packages/ai/test/xai-oauth-usage.test.ts b/packages/ai/test/xai-oauth-usage.test.ts index ca809972a..30cc1539b 100644 --- a/packages/ai/test/xai-oauth-usage.test.ts +++ b/packages/ai/test/xai-oauth-usage.test.ts @@ -125,6 +125,9 @@ function dualBillingFetch( }); } const payload = url.includes("format=credits") ? creditsPayload : monthlyPayload; + if (payload === null) { + return new Response("internal error", { status: 500 }); + } return new Response(JSON.stringify(payload), { status: 200, headers: { "content-type": "application/json" }, @@ -278,6 +281,31 @@ describe("xai-oauth usage provider", () => { expect(credits?.window?.resetsAt).toBe(Date.parse(periodEnd)); }); + it("rejects inferred unified weekly usage when the monthly probe encounters a network error", async () => { + const periodEnd = new Date(Date.now() + 6 * 24 * 60 * 60 * 1000).toISOString(); + const periodStart = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(); + const report = await xaiOauthUsageProvider.fetchUsage( + { provider: "xai-oauth", credential: makeCredential() }, + { + fetch: dualBillingFetch( + { + config: { + currentPeriod: { + end: periodEnd, + start: periodStart, + type: "USAGE_PERIOD_TYPE_WEEKLY", + }, + isUnifiedBillingUser: true, + }, + }, + null, + ).fetch, + }, + ); + + expect(report).toBeNull(); + }); + it("falls back to monthly included quota when credits has no percent fields", async () => { const { fetch, calls } = dualBillingFetch(makeUnifiedCreditsPayload(), makeUnifiedMonthlyPayload()); const report = await xaiOauthUsageProvider.fetchUsage(