mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): guardrails/GuardrailTestPanel to shadcn
- @tremor Button + antd Input.TextArea/Typography/Tooltip + @ant-design Copy/InfoCircle \u2192 shadcn Button/Textarea/Tooltip + lucide Copy/Info. - Blue guardrail-name chips preserved as categorical accent (file added to .eslintrc.json overrides). Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
81ebf913e8
commit
11049a1141
2 changed files with 58 additions and 32 deletions
|
|
@ -63,6 +63,7 @@
|
|||
"src/components/prompts/variable_textarea.tsx",
|
||||
"src/components/chat/MCPCredentialsTab.tsx",
|
||||
"src/components/common_components/KeyLifecycleSettings.tsx",
|
||||
"src/components/guardrails/GuardrailTestPanel.tsx",
|
||||
"src/components/prompts/prompt_editor_view/PromptEditorHeader.tsx",
|
||||
"src/components/prompts/prompt_editor_view/VersionHistorySidePanel.tsx",
|
||||
"src/app/(dashboard)/teams/components/TeamsTable/ModelsCell.tsx",
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
import React, { useState } from "react";
|
||||
import { Button } from "@tremor/react";
|
||||
import { Input, Typography, Tooltip } from "antd";
|
||||
import { CopyOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { Copy, Info } from "lucide-react";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
import GuardrailTestResults from "./GuardrailTestResults";
|
||||
|
||||
const { TextArea } = Input;
|
||||
const { Text } = Typography;
|
||||
|
||||
interface GuardrailTestPanelProps {
|
||||
guardrailNames: string[];
|
||||
onSubmit: (text: string) => void;
|
||||
isLoading: boolean;
|
||||
results: Array<{ guardrailName: string; response_text: string; latency: number }> | null;
|
||||
errors: Array<{ guardrailName: string; error: Error; latency: number }> | null;
|
||||
results:
|
||||
| Array<{ guardrailName: string; response_text: string; latency: number }>
|
||||
| null;
|
||||
errors:
|
||||
| Array<{ guardrailName: string; error: Error; latency: number }>
|
||||
| null;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
|
|
@ -23,7 +30,6 @@ export function GuardrailTestPanel({
|
|||
isLoading,
|
||||
results,
|
||||
errors,
|
||||
onClose,
|
||||
}: GuardrailTestPanelProps) {
|
||||
const [inputText, setInputText] = useState("");
|
||||
|
||||
|
|
@ -82,53 +88,65 @@ export function GuardrailTestPanel({
|
|||
|
||||
return (
|
||||
<div className="space-y-4 h-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between pb-3 border-b border-gray-200">
|
||||
<div className="flex items-center justify-between pb-3 border-b border-border">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<h2 className="text-lg font-semibold text-gray-900">Test Guardrails:</h2>
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
Test Guardrails:
|
||||
</h2>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{guardrailNames.map((name) => (
|
||||
<div
|
||||
key={name}
|
||||
className="inline-flex items-center space-x-1 bg-blue-50 px-3 py-1 rounded-md border border-blue-200"
|
||||
className="inline-flex items-center space-x-1 bg-blue-50 dark:bg-blue-950/30 px-3 py-1 rounded-md border border-blue-200 dark:border-blue-900"
|
||||
>
|
||||
<span className="font-mono text-blue-700 font-medium text-sm">{name}</span>
|
||||
<span className="font-mono text-blue-700 dark:text-blue-300 font-medium text-sm">
|
||||
{name}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-gray-500">
|
||||
Test {guardrailNames.length > 1 ? "guardrails" : "guardrail"} and compare results
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Test {guardrailNames.length > 1 ? "guardrails" : "guardrail"}{" "}
|
||||
and compare results
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Input Section */}
|
||||
<div className="flex-1 overflow-auto space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<label className="text-sm font-medium text-gray-700">Input Text</label>
|
||||
<Tooltip title="Press Enter to submit. Use Shift+Enter for new line.">
|
||||
<InfoCircleOutlined className="text-gray-400 cursor-help" />
|
||||
</Tooltip>
|
||||
<label className="text-sm font-medium text-foreground">
|
||||
Input Text
|
||||
</label>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
Press Enter to submit. Use Shift+Enter for new line.
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
{inputText && (
|
||||
<Button
|
||||
size="xs"
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
icon={CopyOutlined}
|
||||
onClick={handleCopyInput}
|
||||
>
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
Copy Input
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<TextArea
|
||||
<Textarea
|
||||
value={inputText}
|
||||
onChange={(e) => setInputText(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
|
|
@ -137,18 +155,27 @@ export function GuardrailTestPanel({
|
|||
className="font-mono text-sm"
|
||||
/>
|
||||
<div className="flex justify-between items-center mt-1">
|
||||
<Text className="text-xs text-gray-500">
|
||||
Press <kbd className="px-1 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs">Enter</kbd> to submit • <kbd className="px-1 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs">Shift+Enter</kbd> for new line
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-500">Characters: {inputText.length}</Text>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Press{" "}
|
||||
<kbd className="px-1 py-0.5 bg-muted border border-border rounded text-xs">
|
||||
Enter
|
||||
</kbd>{" "}
|
||||
to submit •{" "}
|
||||
<kbd className="px-1 py-0.5 bg-muted border border-border rounded text-xs">
|
||||
Shift+Enter
|
||||
</kbd>{" "}
|
||||
for new line
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
Characters: {inputText.length}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
loading={isLoading}
|
||||
disabled={!inputText.trim()}
|
||||
disabled={isLoading || !inputText.trim()}
|
||||
className="w-full"
|
||||
>
|
||||
{isLoading
|
||||
|
|
@ -158,7 +185,6 @@ export function GuardrailTestPanel({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Results Section */}
|
||||
<GuardrailTestResults results={results} errors={errors} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -166,4 +192,3 @@ export function GuardrailTestPanel({
|
|||
}
|
||||
|
||||
export default GuardrailTestPanel;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue