mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
feat(ui): require embedding model for semantic auto router (#33313)
Co-authored-by: shivam <shivam@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
111d447e1b
commit
5961c173e1
4 changed files with 113 additions and 23 deletions
|
|
@ -21,6 +21,7 @@ import {
|
|||
getSemanticConfigError,
|
||||
} from "./build_complexity_router_config";
|
||||
import { buildAutoRouterTestTargets, AutoRouterTestTarget } from "./build_auto_router_test_targets";
|
||||
import { getSemanticRouterError } from "./build_semantic_router_validation";
|
||||
import AutoRouterConnectionTest from "./auto_router_connection_test";
|
||||
import NotificationManager from "../molecules/notifications_manager";
|
||||
|
||||
|
|
@ -164,23 +165,13 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({ form, handleOk, acc
|
|||
};
|
||||
|
||||
const submitSemanticRouter = (name: string) => {
|
||||
if (!form.getFieldValue("auto_router_default_model")) {
|
||||
NotificationManager.fromBackend("Please select a Default Model");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!routerConfig || !routerConfig.routes || routerConfig.routes.length === 0) {
|
||||
NotificationManager.fromBackend("Please configure at least one route for the auto router");
|
||||
return;
|
||||
}
|
||||
|
||||
const invalidRoutes = routerConfig.routes.filter(
|
||||
(route: any) => !route.name || !route.description || route.utterances.length === 0,
|
||||
);
|
||||
if (invalidRoutes.length > 0) {
|
||||
NotificationManager.fromBackend(
|
||||
"Please ensure all routes have a target model, description, and at least one utterance",
|
||||
);
|
||||
const validationError = getSemanticRouterError({
|
||||
defaultModel: form.getFieldValue("auto_router_default_model"),
|
||||
embeddingModel: form.getFieldValue("auto_router_embedding_model"),
|
||||
routerConfig,
|
||||
});
|
||||
if (validationError) {
|
||||
NotificationManager.fromBackend(validationError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -358,18 +349,18 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({ form, handleOk, acc
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
rules={[{ required: true, message: "Embedding model is required" }]}
|
||||
label="Embedding Model"
|
||||
name="auto_router_embedding_model"
|
||||
tooltip="Optional: embedding model to use for semantic routing decisions"
|
||||
tooltip="Embedding model to use for semantic routing decisions"
|
||||
labelCol={{ span: 10 }}
|
||||
labelAlign="left"
|
||||
>
|
||||
<AntdSelect
|
||||
placeholder="Select an embedding model (optional)"
|
||||
placeholder="Select an embedding model"
|
||||
options={modelGroupOptions}
|
||||
style={{ width: "100%" }}
|
||||
showSearch
|
||||
allowClear
|
||||
/>
|
||||
</Form.Item>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
import { getSemanticRouterError, SemanticRouterConfig } from "./build_semantic_router_validation";
|
||||
|
||||
const validRouterConfig: SemanticRouterConfig = {
|
||||
routes: [{ name: "gpt-4o", description: "general chat", utterances: ["hello there"] }],
|
||||
};
|
||||
|
||||
describe("getSemanticRouterError", () => {
|
||||
it("requires an embedding model once the default model and routes are configured", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: "gpt-4o",
|
||||
embeddingModel: undefined,
|
||||
routerConfig: validRouterConfig,
|
||||
}),
|
||||
).toBe("Please select an Embedding Model");
|
||||
});
|
||||
|
||||
it("treats an empty embedding model string as missing", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: "gpt-4o",
|
||||
embeddingModel: "",
|
||||
routerConfig: validRouterConfig,
|
||||
}),
|
||||
).toBe("Please select an Embedding Model");
|
||||
});
|
||||
|
||||
it("passes when an embedding model is selected", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: "gpt-4o",
|
||||
embeddingModel: "text-embedding-3-large",
|
||||
routerConfig: validRouterConfig,
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("flags a missing default model before checking the embedding model", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: undefined,
|
||||
embeddingModel: undefined,
|
||||
routerConfig: validRouterConfig,
|
||||
}),
|
||||
).toBe("Please select a Default Model");
|
||||
});
|
||||
|
||||
it("flags missing routes before checking the embedding model", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: "gpt-4o",
|
||||
embeddingModel: undefined,
|
||||
routerConfig: { routes: [] },
|
||||
}),
|
||||
).toBe("Please configure at least one route for the auto router");
|
||||
});
|
||||
|
||||
it("validates route completeness after the embedding model is set", () => {
|
||||
expect(
|
||||
getSemanticRouterError({
|
||||
defaultModel: "gpt-4o",
|
||||
embeddingModel: "text-embedding-3-large",
|
||||
routerConfig: { routes: [{ name: "gpt-4o", description: "", utterances: [] }] },
|
||||
}),
|
||||
).toBe("Please ensure all routes have a target model, description, and at least one utterance");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
export interface SemanticRouterRoute {
|
||||
name?: string;
|
||||
description?: string;
|
||||
utterances?: unknown[];
|
||||
}
|
||||
|
||||
export interface SemanticRouterConfig {
|
||||
routes?: SemanticRouterRoute[];
|
||||
}
|
||||
|
||||
export interface SemanticRouterValidationParams {
|
||||
defaultModel: string | undefined;
|
||||
embeddingModel: string | undefined;
|
||||
routerConfig: SemanticRouterConfig | null | undefined;
|
||||
}
|
||||
|
||||
export const getSemanticRouterError = ({
|
||||
defaultModel,
|
||||
embeddingModel,
|
||||
routerConfig,
|
||||
}: SemanticRouterValidationParams): string | null => {
|
||||
if (!defaultModel) return "Please select a Default Model";
|
||||
if (!routerConfig?.routes || routerConfig.routes.length === 0)
|
||||
return "Please configure at least one route for the auto router";
|
||||
if (!embeddingModel) return "Please select an Embedding Model";
|
||||
if (routerConfig.routes.some((route) => !route.name || !route.description || (route.utterances?.length ?? 0) === 0))
|
||||
return "Please ensure all routes have a target model, description, and at least one utterance";
|
||||
return null;
|
||||
};
|
||||
|
|
@ -367,15 +367,18 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
|
|||
</Form.Item>
|
||||
|
||||
{/* Embedding Model */}
|
||||
<Form.Item label="Embedding Model" name="auto_router_embedding_model">
|
||||
<Form.Item
|
||||
label="Embedding Model"
|
||||
name="auto_router_embedding_model"
|
||||
rules={[{ required: true, message: "Embedding model is required" }]}
|
||||
>
|
||||
<AntdSelect
|
||||
placeholder="Select an embedding model (optional)"
|
||||
placeholder="Select an embedding model"
|
||||
onChange={(value) => {
|
||||
setShowCustomEmbeddingModel(value === "custom");
|
||||
}}
|
||||
options={[...modelOptions, { value: "custom", label: "Enter custom model name" }]}
|
||||
showSearch={true}
|
||||
allowClear
|
||||
/>
|
||||
</Form.Item>
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue