diff --git a/ui/litellm-dashboard/src/components/guardrails.tsx b/ui/litellm-dashboard/src/components/guardrails.tsx index 0add74cd598..7f76db0494f 100644 --- a/ui/litellm-dashboard/src/components/guardrails.tsx +++ b/ui/litellm-dashboard/src/components/guardrails.tsx @@ -314,6 +314,8 @@ const GuardrailsPanel: React.FC = ({ accessToken, userRole onClose={handleCloseModal} accessToken={accessToken} onSuccess={handleSuccess} + userRole={userRole} + userID={userID} /> void; accessToken: string | null; onSuccess: () => void; + userRole?: string; + userID?: string | null; } interface GuardrailSettings { @@ -91,7 +95,7 @@ interface ProviderParamsResponse { [provider: string]: { [key: string]: ProviderParam }; } -const AddGuardrailForm: React.FC = ({ visible, onClose, accessToken, onSuccess }) => { +const AddGuardrailForm: React.FC = ({ visible, onClose, accessToken, onSuccess, userRole, userID }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [selectedProvider, setSelectedProvider] = useState(null); @@ -101,6 +105,12 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a const [currentStep, setCurrentStep] = useState(0); const [providerParams, setProviderParams] = useState(null); + // Team-only guardrail state + const [teams, setTeams] = useState([]); + const [isTeamOnly, setIsTeamOnly] = useState(false); + + const isAdmin = userRole === "Admin" || userRole === "Admin Viewer"; + // Azure Text Moderation state const [selectedCategories, setSelectedCategories] = useState([]); const [globalSeverityThreshold, setGlobalSeverityThreshold] = useState(2); @@ -125,20 +135,22 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a return (providerValue || "").toLowerCase() === "tool_permission"; }, [selectedProvider]); - // Fetch guardrail UI settings + provider params on mount / accessToken change + // Fetch guardrail UI settings + provider params + teams on mount / accessToken change useEffect(() => { if (!accessToken) return; const fetchData = async () => { try { // Parallel requests for speed - const [uiSettings, providerParamsResp] = await Promise.all([ + const [uiSettings, providerParamsResp, teamsResponse] = await Promise.all([ getGuardrailUISettings(accessToken), getGuardrailProviderSpecificParams(accessToken), + teamListCall(accessToken, null, isAdmin ? null : userID), ]); setGuardrailSettings(uiSettings); setProviderParams(providerParamsResp); + setTeams(teamsResponse || []); // Populate dynamic providers from API response populateGuardrailProviders(providerParamsResp); @@ -150,7 +162,7 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a }; fetchData(); - }, [accessToken]); + }, [accessToken, isAdmin, userID]); const handleProviderChange = (value: string) => { setSelectedProvider(value); @@ -265,6 +277,7 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a on_disallowed_action: "block", violation_message_template: "", }); + setIsTeamOnly(false); setCurrentStep(0); }; @@ -377,6 +390,11 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a } } + // Add team_id for team-only guardrails + if (isTeamOnly && values.team_id) { + guardrailData.litellm_params.team_id = values.team_id; + } + /****************************** * Add provider-specific params * ---------------------------------- @@ -596,6 +614,46 @@ const AddGuardrailForm: React.FC = ({ visible, onClose, a + {/* Team-only Guardrail Switch */} + + + { + setIsTeamOnly(checked); + if (!checked) { + form.setFieldValue("team_id", undefined); + } + }} + /> + + + + {/* Conditional Team Selection */} + {isTeamOnly && ( + + + + )} + {/* Use the GuardrailProviderFields component to render provider-specific fields */} {!isToolPermissionProvider && !shouldRenderContentFilterConfigSettings(selectedProvider) && (