import StepTimeline from './StepTimeline' import ScoreCard from './ScoreCard' import { generateReasoning, getRegionalComparison } from '../utils' const DECISION_STYLE = { remove: { color: '#f87171', glow: 'glow-red', border: 'rgba(248,113,113,0.25)', bg: 'rgba(248,113,113,0.05)' }, allow: { color: '#4ade80', glow: 'glow-green', border: 'rgba(74,222,128,0.25)', bg: 'rgba(74,222,128,0.05)' }, flag: { color: '#fb923c', glow: 'glow-orange', border: 'rgba(251,146,60,0.25)', bg: 'rgba(251,146,60,0.05)' }, escalate: { color: '#c084fc', glow: 'glow-purple', border: 'rgba(192,132,252,0.25)', bg: 'rgba(192,132,252,0.05)' }, } const SEVERITY_COLOR = { critical: '#f87171', high: '#fb923c', medium: '#fbbf24', low: '#60a5fa', } const VIOLATION_COLOR = { harassment: '#f87171', misinformation: '#fb923c', restricted: '#fbbf24', safe: '#4ade80', } const REGION_LABELS = { US: '🇺🇸 US', EU: '🇪🇺 EU', IN: '🇮🇳 IN', UK: '🇬🇧 UK' } const REGION_ORDER = ['US', 'EU', 'IN', 'UK'] function SectionLabel({ children }) { return (
{children}
) } function Chip({ label, color }) { return ( {label} ) } function ActionPill({ action }) { const ds = DECISION_STYLE[action] || { color: '#5a5f7a', border: 'rgba(90,95,122,0.3)', bg: 'transparent' } return ( {action} ) } function LoadingSkeleton({ llmProvider }) { const modelName = llmProvider === 'gemini' ? 'Gemini 2.5 Flash' : (llmProvider === 'openai' ? 'OpenAI GPT-4o mini' : 'Agent') return (
{[1, 0.85, 0.7, 0.55, 0.4].map((op, i) => (
))}
â—Ž   {modelName} reasoning...
) } export default function AgentPanel({ result, observation, loading, error, animKey, llmProvider }) { const breakdown = result?.score?.breakdown if (loading) return (
Output
Agent Analyzing
) if (error) return (
Output
Error
{error}
) if (!result) return (
Output
Agent Analysis
◌
Select a scenario and run the AI agent to see its reasoning and decision
) const action = breakdown?.agent_action const expected = breakdown?.expected_action const isCorrect = action === expected const ds = DECISION_STYLE[action] || { color: '#5a5f7a', glow: '', border: 'rgba(90,95,122,0.2)', bg: 'transparent' } const sevColor = SEVERITY_COLOR[breakdown?.final_severity] || '#5a5f7a' const vioColor = VIOLATION_COLOR[breakdown?.violation_type] || '#5a5f7a' const reasoning = generateReasoning(breakdown, result.trajectory) const regional = getRegionalComparison(breakdown?.violation_type, breakdown?.final_severity) const currentGeo = observation?.geo || null return (
{/* Header */}
Output
Agent Analysis
{result.trajectory?.length} step{result.trajectory?.length !== 1 ? 's' : ''}
{/* ── 1. DECISION CARD ──────────────────────────── */}
{/* Giant decision word */}
Final Decision
{action?.toUpperCase() ?? 'NO DECISION'}
{/* Expected vs actual */}
Agent: {isCorrect ? '✓' : '✗'}
{!isCorrect && (
Expected:
)}
{/* Chips */}
{breakdown?.violation_type && } {breakdown?.final_severity && }
{/* Reasoning explanation */}
Reasoning

“{reasoning}”

{/* ── 2. REGION COMPARISON ─────────────────────── */}
Policy Comparison by Region
{REGION_ORDER.map(geo => { const decision = regional[geo] || 'allow' const dStyle = DECISION_STYLE[decision] || { color: '#5a5f7a', border: 'rgba(90,95,122,0.2)', bg: 'transparent' } const isCurrent = geo === currentGeo return (
{REGION_LABELS[geo]}
{decision}
{isCurrent && (
current
)}
) })}
{/* ── 3. TRAJECTORY ────────────────────────────── */}
Agent Trajectory
{/* ── 4. SCORE BREAKDOWN ───────────────────────── */}
Performance Breakdown
) }