From 06cfed53c0001b179c25b3205fd189b6c9fdd40f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Apr 2026 13:27:36 +0000 Subject: [PATCH] feat(ui): ModelRetrySettingsTab to shadcn - @tremor Select/SelectItem/TabPanel/Text/Title + antd InputNumber \u2192 shadcn Select/Input (type=number) + plain h3/span. Tremor TabPanel preserved (caller is still tremor TabGroup). - Input onChange reads event.target.value and coerces to number, preserving the null handling pattern from antd's InputNumber. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang --- .../components/ModelRetrySettingsTab.tsx | 143 +++++++++++------- 1 file changed, 90 insertions(+), 53 deletions(-) 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 index 753aeedce54..dfd56a21ff7 100644 --- 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 @@ -1,5 +1,14 @@ -import { Button, Select, SelectItem, TabPanel, Text, Title } from "@tremor/react"; -import { InputNumber } from "antd"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +// eslint-disable-next-line litellm-ui/no-banned-ui-imports +import { TabPanel } from "@tremor/react"; import React from "react"; interface GlobalRetryPolicyObject { @@ -15,10 +24,14 @@ interface ModelRetrySettingsTabProps { setSelectedModelGroup: (selectedModelGroup: string | null) => void; availableModelGroups: string[]; globalRetryPolicy: GlobalRetryPolicyObject | null; - setGlobalRetryPolicy: React.Dispatch>; + setGlobalRetryPolicy: React.Dispatch< + React.SetStateAction + >; defaultRetry: number; modelGroupRetryPolicy: RetryPolicyObject | null; - setModelGroupRetryPolicy: React.Dispatch>; + setModelGroupRetryPolicy: React.Dispatch< + React.SetStateAction + >; handleSaveRetrySettings: () => void; } @@ -42,79 +55,99 @@ const ModelRetrySettingsTab = ({ setModelGroupRetryPolicy, handleSaveRetrySettings, }: ModelRetrySettingsTabProps) => { - // const [modelGroupRetryPolicy, setModelGroupRetryPolicy] = useState(null); - return (
- Retry Policy Scope: + Retry Policy Scope:
{selectedModelGroup === "global" ? ( <> - Global Retry Policy - Default retry settings applied to all model groups unless overridden +

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 for {selectedModelGroup} +

+

+ Model-specific retry settings. Falls back to global defaults if not + set. +

)} - {retryPolicyMap && ( - - - {Object.entries(retryPolicyMap).map(([exceptionType, retryPolicyKey], idx) => { +
+ + {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]; + const modelSpecificCount = + modelGroupRetryPolicy?.[selectedModelGroup!]?.[ + retryPolicyKey + ]; if (modelSpecificCount != null) { retryCount = modelSpecificCount; } else { - // Fall back to global policy, then default - retryCount = globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; + retryCount = + globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry; } } return ( - + ); - })} - -
- {exceptionType} + {exceptionType} {selectedModelGroup !== "global" && ( - - (Global: {globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry}) - + + (Global:{" "} + {globalRetryPolicy?.[retryPolicyKey] ?? defaultRetry}) + )} - { + onChange={(e) => { + const raw = e.target.value; + const value = raw === "" ? null : Number(raw); if (selectedModelGroup === "global") { - // Update global policy setGlobalRetryPolicy((prevGlobalRetryPolicy) => { if (value == null) return prevGlobalRetryPolicy; return { @@ -123,27 +156,31 @@ const ModelRetrySettingsTab = ({ }; }); } else { - // Update model-group specific policy - setModelGroupRetryPolicy((prevModelGroupRetryPolicy) => { - const prevRetryPolicy = prevModelGroupRetryPolicy?.[selectedModelGroup!] ?? {}; - return { - ...(prevModelGroupRetryPolicy ?? {}), - [selectedModelGroup!]: { - ...prevRetryPolicy, - [retryPolicyKey!]: value, - }, - } as RetryPolicyObject; - }); + setModelGroupRetryPolicy( + (prevModelGroupRetryPolicy) => { + const prevRetryPolicy = + prevModelGroupRetryPolicy?.[ + selectedModelGroup! + ] ?? {}; + return { + ...(prevModelGroupRetryPolicy ?? {}), + [selectedModelGroup!]: { + ...prevRetryPolicy, + [retryPolicyKey!]: value, + }, + } as RetryPolicyObject; + }, + ); } }} />
- )} + }, + )} + +