diff --git a/litellm/proxy/route_llm_request.py b/litellm/proxy/route_llm_request.py index 17cc4374560..25306759520 100644 --- a/litellm/proxy/route_llm_request.py +++ b/litellm/proxy/route_llm_request.py @@ -368,6 +368,7 @@ async def route_request( # noqa: PLR0915 - Complex routing function, refactorin "num_retries", "timeout", "model_group_retry_policy", + "routing_strategy", ] # Merge override settings into data (only if not already set in request) diff --git a/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx b/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx index f410a049762..5015cde70c3 100644 --- a/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx +++ b/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx @@ -96,6 +96,7 @@ export interface KeyResponse { }; access_group_ids?: string[]; budget_limits?: Array<{ budget_duration: string; max_budget: number; reset_at?: string }>; + router_settings?: Record; auto_rotate?: boolean; rotation_interval?: string; last_rotation_at?: string; diff --git a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx index 9b38d930a50..640acbc26a2 100644 --- a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx +++ b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx @@ -4,7 +4,7 @@ import { useProjects } from "@/app/(dashboard)/hooks/projects/useProjects"; import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings"; import PolicySelector from "@/components/policies/PolicySelector"; import { InfoCircleOutlined } from "@ant-design/icons"; -import { TextInput, Button as TremorButton } from "@tremor/react"; +import { TextInput, Button as TremorButton, Accordion, AccordionHeader, AccordionBody } from "@tremor/react"; import { Form, Input, Select, Switch, Tooltip } from "antd"; import { useEffect, useState } from "react"; import { rolesWithWriteAccess } from "../../utils/roles"; @@ -15,6 +15,7 @@ import KeyLifecycleSettings from "../common_components/KeyLifecycleSettings"; import PassThroughRoutesSelector from "../common_components/PassThroughRoutesSelector"; import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem"; import OrganizationDropdown from "../common_components/OrganizationDropdown"; +import RouterSettingsAccordion, { RouterSettingsAccordionValue } from "../common_components/RouterSettingsAccordion"; import { extractLoggingSettings, formatMetadataForDisplay, stripTagsFromMetadata } from "../key_info_utils"; import { BudgetWindowEntry, BudgetWindowsEditor } from "../key_team_helpers/BudgetWindowsEditor"; import { KeyResponse } from "../key_team_helpers/key_list"; @@ -108,6 +109,9 @@ export function KeyEditView({ const [budgetLimits, setBudgetLimits] = useState( Array.isArray(keyData.budget_limits) ? keyData.budget_limits : [] ); + const [routerSettings, setRouterSettings] = useState( + keyData.router_settings ? { router_settings: keyData.router_settings } : null + ); const { data: organizations, isLoading: isOrganizationsLoading } = useOrganizations(); const { data: projects } = useProjects(); const { data: uiSettingsData } = useUISettings(); @@ -283,6 +287,16 @@ export function KeyEditView({ const validWindows = budgetLimits.filter((w) => w.budget_duration && w.max_budget !== null && w.max_budget !== undefined); values.budget_limits = validWindows.length > 0 ? validWindows : undefined; + // Add router_settings if any are defined + if (routerSettings?.router_settings) { + const hasValues = Object.values(routerSettings.router_settings).some( + (value) => value !== null && value !== undefined && value !== "", + ); + if (hasValues) { + values.router_settings = routerSettings.router_settings; + } + } + await onSubmit(values); } finally { setIsKeySaving(false); @@ -448,6 +462,22 @@ export function KeyEditView({ /> + + + Router Settings + + +
+ +
+
+
+