fix(ui): stop parsing formatted dates and spend back into values (#50350)

* fix(ui): stop parsing formatted dates and spend back into values

Regenerating a key stored its new created_at as locale text and parsed it
back for display, which shows "Invalid Date" on browsers whose date format
JavaScript cannot parse. It now stores an ISO timestamp.

The model health table stored check times as locale text and sorted by
parsing that text, which misorders or drops rows outside US English. It now
keeps the raw timestamp and formats it in the table cell, so the shown text
is unchanged.

getSpendString decided whether spend rounds to zero by stripping commas from
its own formatted output. It now compares the number against half of the
smallest shown unit, which gives the same output for every value and no
longer depends on how the digits are rendered.

* fix(ui): keep getSpendString exact at high precision

0.5 / 10 ** decimals drifts by one ulp once 10 ** decimals is no longer exact
(past 22 decimals), so a value right at the threshold could flip from "< $..."
to a row of zeros. Parsing 5e-(decimals + 1) gives the correctly rounded
threshold for every precision.
This commit is contained in:
yuneng-jiang 2026-11-06 12:20:02 -08:00 • committed by GitHub
parent de0b389205
commit 0057804dca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 250 additions and 34 deletions

View file

@ -3,7 +3,7 @@ import type { PaginationState } from "@tanstack/react-table";
import { act, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { useState } from "react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import HealthCheckComponent from "./HealthCheckComponent";
@ -65,6 +65,28 @@ const renderHealthCheck = async (props: HarnessProps) => {
});
};
const numericDateTime: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
};
const germanDateTime = new Intl.DateTimeFormat("de-DE", numericDateTime);
const germanLocaleString = function (this: Date): string {
return germanDateTime.format(this);
};
const rowIds = (): string[] =>
screen
.getAllByRole("row")
.slice(1)
.map((row) => row.querySelector('[data-testid^="datatable-select-row-"]'))
.filter((node): node is Element => node !== null)
.map((node) => (node.getAttribute("data-testid") ?? "").replace("datatable-select-row-", ""));
describe("HealthCheckComponent", () => {
beforeEach(() => {
vi.clearAllMocks();
@ -251,5 +273,90 @@ describe("HealthCheckComponent", () => {
expect(screen.queryByText("healthy")).not.toBeInTheDocument();
expect(screen.getByText("none")).toBeInTheDocument();
});
it("does not count a failed stored check as the last success", async () => {
const checkedAt = "2024-01-15T10:05:00Z";
mockLatestHealthChecksCall.mockResolvedValue({
latest_health_checks: {
"id-alpha": { status: "unhealthy", checked_at: checkedAt, error_message: "Connection failed" },
},
});
await renderHealthCheck({ modelData: { data: [makeModel("id-alpha")] }, allModelsOnProxy: ["id-alpha"] });
expect(screen.getAllByText(new Date(checkedAt).toLocaleString())).toHaveLength(1);
});
});
describe("check times on a German-locale browser", () => {
const twoModels = { data: [makeModel("id-alpha", "alpha"), makeModel("id-beta", "beta")] };
const bothIds = ["id-alpha", "id-beta"];
const isoLikeLocaleString = vi.mocked(Date.prototype.toLocaleString).getMockImplementation();
beforeEach(() => {
vi.mocked(Date.prototype.toLocaleString).mockImplementation(germanLocaleString);
});
afterEach(() => {
vi.useRealTimers();
if (isoLikeLocaleString) {
vi.mocked(Date.prototype.toLocaleString).mockImplementation(isoLikeLocaleString);
}
});
it("sorts stored checks most-recent-first and shows them in the browser's format", async () => {
const march = "2024-03-02T10:00:00Z";
const june = "2024-06-01T10:00:00Z";
mockLatestHealthChecksCall.mockResolvedValue({
latest_health_checks: {
"id-alpha": { status: "healthy", checked_at: march, error_message: null },
"id-beta": { status: "healthy", checked_at: june, error_message: null },
},
});
await renderHealthCheck({ modelData: twoModels, allModelsOnProxy: bothIds, rowCount: 2 });
const user = userEvent.setup();
expect(await screen.findAllByText(germanLocaleString.call(new Date(june)))).toHaveLength(2);
await user.click(screen.getByTestId("sort-header-last_check"));
expect(rowIds()).toEqual(["id-beta", "id-alpha"]);
});
const runBetaAlone = {
"a single-model check": async (user: ReturnType<typeof userEvent.setup>) => {
await user.click(screen.getAllByTestId("run-health-check-btn")[1]);
},
"a bulk run of the selected model": async (user: ReturnType<typeof userEvent.setup>) => {
await user.click(screen.getByTestId("datatable-select-row-id-beta"));
await user.click(screen.getByTestId("run-health-checks"));
},
};
describe.each(Object.entries(runBetaAlone))("after %s", (_trigger, runCheck) => {
it.each([
["succeeds", () => mockIndividualModelHealthCheckCall.mockResolvedValue({ unhealthy_count: 0 })],
["fails", () => mockIndividualModelHealthCheckCall.mockRejectedValue(new Error("upstream down"))],
])("that %s, sorts the fresh check above an older stored one", async (_outcome, arrangeCheck) => {
const now = new Date("2026-01-20T12:00:00Z");
vi.useFakeTimers({ toFake: ["Date"] });
vi.setSystemTime(now);
arrangeCheck();
mockLatestHealthChecksCall.mockResolvedValue({
latest_health_checks: {
"id-alpha": { status: "healthy", checked_at: "2024-06-01T10:00:00Z", error_message: null },
},
});
await renderHealthCheck({ modelData: twoModels, allModelsOnProxy: bothIds, rowCount: 2 });
const user = userEvent.setup();
await runCheck(user);
expect((await screen.findAllByText(germanLocaleString.call(now))).length).toBeGreaterThan(0);
await user.click(screen.getByTestId("sort-header-last_check"));
expect(rowIds()).toEqual(["id-beta", "id-alpha"]);
});
});
});
});

