diff --git a/ui/litellm-dashboard/src/components/Issues/IssueFamilySettings.tsx b/ui/litellm-dashboard/src/components/Issues/IssueFamilySettings.tsx
index 619257fc517..50a720dd9f7 100644
--- a/ui/litellm-dashboard/src/components/Issues/IssueFamilySettings.tsx
+++ b/ui/litellm-dashboard/src/components/Issues/IssueFamilySettings.tsx
@@ -224,8 +224,8 @@ export default function IssueFamilySettings({ accessToken }: { accessToken: stri
) : (
<>
- Daily monitoring is enabled by default. Checks wait for a usable baseline and complete usage data. Model
- retirement alerts appear automatically for used models.
+ Daily checks wait for a usable baseline and complete usage data. Model retirement alerts appear
+ automatically for used models.
{delayedChecks > 0 && (
diff --git a/ui/litellm-dashboard/src/components/Issues/Issues.integration.test.tsx b/ui/litellm-dashboard/src/components/Issues/Issues.integration.test.tsx
index 8d3f1f54c18..080144df681 100644
--- a/ui/litellm-dashboard/src/components/Issues/Issues.integration.test.tsx
+++ b/ui/litellm-dashboard/src/components/Issues/Issues.integration.test.tsx
@@ -282,8 +282,8 @@ describe("unified issue investigations", () => {
).toBe("0");
});
- it("keeps old performance list links usable", async () => {
- renderWithProviders( , { searchParams: "type=usage&usage_status=resolved" });
+ it("uses the same kind and status filters in the URL and API", async () => {
+ renderWithProviders( , { searchParams: "kind=performance&status=resolved" });
await screen.findByRole("link", { name: "Spend on Checkout key rose to 20× normal" });
const request = calls.find((call) => call.path === "/alerts");
expect(request?.query.get("kind")).toBe("performance");
@@ -555,7 +555,7 @@ describe("unified issue investigations", () => {
);
expect(screen.getByRole("link", { name: "Migration details" })).toHaveAttribute(
"href",
- "/ui/alerts?type=model-deprecations&model=provider%2Fretiring-model",
+ "/ui/alerts?kind=model_deprecation&model=provider%2Fretiring-model",
);
expect(screen.getByRole("link", { name: "View model activity" })).toHaveAttribute(
"href",
diff --git a/ui/litellm-dashboard/src/components/Issues/IssuesInbox.tsx b/ui/litellm-dashboard/src/components/Issues/IssuesInbox.tsx
index a7a39e0ffb3..509bf78f354 100644
--- a/ui/litellm-dashboard/src/components/Issues/IssuesInbox.tsx
+++ b/ui/litellm-dashboard/src/components/Issues/IssuesInbox.tsx
@@ -54,9 +54,9 @@ export default function IssuesInbox() {
const { accessToken, userRole, isViewOnly } = useAuthorized();
const [params, setParams] = useQueryStates(issueRouteParsers);
const table = useUrlTableState(TABLE_STATE);
- const status = params.status ?? params.state ?? params.usage_status ?? "open";
- const family = params.family ?? (params.type === "model-deprecations" ? "retirement" : undefined);
- const kind = params.type === "usage" && !family ? ("performance" as const) : undefined;
+ const status = params.status ?? "open";
+ const family = params.family ?? undefined;
+ const kind = family ? undefined : params.kind ?? undefined;
const queryOptions = {
status,
family,
@@ -79,13 +79,13 @@ export default function IssuesInbox() {
} else if (query.data && pageIndex > lastPage) onPaginationChange({ pageIndex: lastPage, pageSize });
}, [query.data, pageIndex, pageSize, lastPage, onPaginationChange]);
const changeStatus = (next: IssueStatus) => {
- void setParams({ status: next, state: null, usage_status: null });
+ void setParams({ status: next });
table.onPaginationChange({ ...table.pagination, pageIndex: 0 });
};
const changeFamily = (next: string) => {
void setParams({
family: next === "all" || next === "performance" ? null : (next as AlertFamily),
- type: next === "performance" ? "usage" : null,
+ kind: next === "performance" ? "performance" : null,
});
table.onPaginationChange({ ...table.pagination, pageIndex: 0 });
};
@@ -118,12 +118,12 @@ export default function IssuesInbox() {
changeFamily(event.target.value)}
className="h-8 rounded-md border border-input bg-background px-2 text-xs"
>
All alert types
- {kind && All performance types }
+ All performance types
{ISSUE_FAMILIES.map((value) => (
{FAMILY_LABELS[value]}
diff --git a/ui/litellm-dashboard/src/components/Issues/issueRoute.ts b/ui/litellm-dashboard/src/components/Issues/issueRoute.ts
index 7211ec4ca10..fe7b529ee1e 100644
--- a/ui/litellm-dashboard/src/components/Issues/issueRoute.ts
+++ b/ui/litellm-dashboard/src/components/Issues/issueRoute.ts
@@ -5,8 +5,6 @@ export const issueRouteParsers = {
alert: parseAsString.withOptions({ history: "push" }),
family: parseAsStringLiteral(ISSUE_FAMILIES),
status: parseAsStringLiteral(ISSUE_STATUSES),
- type: parseAsStringLiteral(["usage", "model-deprecations"] as const),
+ kind: parseAsStringLiteral(["performance", "model_deprecation"] as const),
model: parseAsString,
- state: parseAsStringLiteral(ISSUE_STATUSES),
- usage_status: parseAsStringLiteral(ISSUE_STATUSES),
};
diff --git a/ui/litellm-dashboard/src/components/ModelDeprecationAlerts/migrationRoute.ts b/ui/litellm-dashboard/src/components/ModelDeprecationAlerts/migrationRoute.ts
index 4581f8042f4..6f8787af09b 100644
--- a/ui/litellm-dashboard/src/components/ModelDeprecationAlerts/migrationRoute.ts
+++ b/ui/litellm-dashboard/src/components/ModelDeprecationAlerts/migrationRoute.ts
@@ -9,6 +9,6 @@ export const migrationUrlParsers = {
};
export function migrationHref(model?: string) {
- const base = `${uiHref("alerts")}?type=model-deprecations`;
+ const base = `${uiHref("alerts")}?kind=model_deprecation`;
return model ? `${base}&model=${encodeURIComponent(model)}` : base;
}
diff --git a/ui/litellm-dashboard/src/components/Navbar/NotificationsBell/NotificationsBell.test.tsx b/ui/litellm-dashboard/src/components/Navbar/NotificationsBell/NotificationsBell.test.tsx
index b032a317765..c8b3143e9b8 100644
--- a/ui/litellm-dashboard/src/components/Navbar/NotificationsBell/NotificationsBell.test.tsx
+++ b/ui/litellm-dashboard/src/components/Navbar/NotificationsBell/NotificationsBell.test.tsx
@@ -210,6 +210,17 @@ describe("issue notifications", () => {
expect(screen.getByLabelText("Notification content")).toContainElement(update);
});
+ it("lets the reader retry a failed alerts request", async () => {
+ const user = userEvent.setup();
+ const retry = vi.fn();
+ renderWithProviders(
+ ,
+ );
+ await user.click(screen.getByRole("button", { name: /^notifications/i }));
+ await user.click(screen.getByRole("button", { name: "Retry" }));
+ expect(retry).toHaveBeenCalledTimes(1);
+ });
+
it("opens issue-owned investigations and keeps resources outside the scrolling content", async () => {
const user = userEvent.setup();
renderWithProviders( );