Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions gui/src/components/QuotaBars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,8 @@ function StackedQuotaRow({ row, threshold, t, locale, incomplete }: {
}

function formatResetAt(resetAt: number | undefined, t: TFn, locale: Locale): { day: string; time: string } {
if (typeof resetAt !== "number" || !Number.isFinite(resetAt)) return { day: "", time: "" };
const ms = resetAt < 10_000_000_000 ? resetAt * 1000 : resetAt;
const date = new Date(ms);
const date = resetAtDate(resetAt);
if (!date) return { day: "", time: "" };
const now = new Date();
const tag = bcp47(locale);
const time = new Intl.DateTimeFormat(tag, { hour: "2-digit", minute: "2-digit", hour12: false }).format(date);
Expand All @@ -362,9 +361,9 @@ export function formatResetFuture(
locale: Locale = "en",
now = Date.now(),
): string {
if (typeof resetAt !== "number" || !Number.isFinite(resetAt)) return "";
const ms = resetAt < 10_000_000_000 ? resetAt * 1000 : resetAt;
const date = new Date(ms);
const date = resetAtDate(resetAt);
if (!date) return "";
const ms = date.getTime();
const tag = bcp47(locale);
const time = new Intl.DateTimeFormat(tag, { hour: "2-digit", minute: "2-digit", hour12: false }).format(date);
const nowDate = new Date(now);
Expand Down Expand Up @@ -395,3 +394,10 @@ export function formatResetFuture(

return t("quota.resetsAt", { date: dateStr, time, when: `${dateStr}, ${time}` });
}

function resetAtDate(resetAt: number | undefined): Date | null {
if (typeof resetAt !== "number" || !Number.isFinite(resetAt)) return null;
const milliseconds = resetAt < 10_000_000_000 ? resetAt * 1000 : resetAt;
const date = new Date(milliseconds);
return Number.isFinite(date.getTime()) ? date : null;
}
10 changes: 10 additions & 0 deletions gui/tests/intl-formatters.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { describe, expect, test } from "bun:test";
import { formatCreditDate, formatCreditDateTime } from "../src/intl-formatters";
import { formatResetFuture } from "../src/components/QuotaBars";
import type { TFn } from "../src/i18n";

describe("credit date formatting", () => {
test("keeps the compact date format for grant dates", () => {
Expand All @@ -22,3 +24,11 @@ describe("credit date formatting", () => {
expect(formatCreditDateTime("invalid")).toBe("—");
});
});

describe("quota reset formatting", () => {
test("ignores timestamps outside the JavaScript Date range", () => {
const t = ((key: string) => key) as TFn;

expect(formatResetFuture(1e20, t)).toBe("");
});
});
2 changes: 2 additions & 0 deletions src/codex/quota.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ function normalizeResetAt(value: unknown): number | undefined {
? Number(value)
: undefined;
if (typeof numeric !== "number" || !Number.isFinite(numeric) || numeric < 0) return undefined;
const milliseconds = numeric < 10_000_000_000 ? numeric * 1000 : numeric;
if (!Number.isFinite(new Date(milliseconds).getTime())) return undefined;
return numeric;
}

Expand Down
11 changes: 11 additions & 0 deletions tests/rate-limit-reset-credits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ describe("rate-limit reset credits", () => {
expect(quota!.resetCredits).toBeUndefined();
});

it("discards reset timestamps outside the JavaScript Date range", () => {
const quota = parseUsageQuota({
rate_limit: {
primary_window: { used_percent: 10, reset_at: 1e20 },
tertiary_window: { used_percent: 20, reset_at: 1e20 },
},
});

expect(quota).toEqual({ weeklyPercent: 10, monthlyPercent: 20 });
});

it("handles credits-only response (no rate_limit)", () => {
const data: WhamUsageResponse = {
rate_limit_reset_credits: { available_count: 1 },
Expand Down
Loading