[Feature] UI - Guardrail Info Page Show PII Config (#16164)

* Guardrail info page fix

* Make the Configurations more readable and render in a table
This commit is contained in:
yuneng-jiang 2025-11-02 09:05:00 -08:00 • committed by GitHub
parent 48822c2fa2
commit e336434b27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 66 additions and 15 deletions

View file

@ -110,4 +110,41 @@ describe("Guardrail Info", () => {
});
}
});
it("should render the guardrail info", async () => {
// Mock the network responses
vi.mocked(networking.getGuardrailInfo).mockResolvedValue({
guardrail_id: "123",
guardrail_name: "Test Guardrail",
litellm_params: {
guardrail: "presidio",
mode: "pre_call",
default_on: true,
pii_entities_config: {
PERSON: "MASK",
EMAIL: "REDACT",
},
},
created_at: "2024-01-01T00:00:00Z",
updated_at: "2024-01-01T00:00:00Z",
guardrail_definition_location: "database",
});
vi.mocked(networking.getGuardrailUISettings).mockResolvedValue({
supported_entities: ["PERSON", "EMAIL"],
supported_actions: ["MASK", "REDACT"],
pii_entity_categories: [],
supported_modes: ["pre_call", "post_call"],
});
vi.mocked(networking.getGuardrailProviderSpecificParams).mockResolvedValue({});
const { getByText } = render(
<GuardrailInfoView guardrailId="123" onClose={() => {}} accessToken="123" isAdmin={true} />,
);
await waitFor(() => {
expect(getByText("PII Entity Configuration")).toBeInTheDocument();
});
});
});

View file

@ -14,7 +14,7 @@ import {
TextInput,
} from "@tremor/react";
import { Button, Form, Input, Select, Divider, Tooltip } from "antd";
import { InfoCircleOutlined } from "@ant-design/icons";
import { InfoCircleOutlined, EyeInvisibleOutlined, StopOutlined } from "@ant-design/icons";
import {
getGuardrailInfo,
updateGuardrailCall,
@ -414,21 +414,35 @@ const GuardrailInfoView: React.FC<GuardrailInfoProps> = ({ guardrailId, onClose,
</Card>
)}
{guardrailData.guardrail_info && Object.keys(guardrailData.guardrail_info).length > 0 && (
<Card className="mt-6">
<Text>Guardrail Info</Text>
<div className="mt-2 space-y-2">
{Object.entries(guardrailData.guardrail_info).map(([key, value]) => (
<div key={key} className="flex">
<Text className="font-medium w-1/3">{key}</Text>
<Text className="w-2/3">
{typeof value === "object" ? JSON.stringify(value, null, 2) : String(value)}
</Text>
{guardrailData.litellm_params?.pii_entities_config &&
Object.keys(guardrailData.litellm_params.pii_entities_config).length > 0 && (
<Card className="mt-6">
<Text className="mb-4 text-lg font-semibold">PII Entity Configuration</Text>
<div className="border rounded-lg overflow-hidden shadow-sm">
<div className="bg-gray-50 px-5 py-3 border-b flex">
<Text className="flex-1 font-semibold text-gray-700">Entity Type</Text>
<Text className="flex-1 font-semibold text-gray-700">Configuration</Text>
</div>
))}
</div>
</Card>
)}
<div className="max-h-[400px] overflow-y-auto">
{Object.entries(guardrailData.litellm_params?.pii_entities_config).map(([key, value]) => (
<div key={key} className="px-5 py-3 flex border-b hover:bg-gray-50 transition-colors">
<Text className="flex-1 font-medium text-gray-900">{key}</Text>
<Text className="flex-1">
<span
className={`inline-flex items-center gap-1.5 ${
value === "MASK" ? "text-blue-600" : "text-red-600"
}`}
>
{value === "MASK" ? <EyeInvisibleOutlined /> : <StopOutlined />}
{String(value)}
</span>
</Text>
</div>
))}
</div>
</div>
</Card>
)}
</TabPanel>
{/* Settings Panel (only for admins) */}