'use client'; import { useEffect, useState } from 'react'; import { Activity, CheckCircle2, XCircle, Clock, RotateCcw } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { DispatchPanel } from '@/components/agents/dispatch-panel'; interface Agent { id: string; name: string; avatar?: string; description?: string; permission_tier: string; status: 'active' | 'disabled'; last_activity_at?: string; } interface AgentActivity { id: string; agent_id: string; action: string; entity_type: string; entity_id: string; before_state?: Record; after_state?: Record; created: string; } interface AgentTask { id: string; agent_id: string; task_type: string; input: string; status: 'pending' | 'in_progress' | 'completed' | 'failed'; output?: Record; created: string; } export default function AgentsPage() { const [agents, setAgents] = useState([]); const [activity, setActivity] = useState([]); const [agentTasks, setAgentTasks] = useState([]); const [agentsLoading, setAgentsLoading] = useState(true); const [activityLoading, setActivityLoading] = useState(true); const [agentTasksLoading, setAgentTasksLoading] = useState(true); const [agentsError, setAgentsError] = useState(null); const [activityError, setActivityError] = useState(null); const [agentTasksError, setAgentTasksError] = useState(null); const [undoingActivityId, setUndoingActivityId] = useState(null); const [feedback, setFeedback] = useState<{ type: 'success' | 'error'; message: string } | null>(null); const [selectedAgent, setSelectedAgent] = useState(null); useEffect(() => { fetchAgents(); fetchActivity(); fetchAgentTasks(); }, []); async function fetchAgents() { setAgentsLoading(true); setAgentsError(null); try { const response = await fetch('/api/agents'); if (!response.ok) { throw new Error('Unable to load agents.'); } const data = await response.json(); setAgents(data.items || []); } catch (error) { console.error('Failed to fetch agents:', error); setAgentsError('Unable to load agents. Please try again.'); } finally { setAgentsLoading(false); } } async function fetchActivity() { setActivityLoading(true); setActivityError(null); try { const response = await fetch('/api/agent-activity?sort=-created&perPage=50'); if (!response.ok) { throw new Error('Unable to load agent activity.'); } const data = await response.json(); setActivity(data.items || []); } catch (error) { console.error('Failed to fetch activity:', error); setActivityError('Unable to load agent activity. Please try again.'); } finally { setActivityLoading(false); } } async function fetchAgentTasks() { setAgentTasksLoading(true); setAgentTasksError(null); try { const response = await fetch('/api/agent-tasks?sort=-created&perPage=50'); if (!response.ok) { throw new Error('Unable to load agent tasks.'); } const data = await response.json(); setAgentTasks(data.items || []); } catch (error) { console.error('Failed to fetch agent tasks:', error); setAgentTasksError('Unable to load agent tasks. Please try again.'); } finally { setAgentTasksLoading(false); } } async function undoActivity(activityId: string) { setUndoingActivityId(activityId); setFeedback(null); try { const response = await fetch(`/api/agent-activity/${activityId}/undo`, { method: 'POST', }); if (!response.ok) { throw new Error('Unable to undo this activity.'); } setFeedback({ type: 'success', message: 'Activity undone successfully.' }); await fetchActivity(); } catch (error) { console.error('Failed to undo activity:', error); setFeedback({ type: 'error', message: 'Unable to undo this activity. Please try again.' }); } finally { setUndoingActivityId(null); } } function getAgentName(agentId: string): string { const agent = agents.find((a) => a.id === agentId); return agent?.name || 'Unknown Agent'; } function getStatusIcon(status: string) { switch (status) { case 'completed': return ; case 'failed': return ; case 'in_progress': return ; default: return ; } } function getActionLabel(action: string): string { const labels: Record = { create: 'Created', update: 'Updated', delete: 'Deleted', complete: 'Completed', assign: 'Assigned', }; return labels[action] || action; } return (

Agent Activity

Every agent action, visible and reversible.

{feedback && (

{feedback.message}

)}
{/* Agents list */} Agents {agentsLoading ? (

Loading agents...

) : agentsError ? (

{agentsError}

) : agents.length === 0 ? (

No agents configured

) : (
{agents.map((agent) => ( ))}
)}
{/* Activity feed */} Activity Tasks {activityLoading ? (

Loading agent activity...

) : activityError ? (

{activityError}

) : activity.length === 0 ? (

No agent activity yet

) : (
{activity.map((item) => (
{getAgentName(item.agent_id).charAt(0).toUpperCase()}
{getAgentName(item.agent_id)} {getActionLabel(item.action)} {item.entity_type}

{new Date(item.created).toLocaleString()}

{item.before_state && item.after_state && (
View changes

Before

                                        {JSON.stringify(item.before_state, null, 2)}
                                      

After

                                        {JSON.stringify(item.after_state, null, 2)}
                                      
)}
))}
)}
{agentTasksLoading ? (

Loading agent tasks...

) : agentTasksError ? (

{agentTasksError}

) : agentTasks.length === 0 ? (

No agent tasks yet

) : (
{agentTasks.map((task) => (
{getStatusIcon(task.status)}
{getAgentName(task.agent_id)} {task.status}

{task.input}

{new Date(task.created).toLocaleString()}

{task.output && (
View output
                                  {JSON.stringify(task.output, null, 2)}
                                
)}
))}
)}
); }