From cf88e8599557dad2488d997967356c731f7fb921 Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Tue, 29 Sep 2026 14:11:02 -0700 Subject: [PATCH] feat(ui): add Laya decision classifier controls --- .../AutoRouters/autoRouterRows.test.ts | 14 +- .../components/AutoRouters/autoRouterRows.ts | 2 +- ...oRouterClassifierTabs.integration.test.tsx | 2 +- .../add_model/AutoRouterClassifierTabs.tsx | 2 +- .../add_model/ClassificationMethodConfig.tsx | 4 +- .../add_model/ClassifierTypeRadios.tsx | 4 +- .../add_model/ComplexityRouterConfig.tsx | 2 +- .../JevClassifierConfig.integration.test.tsx | 92 ++++++++++- .../add_model/JevClassifierConfig.tsx | 149 +++++++++++++++++- .../JevConnectionTest.integration.test.tsx | 34 +++- .../add_auto_router_tab.integration.test.tsx | 33 ++-- .../add_model/auto_router_connection_test.tsx | 10 +- ...d_auto_router_routing_test_request.test.ts | 22 +++ .../build_complexity_router_config.test.ts | 14 +- .../build_complexity_router_config.ts | 6 +- .../add_model/jev_classifier_config.test.ts | 111 +++++++++++++ .../add_model/jev_classifier_config.ts | 80 ++++++++-- .../src/components/add_model/tier_rows.ts | 2 +- ...d_updated_complexity_router_config.test.ts | 20 +++ ...dit_auto_router_modal.integration.test.tsx | 128 ++++++++++++++- .../hydrate_complexity_router_config.ts | 4 +- .../LogDetailsDrawer/RoutingDecisionCard.tsx | 2 +- 22 files changed, 670 insertions(+), 67 deletions(-) create mode 100644 ui/litellm-dashboard/src/components/add_model/jev_classifier_config.test.ts 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..fb4ea079f75 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 @@ -84,15 +84,21 @@ describe("autoRouterRows", () => { }); it.each([ - ["llm", "LLM Classifier"], - ["jev", "JEV Classifier"], - ])("labels a router using the %s classifier", (classifierType, label) => { + ["llm", "LLM Classifier", undefined], + ["jev", "Decision Model", undefined], + ["jev", "Decision Model", "laya"], + ])("labels a router using the %s classifier", (classifierType, label, provider) => { const row = toAutoRouterRow( { ...complexityDeployment, litellm_params: { ...complexityDeployment.litellm_params, - complexity_router_config: { tiers: {}, classifier_type: classifierType, adaptive: true }, + complexity_router_config: { + tiers: {}, + classifier_type: classifierType, + adaptive: true, + ...(provider && { jev_classifier_config: { provider, model: "english" } }), + }, }, }, 0, 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..efe8cdb7164 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 Laya to choose a tier" }, ].map((option) => (