From bbd6c59d25f16a852e43025a377fee1aeb6183ec Mon Sep 17 00:00:00 2001 From: bubua12 Date: Wed, 12 Aug 2026 16:05:56 +0800 Subject: [PATCH] fix(ai): gate 0% usage inference to active weekly periods - Only infer 0% creditUsagePercent when end > now (active period). - Reject expired weekly periods without explicit usage data so stale cache fallback is retained until rollover completes. - Add unit test verifying expired periods without usage percent are rejected. --- packages/ai/src/usage/xai-oauth.ts | 13 ++++++++----- packages/ai/test/xai-oauth-usage.test.ts | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/ai/src/usage/xai-oauth.ts b/packages/ai/src/usage/xai-oauth.ts index 9a6e172a8..40aaa08ed 100644 --- a/packages/ai/src/usage/xai-oauth.ts +++ b/packages/ai/src/usage/xai-oauth.ts @@ -138,11 +138,14 @@ function parseWeeklyBillingConfig(raw: Record): XaiWeeklyBillin } // Fresh weekly periods (or accounts with 0 usage) omit creditUsagePercent; - // default to 0 when a valid weekly period exists. - const creditUsagePercent = - raw.creditUsagePercent === undefined || raw.creditUsagePercent === null - ? 0 - : parsePercent(raw.creditUsagePercent); + // default to 0 only when the weekly period is active (end > now). + // Expired periods without explicit usage data are rejected to retain last good cache. + let creditUsagePercent: number | undefined; + if (raw.creditUsagePercent === undefined || raw.creditUsagePercent === null) { + creditUsagePercent = end > Date.now() ? 0 : undefined; + } else { + creditUsagePercent = parsePercent(raw.creditUsagePercent); + } if (creditUsagePercent === undefined) return null; const productUsage: XaiProductUsage[] = []; diff --git a/packages/ai/test/xai-oauth-usage.test.ts b/packages/ai/test/xai-oauth-usage.test.ts index 9be58536f..1330f2128 100644 --- a/packages/ai/test/xai-oauth-usage.test.ts +++ b/packages/ai/test/xai-oauth-usage.test.ts @@ -224,6 +224,26 @@ describe("xai-oauth usage provider", () => { expect(report?.limits[0]?.id).toBe("xai-oauth:credits:1w"); expect(report?.limits[0]?.window?.resetsAt).toBe(Date.parse(periodEnd)); }); + it("rejects an expired weekly period when creditUsagePercent is omitted", async () => { + const periodEnd = new Date(Date.now() - 60_000).toISOString(); + const periodStart = new Date(Date.now() - 8 * 24 * 60 * 60 * 1000).toISOString(); + const report = await xaiOauthUsageProvider.fetchUsage( + { provider: "xai-oauth", credential: makeCredential() }, + { + fetch: capturingFetch({ + config: { + currentPeriod: { + end: periodEnd, + start: periodStart, + type: "USAGE_PERIOD_TYPE_WEEKLY", + }, + }, + }).fetch, + }, + ); + + expect(report).toBeNull(); + }); it("reports zero usage when weekly period is active but creditUsagePercent is omitted (fresh reset)", async () => { const periodEnd = new Date(Date.now() + 6 * 24 * 60 * 60 * 1000).toISOString();