import React, { useState, useEffect } from 'react'; import { Mail, Search, Sparkles, Database, ShieldCheck, Terminal, AlertCircle } from 'lucide-react'; import { API_BASE_URL } from '@/app/config'; interface AgentLogItem { step: number; thought: string; action: string; result: string; timestamp: string; } interface AgentRunTimelineProps { runId: string; } export default function AgentRunTimeline({ runId }: AgentRunTimelineProps) { const [logs, setLogs] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(false); useEffect(() => { const fetchLogs = async () => { setIsLoading(true); setError(false); const token = localStorage.getItem('token') || ''; try { const response = await fetch(`${API_BASE_URL}/api/agent/runs/${runId}/logs`, { headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { throw new Error('Failed to fetch run logs'); } const data = await response.json(); setLogs(data); } catch (err) { console.error(err); setError(true); } finally { setIsLoading(false); } }; if (runId) { fetchLogs(); // Poll every 3 seconds while active const interval = setInterval(fetchLogs, 3000); return () => clearInterval(interval); } }, [runId]); const getActionIcon = (action: string) => { switch (action.toUpperCase()) { case 'READ_EMAIL': return ; case 'RETRIEVE_CONTEXT': return ; case 'LLM_TRIAGE': return ; case 'COMMIT_CHANGES': return ; default: return ; } }; const getActionColor = (action: string) => { switch (action.toUpperCase()) { case 'READ_EMAIL': return 'border-cyan-500/30 bg-cyan-950/20'; case 'RETRIEVE_CONTEXT': return 'border-indigo-500/30 bg-indigo-950/20'; case 'LLM_TRIAGE': return 'border-purple-500/30 bg-purple-950/20'; case 'COMMIT_CHANGES': return 'border-emerald-500/30 bg-emerald-950/20'; default: return 'border-slate-800 bg-slate-950/40'; } }; if (isLoading && logs.length === 0) { return (
Loading audit trail...
); } if (error && logs.length === 0) { return (
Could not fetch logs for this agent execution.
); } return (

Agent Thinking Audit Trail

{logs.length === 0 ? (

No agent log steps found for this execution run.

) : (
{logs.map((log) => (
{/* Vertical line connector bullet */}
{getActionIcon(log.action)}
{/* Node Contents */}
Step {log.step}: {log.thought} {new Date(log.timestamp).toLocaleTimeString()}
Action: {log.action} {log.result}
))}
)}
); }