import Drawer from '@mui/material/Drawer'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; import Divider from '@mui/material/Divider'; import IconButton from '@mui/material/IconButton'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import { Sparkles, X } from 'lucide-react'; import type { CopilotExplainRequest, EvaluationRecord, RareEvent } from '../../types/labeleval'; import { StatusChip, GateLineList, fmtNum, fmtPct, HBar } from './shared'; function MetricRow({ label, value }: { label: string; value: string }) { return ( {label} {value} ); } export function evidenceCopilotRequest(record: EvaluationRecord): CopilotExplainRequest { const primary = record.decision?.primary_failure_reason ?? null; let contextType: CopilotExplainRequest['context_type'] = 'general'; if (record.anomaly.is_anomaly) contextType = 'anomaly'; if (primary === 'GRADER_DISAGREEMENT') contextType = 'disagreement'; if (primary === 'MODEL_REGRESSION') contextType = 'regression'; return { context_type: contextType, annotation_id: record.annotation_id, model_version: record.model_version, }; } export default function EvidencePanel({ open, onClose, record, event, onAskCopilot, }: { open: boolean; onClose: () => void; record?: EvaluationRecord | null; event?: RareEvent | null; onAskCopilot: (request: CopilotExplainRequest) => void; }) { return ( Evidence {record ? ( <> {record.decision ? : null} Frame {record.frame_id} · Dataset {record.dataset_id} · Detection confidence{' '} {fmtNum(record.detection.confidence)} {record.ground_truth_type ? ` · GT: ${record.ground_truth_type}` : ' · No ground truth reference'} Geometry
Anomaly ensemble — {record.anomaly.ensemble_strategy.replace(/_/g, ' ')} · threshold{' '} {fmtNum(record.anomaly.decision_threshold)} Score {fmtNum(record.anomaly.score)} {Object.entries(record.anomaly.detector_scores).map(([name, score]) => ( ))} Grading ({record.grading.grader_count} graders)
{record.grading.disagreement_types.length > 0 ? ( {record.grading.disagreement_types.map((d) => ( ))} ) : null} Tracking ID switch: {record.tracking.id_switch ? 'yes' : 'no'} · Fragmentation:{' '} {record.tracking.fragmentation ? 'yes' : 'no'} · Track quality: {fmtNum(record.tracking.track_quality)} Quality gates {record.validation.passed ? '— PASSED' : '— FAILED'} {record.decision ? ( <> Triage decision — policy {record.decision.policy_id} {record.decision.primary_failure_reason ? ( Primary failure: {record.decision.primary_failure_reason.replace(/_/g, ' ')} ) : null} ) : null} {record.injected_errors.length > 0 ? ( <> Synthetic injected defects (demo transparency): {record.injected_errors.join(', ')} ) : null} ) : null} {event ? ( <> {event.verified ? : null} {event.description}
Evidence frames ({event.evidence_frames.length}) {event.evidence_frames.map((f) => ( ))} {Object.keys(event.sensor_evidence).length > 0 ? ( <> Sensor evidence {Object.entries(event.sensor_evidence).map(([sensor, note]) => ( ))}
) : null} ) : null} {!record && !event ? ( No evidence selected. ) : null}
); }