View file

@ -131,19 +131,10 @@ const extractMeaningfulError = (error: unknown, t: TFunction = i18n.t.bind(i18n)
return truncate(cleaned);
};
const toCheckedAtLabel = (checkedAt: string | null | undefined, fallback: string): string => {
if (!checkedAt) {
return fallback;
}
return new Date(checkedAt).toLocaleString();
};
const checkedAtOr = (checkedAt: string | null | undefined, fallback: string): string => checkedAt || fallback;
const toLastSuccessLabel = (checkData: LatestHealthCheck, fallback: string): string => {
if (checkData.status !== "healthy") {
return fallback;
}
return toCheckedAtLabel(checkData.checked_at, fallback);
};
const lastSuccessAtOr = (checkData: LatestHealthCheck, fallback: string): string =>
checkData.status === "healthy" ? checkedAtOr(checkData.checked_at, fallback) : fallback;
interface HealthCheckComponentProps {
accessToken: string | null;
@ -229,8 +220,8 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
healthStatusMap[modelId] = {
status: checkData.status || "unknown",
lastCheck: toCheckedAtLabel(checkData.checked_at, "None"),
lastSuccess: toLastSuccessLabel(checkData, "None"),
lastCheck: checkedAtOr(checkData.checked_at, "None"),
lastSuccess: lastSuccessAtOr(checkData, "None"),
loading: false,
error: fullError ? extractMeaningfulError(fullError) : undefined,
fullError: fullError,
@ -263,7 +254,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
try {
const response = await individualModelHealthCheckCall(accessToken, modelId);
const currentTime = new Date().toLocaleString();
const currentTime = new Date().toISOString();
if (response.unhealthy_count > 0 && response.unhealthy_endpoints && response.unhealthy_endpoints.length > 0) {
const rawError =
@ -303,8 +294,8 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
...prev,
[modelId]: {
status: checkData.status || prev[modelId]?.status || "unknown",
lastCheck: toCheckedAtLabel(checkData.checked_at, prev[modelId]?.lastCheck || "None"),
lastSuccess: toLastSuccessLabel(checkData, prev[modelId]?.lastSuccess || "None"),
lastCheck: checkedAtOr(checkData.checked_at, prev[modelId]?.lastCheck || "None"),
lastSuccess: lastSuccessAtOr(checkData, prev[modelId]?.lastSuccess || "None"),
loading: false,
error: fullError ? extractMeaningfulError(fullError) : prev[modelId]?.error,
fullError: fullError || prev[modelId]?.fullError,
@ -314,7 +305,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
}
} catch (dbError) {}
} catch (error) {
const currentTime = new Date().toLocaleString();
const currentTime = new Date().toISOString();
const rawError = error instanceof Error ? error.message : String(error);
const errorMessage = extractMeaningfulError(rawError);
setModelHealthStatuses((prev) => ({
@ -361,7 +352,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
try {
const response = await individualModelHealthCheckCall(accessToken, modelId);
const currentTime = new Date().toLocaleString();
const currentTime = new Date().toISOString();
if (response.unhealthy_count > 0 && response.unhealthy_endpoints && response.unhealthy_endpoints.length > 0) {
const rawError =
response.unhealthy_endpoints[0]?.error || t("modelDashboard.healthCheckComponent.healthCheckFailed");
@ -391,7 +382,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
}
} catch (error) {
console.error(`Health check failed for model id ${modelId}:`, error);
const currentTime = new Date().toLocaleString();
const currentTime = new Date().toISOString();
const rawError = error instanceof Error ? error.message : String(error);
const errorMessage = extractMeaningfulError(rawError, t);
setModelHealthStatuses((prev) => ({
@ -426,8 +417,8 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
...prev,
[modelId]: {
status: checkData.status || currentStatus?.status || "unknown",
lastCheck: toCheckedAtLabel(checkData.checked_at, currentStatus?.lastCheck || "None"),
lastSuccess: toLastSuccessLabel(checkData, currentStatus?.lastSuccess || "None"),
lastCheck: checkedAtOr(checkData.checked_at, currentStatus?.lastCheck || "None"),
lastSuccess: lastSuccessAtOr(checkData, currentStatus?.lastSuccess || "None"),
loading: false,
error: fullError ? extractMeaningfulError(fullError, t) : currentStatus?.error,
fullError: fullError || currentStatus?.fullError,

View file

@ -60,6 +60,11 @@ const SENTINEL_LABEL_KEYS: Readonly<Record<string, ParseKeys>> = {
const sentinelLabel = (value: string, t: TFunction): string =>
Object.hasOwn(SENTINEL_LABEL_KEYS, value) ? t(SENTINEL_LABEL_KEYS[value]) : value;
const checkTimeLabel = (value: string, t: TFunction): string => {
const checkedAt = new Date(value);
return Number.isNaN(checkedAt.getTime()) ? sentinelLabel(value, t) : checkedAt.toLocaleString();
};
function HealthStatusBadge({ status }: { status: string }) {
const tone = HEALTH_STATUS_TONES[status];
if (!tone) {
@ -427,7 +432,7 @@ export const getHealthChecksTableColumns = (
<span className="text-sm text-muted-foreground">
{row.original.health_loading
? t("modelDashboard.healthChecksTableColumns.sentinels.checkInProgress")
: sentinelLabel(row.original.last_check, t)}
: checkTimeLabel(row.original.last_check, t)}
</span>
),
},
@ -453,7 +458,7 @@ export const getHealthChecksTableColumns = (
cell: ({ row }) => {
const modelId = row.original.model_info?.id ?? "";
const lastSuccess = modelHealthStatuses[modelId]?.lastSuccess || NONE;
return <span className="text-sm text-muted-foreground">{sentinelLabel(lastSuccess, t)}</span>;
return <span className="text-sm text-muted-foreground">{checkTimeLabel(lastSuccess, t)}</span>;
},
},
{

View file

@ -3,9 +3,9 @@ import useTeams from "@/app/(dashboard)/hooks/useTeams";
import { renderWithProviders } from "../../../tests/test-utils";
import { screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { KeyResponse, Team } from "../key_team_helpers/key_list";
import { keyDeleteCall, keyUpdateCall, teamInfoCall } from "../networking";
import { keyDeleteCall, keyUpdateCall, regenerateKeyCall, teamInfoCall } from "../networking";
import { QueryClient } from "@tanstack/react-query";
import KeyInfoView, { needsLifetimeSpendBackfill } from "./key_info_view";
@ -92,6 +92,7 @@ vi.mock("../networking", () => ({
serverRootPath: "",
keyDeleteCall: vi.fn().mockResolvedValue({}),
keyUpdateCall: vi.fn().mockResolvedValue({}),
regenerateKeyCall: vi.fn().mockResolvedValue({ key: "sk-regenerated", token: "regenerated-token" }),
teamInfoCall: vi.fn(),
getPolicyInfoWithGuardrails: vi.fn().mockResolvedValue({
resolved_guardrails: ["guardrail-1", "guardrail-2"],
@ -1481,4 +1482,86 @@ describe("KeyInfoView", () => {
invalidateSpy.mockRestore();
});
});
describe("regenerate on a German-locale browser", () => {
const isoLikeLocaleString = vi.mocked(Date.prototype.toLocaleString).getMockImplementation();
const numericDateTime: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
};
const germanDateTime = new Intl.DateTimeFormat("de-DE", numericDateTime);
beforeEach(() => {
vi.useFakeTimers({ toFake: ["Date"] });
vi.setSystemTime(new Date("2026-01-20T12:00:00Z"));
vi.mocked(Date.prototype.toLocaleString).mockImplementation(function (this: Date) {
return germanDateTime.format(this);
});
});
afterEach(() => {
vi.useRealTimers();
if (isoLikeLocaleString) {
vi.mocked(Date.prototype.toLocaleString).mockImplementation(isoLikeLocaleString);
}
});
it("shows the regeneration time as the key's created time", async () => {
vi.mocked(useAuthorized).mockReturnValue({
...baseUseAuthorizedMock,
userId: "proxy-admin-user",
userRole: "proxy_admin",
});
renderWithProviders(
<KeyInfoView
keyData={MOCK_KEY_DATA}
onClose={() => {}}
keyId="test-key-id"
onKeyDataUpdate={() => {}}
teams={[]}
/>,
);
await userEvent.click(await screen.findByRole("button", { name: "Regenerate Key" }));
await userEvent.click(await screen.findByRole("button", { name: "Regenerate" }));
await waitFor(() => expect(regenerateKeyCall).toHaveBeenCalled());
await userEvent.keyboard("{Escape}");
await userEvent.click(screen.getByRole("tab", { name: "Settings" }));
const lastRegenerated = within(screen.getByText("Last Regenerated").parentElement!).getByText(/ at /);
expect(lastRegenerated).toHaveTextContent("2026");
expect(screen.getByText("Created").nextElementSibling).toHaveTextContent(lastRegenerated.textContent!);
});
it("hands the parent the regeneration time as an ISO timestamp", async () => {
vi.mocked(useAuthorized).mockReturnValue({
...baseUseAuthorizedMock,
userId: "proxy-admin-user",
userRole: "proxy_admin",
});
const onKeyDataUpdate = vi.fn();
renderWithProviders(
<KeyInfoView
keyData={MOCK_KEY_DATA}
onClose={() => {}}
keyId="test-key-id"
onKeyDataUpdate={onKeyDataUpdate}
teams={[]}
/>,
);
await userEvent.click(await screen.findByRole("button", { name: "Regenerate Key" }));
await userEvent.click(await screen.findByRole("button", { name: "Regenerate" }));
await waitFor(() => expect(regenerateKeyCall).toHaveBeenCalled());
await userEvent.keyboard("{Escape}");
expect(onKeyDataUpdate).toHaveBeenCalledWith(
expect.objectContaining({ token: "regenerated-token", created_at: "2026-01-20T12:00:00.000Z" }),
);
});
});
});

View file

@ -452,7 +452,7 @@ export default function KeyInfoView({
...prevData,
...updatedKeyData, // This should include the new token (key-id)
// Update the created_at to show when it was regenerated
created_at: regeneratedAt.toLocaleString(),
created_at: regeneratedAt.toISOString(),
};
return newData;
});
@ -463,7 +463,7 @@ export default function KeyInfoView({
setKeyDataUpdateHeldUntilModalClose({
...updatedKeyData,
created_at: regeneratedAt.toLocaleString(),
created_at: regeneratedAt.toISOString(),
});
};

View file

@ -14,6 +14,14 @@ import {
import { toast } from "@/lib/toast";
const mockToast = vi.mocked(toast);
const arabicDigitsLocaleString = function (
this: number,
_locales?: Intl.LocalesArgument,
options?: Intl.NumberFormatOptions,
): string {
return new Intl.NumberFormat("ar-EG", options).format(this);
};
describe("dataUtils", () => {
beforeEach(() => {
vi.clearAllMocks();
@ -118,6 +126,30 @@ describe("dataUtils", () => {
expect(getSpendString(0.01234, 3)).toBe("$0.012");
expect(getSpendString(999.9999, 1)).toBe("$1,000.0");
});
it("rounds a spend of exactly half the smallest unit up instead of reporting it below the threshold", () => {
expect(getSpendString(0.0000005, 6)).toBe("$0.000001");
expect(getSpendString(-0.0000005, 6)).toBe("$-0.000001");
});
it("reports spend just under half the smallest unit as below the threshold", () => {
expect(getSpendString(0.00000045, 6)).toBe("< $0.000001");
expect(getSpendString(4.9999999999999996e-26, 25)).toBe("< $0.0000000000000000000000001");
});
describe("when numbers render with non-Latin digits", () => {
beforeEach(() => {
vi.spyOn(Number.prototype, "toLocaleString").mockImplementation(arabicDigitsLocaleString);
});
afterEach(() => {
vi.mocked(Number.prototype.toLocaleString).mockRestore();
});
it("still reports spend that rounds to zero as below the threshold", () => {
expect(getSpendString(0.0000004, 6)).toBe("< $0.000001");
});
});
});
describe("formatPerSecondCost", () => {

View file

@ -53,15 +53,13 @@ export const getSpendString = (value: number | null | undefined, decimals: numbe
return "-";
}
const formatted = formatNumberWithCommas(value, decimals, false, false);
const numericFormatted = Number(formatted.replace(/,/g, ""));
if (numericFormatted === 0) {
const halfSmallestUnit = Number(`5e-${decimals + 1}`);
if (Math.abs(value) < halfSmallestUnit) {
const threshold = (1 / 10 ** decimals).toFixed(decimals);
return `< $${threshold}`;
}
return `$${formatted}`;
return `$${formatNumberWithCommas(value, decimals, false, false)}`;
};
export const formatPerSecondCost = (cost: number): string =>