From 020cecfe33f90c5df869048ed1370b58a48db8dd Mon Sep 17 00:00:00 2001 From: Achintya Rajan Date: Fri, 10 Oct 2025 15:32:55 -0700 Subject: [PATCH] ModelRetrySettingsTab and PriceDataManagementTab --- .../components/ModelRetrySettingsTab.tsx | 154 +++++++++++++++++ .../components/PriceDataManagementTab.tsx | 43 +++++ .../models-and-endpoints/model_dashboard.tsx | 157 ++---------------- 3 files changed, 212 insertions(+), 142 deletions(-) create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab.tsx create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/PriceDataManagementTab.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab.tsx new file mode 100644 index 00000000000..753aeedce54 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab.tsx @@ -0,0 +1,154 @@ +import { Button, Select, SelectItem, TabPanel, Text, Title } from "@tremor/react"; +import { InputNumber } from "antd"; +import React from "react"; + +interface GlobalRetryPolicyObject { + [retryPolicyKey: string]: number; +} + +interface RetryPolicyObject { + [key: string]: { [retryPolicyKey: string]: number } | undefined; +} + +interface ModelRetrySettingsTabProps { + selectedModelGroup: string | null; + setSelectedModelGroup: (selectedModelGroup: string | null) => void; + availableModelGroups: string[]; + globalRetryPolicy: GlobalRetryPolicyObject | null; + setGlobalRetryPolicy: React.Dispatch>; + defaultRetry: number; + modelGroupRetryPolicy: RetryPolicyObject | null; + setModelGroupRetryPolicy: React.Dispatch>; + handleSaveRetrySettings: () => void; +} + +const retryPolicyMap: Record = { + "BadRequestError (400)": "BadRequestErrorRetries", + "AuthenticationError (401)": "AuthenticationErrorRetries", + "TimeoutError (408)": "TimeoutErrorRetries", + "RateLimitError (429)": "RateLimitErrorRetries", + "ContentPolicyViolationError (400)": "ContentPolicyViolationErrorRetries", + "InternalServerError (500)": "InternalServerErrorRetries", +}; + +const ModelRetrySettingsTab = ({ + selectedModelGroup, + setSelectedModelGroup, + availableModelGroups, + globalRetryPolicy, + setGlobalRetryPolicy, + defaultRetry, + modelGroupRetryPolicy, + setModelGroupRetryPolicy, + handleSaveRetrySettings, +}: ModelRetrySettingsTabProps) => { + // const [modelGroupRetryPolicy, setModelGroupRetryPolicy] = useState(null); + + return ( + +
+
+ Retry Policy Scope: + +
+
+ + {selectedModelGroup === "global" ? ( + <> + Global Retry Policy + Default retry settings applied to all model groups unless overridden + + ) : ( + <> + Retry Policy for {selectedModelGroup} + Model-specific retry settings. Falls back to global defaults if not set. + + )} + {retryPolicyMap && ( + + + {Object.entries(retryPolicyMap).map(([exceptionType, retryPolicyKey], idx) => { + let retryCount: number; + + if (selectedModelGroup === "global") { + // Show global policy values + retryCount = globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; + } else { + // Show model-group specific values with fallback to global + const modelSpecificCount = modelGroupRetryPolicy?.[selectedModelGroup!]?.[retryPolicyKey]; + if (modelSpecificCount != null) { + retryCount = modelSpecificCount; + } else { + // Fall back to global policy, then default + retryCount = globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; + } + } + + return ( + + + + + ); + })} + +
+ {exceptionType} + {selectedModelGroup !== "global" && ( + + (Global: {globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry}) + + )} + + { + if (selectedModelGroup === "global") { + // Update global policy + setGlobalRetryPolicy((prevGlobalRetryPolicy) => { + if (value == null) return prevGlobalRetryPolicy; + return { + ...(prevGlobalRetryPolicy ?? {}), + [retryPolicyKey]: value, + }; + }); + } else { + // Update model-group specific policy + setModelGroupRetryPolicy((prevModelGroupRetryPolicy) => { + const prevRetryPolicy = prevModelGroupRetryPolicy?.[selectedModelGroup!] ?? {}; + return { + ...(prevModelGroupRetryPolicy ?? {}), + [selectedModelGroup!]: { + ...prevRetryPolicy, + [retryPolicyKey!]: value, + }, + } as RetryPolicyObject; + }); + } + }} + /> +
+ )} + +
+ ); +}; + +export default ModelRetrySettingsTab; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/PriceDataManagementTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/PriceDataManagementTab.tsx new file mode 100644 index 00000000000..6edb6c5b445 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/PriceDataManagementTab.tsx @@ -0,0 +1,43 @@ +import { TabPanel, Text, Title } from "@tremor/react"; +import PriceDataReload from "@/components/price_data_reload"; +import { modelCostMap } from "@/components/networking"; +import React from "react"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; + +interface PriceDataManagementPanelProps { + setModelMap: (data: any) => void; +} + +const PriceDataManagementTab = ({ setModelMap }: PriceDataManagementPanelProps) => { + const { accessToken } = useAuthorized(); + + return ( + +
+
+ Price Data Management + + Manage model pricing data and configure automatic reload schedules + +
+ { + // Refresh the model map after successful reload + const fetchModelMap = async () => { + const data = await modelCostMap(accessToken); + setModelMap(data); + }; + fetchModelMap(); + }} + buttonText="Reload Price Data" + size="middle" + type="primary" + className="w-full" + /> +
+
+ ); +}; + +export default PriceDataManagementTab; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/model_dashboard.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/model_dashboard.tsx index 1916832d708..7c0244b256b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/model_dashboard.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/model_dashboard.tsx @@ -57,6 +57,8 @@ import ModelGroupAliasSettings from "../../../components/model_group_alias_setti import { all_admin_roles } from "@/utils/roles"; import NotificationsManager from "../../../components/molecules/notifications_manager"; import AllModelsTab from "@/app/(dashboard)/models-and-endpoints/components/AllModelsTab"; +import PriceDataManagementTab from "@/app/(dashboard)/models-and-endpoints/components/PriceDataManagementTab"; +import ModelRetrySettingsTab from "@/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab"; interface ModelDashboardProps { accessToken: string | null; @@ -97,15 +99,6 @@ interface ProviderSettings { fields: ProviderFields[]; } -const retry_policy_map: Record = { - "BadRequestError (400)": "BadRequestErrorRetries", - "AuthenticationError (401)": "AuthenticationErrorRetries", - "TimeoutError (408)": "TimeoutErrorRetries", - "RateLimitError (429)": "RateLimitErrorRetries", - "ContentPolicyViolationError (400)": "ContentPolicyViolationErrorRetries", - "InternalServerError (500)": "InternalServerErrorRetries", -}; - const ModelsAndEndpointsView: React.FC = ({ accessToken, token, @@ -565,7 +558,7 @@ const ModelsAndEndpointsView: React.FC = ({ let router_settings = routerSettingsInfo.router_settings; console.log("routerSettingsInfo:", router_settings); - + ``; let model_group_retry_policy = router_settings.model_group_retry_policy; let default_retries = router_settings.num_retries; @@ -1278,113 +1271,17 @@ const ModelsAndEndpointsView: React.FC = ({ )} - -
-
- Retry Policy Scope: - -
-
- - {selectedModelGroup === "global" ? ( - <> - Global Retry Policy - Default retry settings applied to all model groups unless overridden - - ) : ( - <> - Retry Policy for {selectedModelGroup} - - Model-specific retry settings. Falls back to global defaults if not set. - - - )} - {retry_policy_map && ( - - - {Object.entries(retry_policy_map).map(([exceptionType, retryPolicyKey], idx) => { - let retryCount: number; - - if (selectedModelGroup === "global") { - // Show global policy values - retryCount = globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; - } else { - // Show model-group specific values with fallback to global - const modelSpecificCount = modelGroupRetryPolicy?.[selectedModelGroup!]?.[retryPolicyKey]; - if (modelSpecificCount != null) { - retryCount = modelSpecificCount; - } else { - // Fall back to global policy, then default - retryCount = globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; - } - } - - return ( - - - - - ); - })} - -
- {exceptionType} - {selectedModelGroup !== "global" && ( - - (Global: {globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry}) - - )} - - { - if (selectedModelGroup === "global") { - // Update global policy - setGlobalRetryPolicy((prevGlobalRetryPolicy) => { - if (value == null) return prevGlobalRetryPolicy; - return { - ...(prevGlobalRetryPolicy ?? {}), - [retryPolicyKey]: value, - }; - }); - } else { - // Update model-group specific policy - setModelGroupRetryPolicy((prevModelGroupRetryPolicy) => { - const prevRetryPolicy = prevModelGroupRetryPolicy?.[selectedModelGroup!] ?? {}; - return { - ...(prevModelGroupRetryPolicy ?? {}), - [selectedModelGroup!]: { - ...prevRetryPolicy, - [retryPolicyKey!]: value, - }, - } as RetryPolicyObject; - }); - } - }} - /> -
- )} - -
+ = ({ onAliasUpdate={setModelGroupAlias} /> - -
-
- Price Data Management - - Manage model pricing data and configure automatic reload schedules - -
- { - // Refresh the model map after successful reload - const fetchModelMap = async () => { - const data = await modelCostMap(accessToken); - setModelMap(data); - }; - fetchModelMap(); - }} - buttonText="Reload Price Data" - size="middle" - type="primary" - className="w-full" - /> -
-
+ )}