import React, { useState } from "react"; interface RecognitionMetadata { recognizer_name: string; recognizer_identifier: string; } interface GuardrailEntity { end: number; score: number; start: number; entity_type: string; analysis_explanation: string | null; recognition_metadata: RecognitionMetadata; } interface MaskedEntityCount { [key: string]: number; } interface GuardrailInformation { duration: number; end_time: number; start_time: number; guardrail_mode: string; guardrail_name: string; guardrail_status: string; guardrail_response: GuardrailEntity[]; masked_entity_count: MaskedEntityCount; } interface GuardrailViewerProps { data: GuardrailInformation; } export function GuardrailViewer({ data }: GuardrailViewerProps) { const [sectionExpanded, setSectionExpanded] = useState(true); const [entityListExpanded, setEntityListExpanded] = useState(true); const [expandedEntities, setExpandedEntities] = useState>({}); if (!data) { return null; } // Calculate total masked entities const totalMaskedEntities = data.masked_entity_count ? Object.values(data.masked_entity_count).reduce((sum, count) => sum + count, 0) : 0; const formatTime = (timestamp: number): string => { const date = new Date(timestamp * 1000); return date.toLocaleString(); }; const toggleEntity = (index: number) => { setExpandedEntities(prev => ({ ...prev, [index]: !prev[index] })); }; const getScoreColor = (score: number): string => { if (score >= 0.8) return "text-green-600"; return "text-yellow-600"; }; return (
setSectionExpanded(!sectionExpanded)} >

Guardrail Information

{data.guardrail_status} {totalMaskedEntities > 0 && ( {totalMaskedEntities} masked {totalMaskedEntities === 1 ? 'entity' : 'entities'} )}
{sectionExpanded ? 'Click to collapse' : 'Click to expand'}
{sectionExpanded && (
Guardrail Name: {data.guardrail_name}
Mode: {data.guardrail_mode}
Status: {data.guardrail_status}
Start Time: {formatTime(data.start_time)}
End Time: {formatTime(data.end_time)}
Duration: {data.duration.toFixed(4)}s
{/* Masked Entity Summary */} {data.masked_entity_count && Object.keys(data.masked_entity_count).length > 0 && (

Masked Entity Summary

{Object.entries(data.masked_entity_count).map(([entityType, count]) => ( {entityType}: {count} ))}
)}
{/* Detected Entities Section */} {data.guardrail_response && data.guardrail_response.length > 0 && (
setEntityListExpanded(!entityListExpanded)} >

Detected Entities ({data.guardrail_response.length})

{entityListExpanded && (
{data.guardrail_response.map((entity, index) => { const isExpanded = expandedEntities[index] || false; return (
toggleEntity(index)} >
{entity.entity_type} Score: {entity.score.toFixed(2)}
Position: {entity.start}-{entity.end}
{isExpanded && (
Entity Type: {entity.entity_type}
Position: Characters {entity.start}-{entity.end}
Confidence: {entity.score.toFixed(2)}
{entity.recognition_metadata && ( <>
Recognizer: {entity.recognition_metadata.recognizer_name}
Identifier: {entity.recognition_metadata.recognizer_identifier}
)} {entity.analysis_explanation && (
Explanation: {entity.analysis_explanation}
)}
)}
); })}
)}
)}
)}
); }