mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): guardrails \u2014 guardrail_garden + pii_configuration + GuardrailsMonitorView
- GuardrailsMonitorView: tremor DateRangePickerValue type-only import now has an inline eslint-disable (kept as a shared type in phase 1). - pii_configuration: antd Typography \u2192 plain <h4>/<span> with semantic tokens. - guardrail_garden: antd Input + @ant-design/icons SearchOutlined / ArrowRightOutlined \u2192 shadcn Input with lucide Search/ArrowRight. Replaced every inline style attribute with Tailwind utilities and semantic tokens (text-foreground/text-muted-foreground/text-primary). The only retained inline style is the CSS grid template column value which relies on a dynamic auto-fill minmax() that Tailwind can't express succinctly. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
8d254dc977
commit
b8acfb4f9f
3 changed files with 73 additions and 48 deletions
|
|
@ -1,3 +1,4 @@
|
|||
// eslint-disable-next-line litellm-ui/no-banned-ui-imports
|
||||
import type { DateRangePickerValue } from "@tremor/react";
|
||||
import React, { useCallback, useMemo, useState } from "react";
|
||||
import { formatDate } from "@/components/networking";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import { Input } from "antd";
|
||||
import { SearchOutlined, ArrowRightOutlined } from "@ant-design/icons";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { ArrowRight, Search } from "lucide-react";
|
||||
import { GuardrailCardInfo, ALL_CARDS } from "./guardrail_garden_data";
|
||||
import GuardrailCard from "./guardrail_garden_card";
|
||||
import GuardrailDetailView from "./guardrail_garden_detail";
|
||||
|
|
@ -10,9 +10,14 @@ interface GuardrailGardenProps {
|
|||
onGuardrailCreated: () => void;
|
||||
}
|
||||
|
||||
const GuardrailGarden: React.FC<GuardrailGardenProps> = ({ accessToken, onGuardrailCreated }) => {
|
||||
const GuardrailGarden: React.FC<GuardrailGardenProps> = ({
|
||||
accessToken,
|
||||
onGuardrailCreated,
|
||||
}) => {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [selectedCard, setSelectedCard] = useState<GuardrailCardInfo | null>(null);
|
||||
const [selectedCard, setSelectedCard] = useState<GuardrailCardInfo | null>(
|
||||
null,
|
||||
);
|
||||
const [showAllLitellm, setShowAllLitellm] = useState(false);
|
||||
const CARDS_PER_ROW = 5;
|
||||
const VISIBLE_ROWS = 2;
|
||||
|
|
@ -43,63 +48,83 @@ const GuardrailGarden: React.FC<GuardrailGardenProps> = ({ accessToken, onGuardr
|
|||
|
||||
return (
|
||||
<div>
|
||||
{/* Search Bar */}
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<Input
|
||||
size="large"
|
||||
placeholder="Search guardrails"
|
||||
prefix={<SearchOutlined style={{ color: "#9ca3af" }} />}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
style={{ borderRadius: 8 }}
|
||||
/>
|
||||
<div className="mb-6">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
|
||||
<Input
|
||||
placeholder="Search guardrails"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-9 h-11 rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* LiteLLM Content Filter Section */}
|
||||
<div style={{ marginBottom: 40 }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 }}>
|
||||
<h2 style={{ fontSize: 20, fontWeight: 600, color: "#111827", margin: 0 }}>LiteLLM Content Filter</h2>
|
||||
<span
|
||||
style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 14, color: "#1a73e8", cursor: "pointer" }}
|
||||
<div className="mb-10">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<h2 className="text-xl font-semibold text-foreground m-0">
|
||||
LiteLLM Content Filter
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowAllLitellm(!showAllLitellm)}
|
||||
className="inline-flex items-center gap-1.5 text-sm text-primary cursor-pointer bg-transparent border-none"
|
||||
>
|
||||
{showAllLitellm ? (
|
||||
<>Show less</>
|
||||
) : (
|
||||
<>
|
||||
<ArrowRightOutlined style={{ fontSize: 12 }} />
|
||||
<ArrowRight className="h-3 w-3" />
|
||||
{`Show all (${litellmCards.length})`}
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<p style={{ fontSize: 13, color: "#6b7280", margin: "4px 0 20px 0" }}>
|
||||
Built-in guardrails powered by LiteLLM. Zero latency, no external dependencies, no additional cost.
|
||||
<p className="text-sm text-muted-foreground mt-1 mb-5">
|
||||
Built-in guardrails powered by LiteLLM. Zero latency, no external
|
||||
dependencies, no additional cost.
|
||||
</p>
|
||||
<div style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
|
||||
gap: 16,
|
||||
}}>
|
||||
{(showAllLitellm ? litellmCards : litellmCards.slice(0, CARDS_PER_ROW * VISIBLE_ROWS)).map((card) => (
|
||||
<GuardrailCard key={card.id} card={card} onClick={() => setSelectedCard(card)} />
|
||||
<div
|
||||
className="grid gap-4"
|
||||
style={{
|
||||
gridTemplateColumns:
|
||||
"repeat(auto-fill, minmax(220px, 1fr))",
|
||||
}}
|
||||
>
|
||||
{(showAllLitellm
|
||||
? litellmCards
|
||||
: litellmCards.slice(0, CARDS_PER_ROW * VISIBLE_ROWS)
|
||||
).map((card) => (
|
||||
<GuardrailCard
|
||||
key={card.id}
|
||||
card={card}
|
||||
onClick={() => setSelectedCard(card)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Partner Guardrails Section */}
|
||||
<div style={{ marginBottom: 40 }}>
|
||||
<h2 style={{ fontSize: 20, fontWeight: 600, color: "#111827", margin: "0 0 4px 0" }}>Partner Guardrails</h2>
|
||||
<p style={{ fontSize: 13, color: "#6b7280", margin: "4px 0 20px 0" }}>
|
||||
Third-party guardrail integrations from leading AI security providers.
|
||||
<div className="mb-10">
|
||||
<h2 className="text-xl font-semibold text-foreground mt-0 mb-1">
|
||||
Partner Guardrails
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground mt-1 mb-5">
|
||||
Third-party guardrail integrations from leading AI security
|
||||
providers.
|
||||
</p>
|
||||
<div style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
|
||||
gap: 16,
|
||||
}}>
|
||||
<div
|
||||
className="grid gap-4"
|
||||
style={{
|
||||
gridTemplateColumns:
|
||||
"repeat(auto-fill, minmax(220px, 1fr))",
|
||||
}}
|
||||
>
|
||||
{partnerCards.map((card) => (
|
||||
<GuardrailCard key={card.id} card={card} onClick={() => setSelectedCard(card)} />
|
||||
<GuardrailCard
|
||||
key={card.id}
|
||||
card={card}
|
||||
onClick={() => setSelectedCard(card)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import { Typography } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { CategoryFilter, PiiEntityList, QuickActions } from "./pii_components";
|
||||
import { PiiConfigurationProps } from "./types";
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
/**
|
||||
* A reusable component for rendering PII entity selection and action configuration
|
||||
* Used in both add and edit guardrail forms
|
||||
|
|
@ -57,11 +54,13 @@ const PiiConfiguration: React.FC<PiiConfigurationProps> = ({
|
|||
<div className="pii-configuration">
|
||||
<div className="flex justify-between items-center mb-5">
|
||||
<div className="flex items-center">
|
||||
<Title level={4} className="!m-0 font-semibold text-gray-800">
|
||||
<h4 className="m-0 font-semibold text-foreground text-base">
|
||||
Configure PII Protection
|
||||
</Title>
|
||||
</h4>
|
||||
</div>
|
||||
<Text className="text-gray-500">{selectedEntities.length} items selected</Text>
|
||||
<span className="text-muted-foreground">
|
||||
{selectedEntities.length} items selected
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue