diff --git a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py index abaa4f9fe92..0039e1de316 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py @@ -7547,14 +7547,20 @@ class TestTeamMemberAutoRouterWrites: @pytest.mark.asyncio @pytest.mark.parametrize("endpoint", ["patch", "legacy"]) - @pytest.mark.parametrize("change", ["save", "rotate", "move", "move-without-key", "reset", "heuristic"]) - async def test_jev_dashboard_save_preserves_server_transport(self, endpoint: str, change: str) -> None: + @pytest.mark.parametrize("provider", ["typesafe", "bespoke_nimble"]) + @pytest.mark.parametrize("change", ["save", "rotate", "move", "move-without-key", "clear-key", "reset", "heuristic"]) + async def test_jev_dashboard_save_preserves_server_transport( + self, endpoint: str, provider: str, change: str + ) -> None: original: Final = self._row() transport: Final = {"api_key": "synthetic-original-jev-key", "api_base": "https://jev.example.com"} + identity: Final = ( + {"provider": "bespoke_nimble", "model": "nimble-latest"} if provider == "bespoke_nimble" else {} + ) stored_config: Final = { "classifier_type": "jev", "tiers": {"SIMPLE": "allowed"}, - "jev_classifier_config": {**transport, "instructions": "Old instructions", "timeout_ms": 6100}, + "jev_classifier_config": {**identity, **transport, "instructions": "Old instructions", "timeout_ms": 6100}, } row: Final = original.model_copy( update={ @@ -7570,6 +7576,7 @@ class TestTeamMemberAutoRouterWrites: "rotate": {"api_key": "synthetic-replacement-jev-key"}, "move": {"api_base": "https://new-jev.example.com", "api_key": "synthetic-replacement-jev-key"}, "move-without-key": {"api_base": "https://new-jev.example.com"}, + "clear-key": {"api_key": None}, "reset": {"api_key": None, "api_base": None}, "heuristic": {}, }[change] @@ -7587,7 +7594,7 @@ class TestTeamMemberAutoRouterWrites: operation: Final = ( patch_model(row.model_id, request, actor) if endpoint == "patch" else update_model(request, actor) ) - if change == "move-without-key": + if provider == "typesafe" and change in ("move-without-key", "clear-key"): with pytest.raises(ProxyException, match="api_base requires"): await operation database.db.litellm_proxymodeltable.update.assert_not_awaited() @@ -7595,10 +7602,13 @@ class TestTeamMemberAutoRouterWrites: await operation written: Final = database.db.litellm_proxymodeltable.update.await_args.kwargs["data"] saved: Final = json.loads(written["litellm_params"])["complexity_router_config"] + carried_transport: Final = ( + {"api_base": transport["api_base"]} if change == "move-without-key" else transport + ) expected: Final = ( config if change == "heuristic" - else {**config, "jev_classifier_config": {**transport, "timeout_ms": 8100, **overrides}} + else {**config, "jev_classifier_config": {**identity, **carried_transport, "timeout_ms": 8100, **overrides}} ) assert saved == expected assert row.litellm_params["complexity_router_config"] == stored_config diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.test.ts index 79c4243271e..2c433263c0f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.test.ts @@ -85,7 +85,7 @@ describe("autoRouterRows", () => { it.each([ ["llm", "LLM Classifier"], - ["jev", "JEV Classifier"], + ["jev", "Decision Model"], ])("labels a router using the %s classifier", (classifierType, label) => { const row = toAutoRouterRow( { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.ts b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.ts index 1faf3408c23..429bca3ab6f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AutoRouters/autoRouterRows.ts @@ -57,7 +57,7 @@ const dedupe = (models: string[]): string[] => Array.from(new Set(models)); const COMPLEXITY_TYPE_LABELS: Record = { llm: "LLM Classifier", - jev: "JEV Classifier", + jev: "Decision Model", capability: "Capability", llm_v2: "Fuse v2", heuristic_first: "Heuristic first", diff --git a/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.integration.test.tsx b/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.integration.test.tsx index f843a472d15..137ba954f32 100644 --- a/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.integration.test.tsx +++ b/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.integration.test.tsx @@ -68,7 +68,7 @@ describe("Auto-router classifier selection", () => { llm: "LLM", heuristic_first: "LLM", hybrid: "LLM", - jev: "Jev", + jev: "Decision Model", }[classifier_type]; expect(screen.getByRole("radio", { name: new RegExp(`^${family}$`) })).toBeChecked(); fireEvent.click(screen.getByRole("radio", { name: new RegExp(`^${family}$`) })); diff --git a/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.tsx b/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.tsx index 92fc8d2a335..b6997c3d4c4 100644 --- a/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.tsx +++ b/ui/litellm-dashboard/src/components/add_model/AutoRouterClassifierTabs.tsx @@ -164,7 +164,7 @@ const AutoRouterClassifierTabs: React.FC = ({ val {[ { value: "heuristics", label: "Heuristics", description: "Classify locally, with no API call" }, { value: "llm", label: "LLM", description: "Use a judge model to choose a solver" }, - { value: "jev", label: "Jev", description: "Use TypeSafe System One Choice to choose a tier" }, + { value: "jev", label: "Decision Model", description: "Use Jev or open-source Nimble to choose a tier" }, ].map((option) => (