import { useEffect } from 'react' import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ReferenceLine, } from 'recharts' import { TrendingUp, Loader2, RefreshCw } from 'lucide-react' import { useStore } from '../store/useStore' import { fetchRLState } from '../lib/api' const CustomTooltip = ({ active, payload, label, }: { active?: boolean payload?: { value: number; name: string; color: string }[] label?: string | number }) => { if (active && payload?.length) { return (

#{label}

{payload.map((p) => (

{p.name}: {p.value}

))}
) } return null } export function PerformanceGraph() { const { rlState, setRlState } = useStore() const load = async () => { try { const data = await fetchRLState() setRlState(data) } catch { // noop — backend might not be up } } useEffect(() => { void load() const interval = setInterval(() => void load(), 10_000) return () => clearInterval(interval) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) if (!rlState) { return (

RL metrics appear after agent episodes

) } const totalEpisodes: number = rlState.totalEpisodes ?? 0 const successRate: number = rlState.successRate ?? 0 const currentAlpha: number = rlState.currentAlpha ?? 0 const episodes: { episode: number; totalReward: number; successRate: number }[] = Array.isArray(rlState.episodes) ? rlState.episodes : [] const actionDistribution: { action: string; count: number }[] = Array.isArray(rlState.actionDistribution) ? rlState.actionDistribution : [] return (
{/* Stats row */}
{[ { label: 'Episodes', value: totalEpisodes, color: 'text-blue-400' }, { label: 'Success', value: `${(successRate * 100).toFixed(0)}%`, color: 'text-green-400' }, { label: 'Alpha', value: currentAlpha.toFixed(3), color: 'text-orange-400' }, ].map((s) => (
{s.value}
{s.label}
))}
{/* Reward per episode */} {episodes.length > 0 && (
Reward per Episode
} />
)} {/* Action distribution */} {actionDistribution.length > 0 && (
LinUCB Action Distribution
v.replace('FIX_', '').slice(0, 6)} /> } />
)} {/* Success rate line */} {episodes.length >= 3 && (
Rolling Success Rate
} />
)}
) }