From c9e15005b1a394ae9b3df56feabbd4e43163fb68 Mon Sep 17 00:00:00 2001 From: Alejandro Tapia Date: Mon, 16 Feb 2026 12:37:53 -0800 Subject: [PATCH] differentiate solely by model_Id --- .../HealthCheckComponent.test.tsx | 172 +++++++++++++----- .../model_dashboard/HealthCheckComponent.tsx | 28 +-- 2 files changed, 134 insertions(+), 66 deletions(-) diff --git a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx index 84c9f0a0948..48e325baa3d 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.test.tsx @@ -92,56 +92,140 @@ describe("HealthCheckComponent", () => { expect(mockIndividualModelHealthCheckCall).not.toHaveBeenCalledWith("token-123", "gpt-4"); }); - it("should key health status by model id and show status from latest_health_checks by model_id", async () => { - const modelData = { - data: [ - { - model_name: "gpt-4", - model_info: { id: "id-alpha" }, - litellm_model_name: "gpt-4", - }, - { - model_name: "gpt-4", - model_info: { id: "id-beta" }, - litellm_model_name: "gpt-4", - }, - ], - }; + describe("latest_health_checks keyed by model id", () => { + it("should show status from latest_health_checks when keys match model ids", async () => { + const modelData = { + data: [ + { + model_name: "gpt-4", + model_info: { id: "id-alpha" }, + litellm_model_name: "gpt-4", + }, + { + model_name: "gpt-4", + model_info: { id: "id-beta" }, + litellm_model_name: "gpt-4", + }, + ], + }; - mockLatestHealthChecksCall.mockResolvedValue({ - latest_health_checks: { - "id-alpha": { - status: "healthy", - checked_at: "2024-01-15T10:00:00Z", - error_message: null, + mockLatestHealthChecksCall.mockResolvedValue({ + latest_health_checks: { + "id-alpha": { + status: "healthy", + checked_at: "2024-01-15T10:00:00Z", + error_message: null, + }, + "id-beta": { + status: "unhealthy", + checked_at: "2024-01-15T10:05:00Z", + error_message: "Connection failed", + }, }, - "id-beta": { - status: "unhealthy", - checked_at: "2024-01-15T10:05:00Z", - error_message: "Connection failed", - }, - }, + }); + + await act(async () => { + render( + , + ); + }); + await act(async () => { + await new Promise((r) => setTimeout(r, 0)); + }); + + expect(mockLatestHealthChecksCall).toHaveBeenCalledWith("token"); + const healthyBadges = screen.getAllByText("healthy"); + const unhealthyBadges = screen.getAllByText("unhealthy"); + expect(healthyBadges.length).toBeGreaterThanOrEqual(1); + expect(unhealthyBadges.length).toBeGreaterThanOrEqual(1); }); - await act(async () => { - render( - , - ); + it("should skip latest_health_checks entries whose key is not a known model id", async () => { + const modelData = { + data: [ + { + model_name: "gpt-4", + model_info: { id: "current-model-id" }, + litellm_model_name: "gpt-4", + }, + ], + }; + + mockLatestHealthChecksCall.mockResolvedValue({ + latest_health_checks: { + "current-model-id": { + status: "healthy", + checked_at: "2024-01-15T10:00:00Z", + error_message: null, + }, + "deleted-or-unknown-id": { + status: "unhealthy", + checked_at: "2024-01-15T10:05:00Z", + error_message: "Stale entry", + }, + }, + }); + + await act(async () => { + render( + , + ); + }); + await act(async () => { + await new Promise((r) => setTimeout(r, 0)); + }); + + expect(screen.getByText("healthy")).toBeInTheDocument(); + expect(screen.queryByText("unhealthy")).not.toBeInTheDocument(); }); - await act(async () => { - await new Promise((r) => setTimeout(r, 0)); - }); + it("should not apply status when latest_health_checks key is model name not model id", async () => { + const modelData = { + data: [ + { + model_name: "gpt-4", + model_info: { id: "model-id-123" }, + litellm_model_name: "gpt-4", + }, + ], + }; - expect(mockLatestHealthChecksCall).toHaveBeenCalledWith("token"); - const healthyBadges = screen.getAllByText("healthy"); - const unhealthyBadges = screen.getAllByText("unhealthy"); - expect(healthyBadges.length).toBeGreaterThanOrEqual(1); - expect(unhealthyBadges.length).toBeGreaterThanOrEqual(1); + mockLatestHealthChecksCall.mockResolvedValue({ + latest_health_checks: { + "gpt-4": { + status: "healthy", + checked_at: "2024-01-15T10:00:00Z", + error_message: null, + }, + }, + }); + + await act(async () => { + render( + , + ); + }); + await act(async () => { + await new Promise((r) => setTimeout(r, 0)); + }); + + expect(screen.queryByText("healthy")).not.toBeInTheDocument(); + expect(screen.getByText("none")).toBeInTheDocument(); + }); }); }); diff --git a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx index b4bb1019dd6..db71733b5ba 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx @@ -85,31 +85,16 @@ const HealthCheckComponent: React.FC = ({ latestHealthChecks.latest_health_checks && typeof latestHealthChecks.latest_health_checks === "object" ) { - Object.entries(latestHealthChecks.latest_health_checks).forEach(([key, checkData]: [string, any]) => { + Object.entries(latestHealthChecks.latest_health_checks).forEach(([modelId, checkData]: [string, any]) => { if (!checkData) return; - let targetModelId: string | null = null; + // Key is model_id from the backend (guaranteed by DB schema) + const modelExists = modelData.data.some((m: any) => m.model_info?.id === modelId); + if (!modelExists) return; - // The key is model_id from the backend; fallback to matching by model_name for legacy data - const modelByIdMatch = modelData.data.find((m: any) => m.model_info && m.model_info.id === key); - if (modelByIdMatch) { - targetModelId = modelByIdMatch.model_info.id; - } else { - const directModelMatch = modelData.data.find((m: any) => m.model_name === key); - if (directModelMatch?.model_info?.id) { - targetModelId = directModelMatch.model_info.id; - } else if (checkData.model_name) { - const modelByNameInData = modelData.data.find((m: any) => m.model_name === checkData.model_name); - if (modelByNameInData?.model_info?.id) { - targetModelId = modelByNameInData.model_info.id; - } - } - } + const fullError = checkData.error_message || undefined; - if (targetModelId) { - const fullError = checkData.error_message || undefined; - - healthStatusMap[targetModelId] = { + healthStatusMap[modelId] = { status: checkData.status || "unknown", lastCheck: checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : "None", lastSuccess: @@ -123,7 +108,6 @@ const HealthCheckComponent: React.FC = ({ fullError: fullError, successResponse: checkData.status === "healthy" ? checkData : undefined, }; - } }); } } catch (healthError) {