/** * Agent Panel Component * * Displays a list of active agents on the project with their status and current task. */ 'use client'; import { Bot, MoreVertical } from 'lucide-react'; import { formatDistanceToNow } from 'date-fns'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Skeleton } from '@/components/ui/skeleton'; import { AgentStatusIndicator } from './AgentStatusIndicator'; import type { AgentInstance } from './types'; // ============================================================================ // Types // ============================================================================ interface AgentPanelProps { /** List of agent instances */ agents: AgentInstance[]; /** Whether data is loading */ isLoading?: boolean; /** Callback when "Manage Agents" is clicked */ onManageAgents?: () => void; /** Callback when an agent action is triggered */ onAgentAction?: (agentId: string, action: 'view' | 'pause' | 'restart' | 'terminate') => void; /** Additional CSS classes */ className?: string; } // ============================================================================ // Helper Functions // ============================================================================ function getAgentAvatarText(agent: AgentInstance): string { if (agent.avatar) return agent.avatar; // Generate initials from role const words = agent.role.split(/[\s_-]+/); if (words.length >= 2) { return (words[0][0] + words[1][0]).toUpperCase(); } /* istanbul ignore next -- fallback for single-word roles */ return agent.role.substring(0, 2).toUpperCase(); } function formatLastActivity(lastActivity?: string): string { if (!lastActivity) return 'No activity'; try { return formatDistanceToNow(new Date(lastActivity), { addSuffix: true }); } catch { /* istanbul ignore next -- defensive catch for invalid date strings */ return 'Unknown'; } } // ============================================================================ // Subcomponents // ============================================================================ function AgentListItem({ agent, onAction, }: { agent: AgentInstance; onAction?: (agentId: string, action: 'view' | 'pause' | 'restart' | 'terminate') => void; }) { const avatarText = getAgentAvatarText(agent); const lastActivity = formatLastActivity(agent.last_activity_at); return (
{agent.current_task || 'No active task'}
No agents assigned to this project