fix(dashboard): show Codex weekly usage

This commit is contained in:
gsxdsm
2026-07-21 00:33:57 -07:00
parent 3c22c133e7
commit b1fa2c77d8
3 changed files with 73 additions and 3 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Show Codex weekly usage when OpenAI reports it as the primary quota window.
category: fix
dev: Classifies Codex quota windows by their declared duration while preserving legacy response support.

View File

@@ -2570,6 +2570,7 @@ describe("usage", () => {
expect(codex.email).toBe("test@example.com"); expect(codex.email).toBe("test@example.com");
expect(codex.plan).toBe("Pro"); expect(codex.plan).toBe("Pro");
expect(codex.windows).toHaveLength(2); expect(codex.windows).toHaveLength(2);
expect(codex.windows.map((window) => window.label)).toEqual(["Session (5h)", "Weekly"]);
const sessionWindow = codex.windows.find((w) => w.label.includes("Session")); const sessionWindow = codex.windows.find((w) => w.label.includes("Session"));
expect(sessionWindow).toBeDefined(); expect(sessionWindow).toBeDefined();
@@ -2577,6 +2578,56 @@ describe("usage", () => {
expect(sessionWindow!.percentLeft).toBe(32.5); expect(sessionWindow!.percentLeft).toBe(32.5);
}); });
it("labels a seven-day primary window as Weekly when no secondary window is returned", async () => {
const mockResponse = {
rate_limit: {
primary_window: {
used_percent: 67,
limit_window_seconds: 7 * 24 * 60 * 60,
reset_after_seconds: 4 * 24 * 60 * 60,
},
secondary_window: null,
},
};
mockReadFile.mockImplementation((filePath: string) => {
if (filePath.includes("codex")) {
return JSON.stringify({
tokens: {
access_token: "test-token",
},
});
}
return Promise.reject(new Error("File not found"));
});
const mockReq = { on: vi.fn(), write: vi.fn(), end: vi.fn() };
mockRequest.mockImplementation((_options: any, callback: any) => {
const mockRes = {
statusCode: 200,
headers: {},
on: vi.fn((event: string, handler: any) => {
if (event === "data") handler(Buffer.from(JSON.stringify(mockResponse)));
if (event === "end") handler();
}),
};
callback(mockRes);
return mockReq;
});
const providers = await fetchAllProviderUsage();
const codex = providers.find((provider) => provider.name === "Codex")!;
expect(codex.status).toBe("ok");
expect(codex.windows).toHaveLength(1);
expect(codex.windows[0]).toMatchObject({
label: "Weekly",
percentUsed: 67,
windowDurationMs: 7 * 24 * 60 * 60 * 1000,
});
expect(codex.windows.some((window) => window.label === "Session (5h)")).toBe(false);
});
it("sets resetAt from reset_at timestamp", async () => { it("sets resetAt from reset_at timestamp", async () => {
const resetAtTimestamp = Math.floor(Date.now() / 1000) + 2 * 60 * 60; // 2 hours from now in seconds const resetAtTimestamp = Math.floor(Date.now() / 1000) + 2 * 60 * 60; // 2 hours from now in seconds
const mockResponse = { const mockResponse = {

View File

@@ -1320,10 +1320,22 @@ async function fetchCodexUsage(): Promise<ProviderUsage> {
}; };
}; };
// Main rate limits const getWindowLabel = (win: unknown, fallbackLabel: string): string => {
if (!win || typeof win !== "object") return fallbackLabel;
const durationSeconds = (win as { limit_window_seconds?: unknown }).limit_window_seconds;
if (durationSeconds === 7 * 24 * 60 * 60) return "Weekly";
if (durationSeconds === 5 * 60 * 60) return "Session (5h)";
return fallbackLabel;
};
// Codex has used both positional shapes: primary=session + secondary=weekly,
// and primary=weekly with no secondary. Prefer the declared duration so the
// same quota keeps its meaning across both API responses.
if (data.rate_limit) { if (data.rate_limit) {
const primary = parseWindow(data.rate_limit.primary_window, "Session (5h)"); const primaryWindow = data.rate_limit.primary_window;
const secondary = parseWindow(data.rate_limit.secondary_window, "Weekly"); const secondaryWindow = data.rate_limit.secondary_window;
const primary = parseWindow(primaryWindow, getWindowLabel(primaryWindow, "Session (5h)"));
const secondary = parseWindow(secondaryWindow, getWindowLabel(secondaryWindow, "Weekly"));
if (primary) usage.windows.push(primary); if (primary) usage.windows.push(primary);
if (secondary) usage.windows.push(secondary); if (secondary) usage.windows.push(secondary);
} }