import React, { useState } from "react"; import { motion } from "framer-motion"; import { Play, Clock, Hash, Bot } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Pagination } from "@/components/ui/pagination"; import { cn } from "@/lib/utils"; import { formatISOTimestamp } from "@/lib/date-utils"; import type { AgentRunWithMetrics } from "@/lib/api"; import { AGENT_ICONS } from "./CCAgents"; interface AgentRunsListProps { /** * Array of agent runs to display */ runs: AgentRunWithMetrics[]; /** * Callback when a run is clicked */ onRunClick?: (run: AgentRunWithMetrics) => void; /** * Optional className for styling */ className?: string; } const ITEMS_PER_PAGE = 5; /** * AgentRunsList component - Displays a paginated list of agent execution runs * * @example * console.log('Selected:', run)} * /> */ export const AgentRunsList: React.FC = ({ runs, onRunClick, className, }) => { const [currentPage, setCurrentPage] = useState(1); // Calculate pagination const totalPages = Math.ceil(runs.length / ITEMS_PER_PAGE); const startIndex = (currentPage - 1) * ITEMS_PER_PAGE; const endIndex = startIndex + ITEMS_PER_PAGE; const currentRuns = runs.slice(startIndex, endIndex); // Reset to page 1 if runs change React.useEffect(() => { setCurrentPage(1); }, [runs.length]); const renderIcon = (iconName: string) => { const Icon = AGENT_ICONS[iconName as keyof typeof AGENT_ICONS] || Bot; return ; }; const formatDuration = (ms?: number) => { if (!ms) return "N/A"; const seconds = Math.floor(ms / 1000); if (seconds < 60) return `${seconds}s`; const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}m ${remainingSeconds}s`; }; const formatTokens = (tokens?: number) => { if (!tokens) return "0"; if (tokens >= 1000) { return `${(tokens / 1000).toFixed(1)}k`; } return tokens.toString(); }; if (runs.length === 0) { return (

No execution history yet

); } return (
{currentRuns.map((run, index) => ( onRunClick?.(run)} >
{renderIcon(run.agent_icon)}

{run.task}

{run.model === 'opus' ? 'Claude 4 Opus' : 'Claude 4 Sonnet'}
by {run.agent_name} {run.completed_at && ( <>
{formatDuration(run.metrics?.duration_ms)}
)} {run.metrics?.total_tokens && ( <>
{formatTokens(run.metrics?.total_tokens)}
)} {run.metrics?.cost_usd && ( <> ${run.metrics?.cost_usd?.toFixed(4)} )}

{formatISOTimestamp(run.created_at)}

{!run.completed_at && ( Running )}
))}
{totalPages > 1 && ( )}
); };