Skip to content

Commit af18005

Browse files
committed
fix: remap primary_window to weekly instead of dropping it
The upstream WHAM API and x-codex-primary headers still carry quota data through primary_window, but it now represents the weekly limit (was 5h). Prefer primary over secondary for weekly, with secondary as fallback.
1 parent 8088ff5 commit af18005

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

src/codex/quota.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,15 @@ export function parseUsageQuota(data: WhamUsageResponse): Omit<StoredAccountQuot
110110

111111
const quota: Omit<StoredAccountQuota, "updatedAt"> = {};
112112
const thirtyDayOnly = data.plan_type?.trim().toLowerCase() === "go" || data.plan_type?.trim().toLowerCase() === "free";
113-
const weeklyPercent = normalizeUsagePercent(data.rate_limit.secondary_window?.used_percent);
113+
// primary_window was the 5h window; it now carries weekly data for GPT plans.
114+
// secondary_window is the legacy weekly source; prefer primary when present.
115+
const primaryPercent = normalizeUsagePercent(data.rate_limit.primary_window?.used_percent);
116+
const secondaryPercent = normalizeUsagePercent(data.rate_limit.secondary_window?.used_percent);
117+
const weeklyPercent = primaryPercent ?? secondaryPercent;
114118
const monthlyPercent = normalizeUsagePercent(data.rate_limit.tertiary_window?.used_percent);
115-
const weeklyResetAt = normalizeResetAt(data.rate_limit.secondary_window?.reset_at);
119+
const primaryResetAt = normalizeResetAt(data.rate_limit.primary_window?.reset_at);
120+
const secondaryResetAt = normalizeResetAt(data.rate_limit.secondary_window?.reset_at);
121+
const weeklyResetAt = primaryPercent !== undefined ? primaryResetAt : secondaryResetAt;
116122
const monthlyResetAt = normalizeResetAt(data.rate_limit.tertiary_window?.reset_at);
117123
if (thirtyDayOnly) {
118124
if (monthlyPercent !== undefined) {

src/server/responses.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -735,10 +735,16 @@ export async function handleResponses(
735735
const terminalRecorder = codexForwardTerminalOutcomeRecorder(config, authCtx, route.provider);
736736
const terminalBodyWillRecord = !!terminalRecorder && upstreamResponse.ok && isEventStream;
737737
// Capture quota from upstream response for multi-account tracking
738-
if (usesCodexForwardPoolAuth(authCtx, route.provider)) {
739-
const weeklyRaw = upstreamResponse.headers.get("x-codex-secondary-used-percent");
738+
if (usesCodexForwardPoolAuth(authCtx, route.provider)) {
739+
// primary was the 5h window; it now carries weekly data for GPT plans.
740+
// Prefer primary when present, fall back to secondary for compatibility.
741+
const primaryRaw = upstreamResponse.headers.get("x-codex-primary-used-percent");
742+
const secondaryRaw = upstreamResponse.headers.get("x-codex-secondary-used-percent");
743+
const weeklyRaw = primaryRaw ?? secondaryRaw;
740744
const monthlyRaw = upstreamResponse.headers.get("x-codex-tertiary-used-percent");
741-
const weeklyResetRaw = upstreamResponse.headers.get("x-codex-secondary-reset-at");
745+
const primaryResetRaw = upstreamResponse.headers.get("x-codex-primary-reset-at");
746+
const secondaryResetRaw = upstreamResponse.headers.get("x-codex-secondary-reset-at");
747+
const weeklyResetRaw = primaryRaw ? primaryResetRaw : secondaryResetRaw;
742748
const monthlyResetRaw = upstreamResponse.headers.get("x-codex-tertiary-reset-at");
743749
const retryAfterRaw = upstreamResponse.headers.get("retry-after");
744750
if (weeklyRaw || monthlyRaw) {
@@ -758,8 +764,8 @@ export async function handleResponses(
758764
});
759765
} else {
760766
recordCodexUpstreamOutcome(config, authCtx.accountId, upstreamResponse.status, {
761-
retryAfter: retryAfterRaw,
762-
resetAt: [weeklyResetRaw, monthlyResetRaw],
767+
retryAfter: retryAfterRaw,
768+
resetAt: [primaryResetRaw, secondaryResetRaw, monthlyResetRaw].filter(Boolean),
763769
});
764770
}
765771
}

0 commit comments

Comments
 (0)