Files
OmniRoute/open-sse/services/usage/xaiOauth.ts
Alan Vb da20b96dc0 feat(providers): weekly quota for xAI OAuth (Grok) (#8471)
* feat(providers): weekly quota for xAI OAuth (Grok)

Live weekly credit pool for xai-oauth (alias xao) via the shared
cli-chat-proxy billing API (creditUsagePercent), using the connection OAuth access token.

- Export fetchGrokBillingWithToken from grokQuotaFetcher for reuse
- xaiOauthQuotaFetcher: 60s cache, fail-open, preflight + monitor
- Provider Limits allowlist and weekly window

* test(providers): cover xai-oauth usage dispatch + fix changelog

Address PR review:
- fix changelog file & rename to 8471-xai-oauth-weekly-quota.md
- export getXaiOauthUsage via __testing
- add xai-oauth-usage.test.ts

---------

Co-authored-by: allanvb <allanvb@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-26 12:11:02 -03:00

93 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* usage/xaiOauth.ts — xAI OAuth (Grok) weekly quota fetcher.
*
* Extracted from services/usage.ts (god-file decomposition): the xAI OAuth
* variant uses a live billing endpoint (`cli-chat-proxy.grok.com/v1/billing`)
* with the connection's OAuth access token, falling back to OmniRoute's own
* self-tracked token totals when the live quota is unavailable.
*
* `creditUsagePercent` is percent **used** (0100), matching grok.com Usage.
*/
import { type UsageQuota, createQuotaFromUsage } from "./quota.ts";
type JsonRecord = Record<string, unknown>;
type UsageProviderConnection = JsonRecord & {
id?: string;
provider?: string;
accessToken?: string;
apiKey?: string;
providerSpecificData?: JsonRecord;
projectId?: string;
email?: string;
};
/**
* Weekly quota for xAI OAuth (Grok) — live credit pool.
*
* Same billing endpoint as grok-web / Grok CLI usage
* (`cli-chat-proxy.grok.com/v1/billing?format=credits`) using the connection
* OAuth access token (not ~/.grok/auth.json).
* `creditUsagePercent` is percent **used** (0100), matching grok.com Usage.
*/
export async function getXaiOauthUsage(
connectionId: string,
accessToken?: string,
connection?: UsageProviderConnection
) {
if (!connectionId) {
return { message: "xAI OAuth: connection id unavailable." };
}
try {
const { fetchXaiOauthQuota } = await import("../xaiOauthQuotaFetcher.ts");
const live = await fetchXaiOauthQuota(connectionId, {
...(connection || {}),
accessToken: accessToken || connection?.accessToken,
credentials: {
accessToken: accessToken || connection?.accessToken,
},
} as Record<string, unknown>);
if (live && typeof live.percentUsed === "number") {
// QuotaInfo.percentUsed is a 01 fraction used
const usedPct = Math.round(Math.min(100, Math.max(0, live.percentUsed * 100)));
return {
plan: "xAI OAuth (Grok) · Weekly",
quotas: {
weekly: createQuotaFromUsage(usedPct, 100, live.resetAt ?? null),
},
};
}
} catch (error) {
console.warn(
"[usage] xai-oauth live quota failed, falling back to self-track:",
(error as Error)?.message || error
);
}
try {
const { getMonthlyProviderTokensForConnection } = await import("@/lib/usage/usageStats");
const used =
getMonthlyProviderTokensForConnection("xai-oauth", connectionId) ||
getMonthlyProviderTokensForConnection("xao", connectionId) ||
0;
return {
plan: "xAI OAuth (Grok) · OmniRoute-tracked",
message: "Live weekly quota unavailable; showing OmniRoute-routed token totals only.",
quotas: {
monthly: {
used,
total: 0,
remaining: 100,
remainingPercentage: 100,
resetAt: null,
unlimited: true,
} as UsageQuota,
},
};
} catch (error) {
return { message: `xAI OAuth usage error: ${(error as Error).message}` };
}
}