diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.test.tsx
new file mode 100644
index 00000000000..3b2c0a84ea2
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.test.tsx
@@ -0,0 +1,61 @@
+/* @vitest-environment jsdom */
+import { act, render } from "@testing-library/react";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+
+import AllModelsPanel from "./AllModelsPanel";
+
+interface CapturedTabProps {
+ selectedModelGroup: string | null;
+ setSelectedModelGroup: (modelGroup: string) => void;
+}
+
+const captured: { props: CapturedTabProps | null } = { props: null };
+
+vi.mock("@/app/(dashboard)/models-and-endpoints/components/AllModelsTab", () => ({
+ default: (props: CapturedTabProps) => {
+ captured.props = props;
+ return
;
+ },
+}));
+vi.mock("@/app/(dashboard)/models-and-endpoints/components/AllModelsTable", () => ({
+ ALL_MODEL_GROUPS_VALUE: "all",
+}));
+vi.mock("@/app/(dashboard)/models-and-endpoints/useModelDashboardData", () => ({
+ useModelDashboardData: () => ({ availableModelGroups: [], availableModelAccessGroups: [] }),
+}));
+vi.mock("next/navigation", () => ({ useSearchParams: () => new URLSearchParams(window.location.search) }));
+
+describe("AllModelsPanel ?model_group= filter", () => {
+ beforeEach(() => {
+ captured.props = null;
+ window.history.pushState(null, "", "/models-and-endpoints/");
+ });
+
+ it("seeds the model group filter from the URL", () => {
+ window.history.pushState(null, "", "/models-and-endpoints/?model_group=gpt-4o");
+ render();
+ expect(captured.props?.selectedModelGroup).toBe("gpt-4o");
+ });
+
+ it("defaults to no filter when the param is absent", () => {
+ render();
+ expect(captured.props?.selectedModelGroup).toBeNull();
+ });
+
+ it("writes the selected group to the URL via replaceState", () => {
+ render();
+ const spy = vi.spyOn(window.history, "replaceState");
+ act(() => captured.props?.setSelectedModelGroup("claude-opus-5"));
+ expect(spy.mock.calls.at(-1)?.[2]).toContain("model_group=claude-opus-5");
+ spy.mockRestore();
+ });
+
+ it("removes the param when the filter resets to all groups", () => {
+ window.history.pushState(null, "", "/models-and-endpoints/?model_group=gpt-4o");
+ render();
+ const spy = vi.spyOn(window.history, "replaceState");
+ act(() => captured.props?.setSelectedModelGroup("all"));
+ expect(spy.mock.calls.at(-1)?.[2] as string).not.toContain("model_group");
+ spy.mockRestore();
+ });
+});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.tsx
index 9d40ea32185..f6021e92ede 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/panels/AllModelsPanel.tsx
@@ -1,12 +1,25 @@
"use client";
-import { useState } from "react";
+import { useCallback } from "react";
+import { useSearchParams } from "next/navigation";
import AllModelsTab from "@/app/(dashboard)/models-and-endpoints/components/AllModelsTab";
+import { ALL_MODEL_GROUPS_VALUE } from "@/app/(dashboard)/models-and-endpoints/components/AllModelsTable";
import { useModelDashboardData } from "@/app/(dashboard)/models-and-endpoints/useModelDashboardData";
import { useModelDetailRouting } from "@/app/(dashboard)/models-and-endpoints/detailNavigation";
+import { navigateWithParams } from "@/app/(dashboard)/navigateWithParams";
export default function AllModelsPanel() {
- const [selectedModelGroup, setSelectedModelGroup] = useState(null);
+ const searchParams = useSearchParams();
+ const selectedModelGroup = searchParams?.get("model_group") ?? null;
+ const setSelectedModelGroup = useCallback((modelGroup: string) => {
+ navigateWithParams((params) => {
+ if (modelGroup && modelGroup !== ALL_MODEL_GROUPS_VALUE) {
+ params.set("model_group", modelGroup);
+ } else {
+ params.delete("model_group");
+ }
+ }, "replace");
+ }, []);
const { availableModelGroups, availableModelAccessGroups } = useModelDashboardData();
const { openModel, openTeam } = useModelDetailRouting();