import dayjs from 'dayjs' import duration from 'dayjs/plugin/duration' import relativeTime from 'dayjs/plugin/relativeTime' import { CheckCircle2, ChevronDown, CircleDot, CircleSlash2, MessageSquareText, Trash2, XCircle, } from 'lucide-react' import { type FC, useMemo, useState } from 'react' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible' import type { ExecutionTaskRecord } from '@/lib/execution-history/types' import { cn } from '@/lib/utils' import { ExecutionStepItem } from './ExecutionStepItem' dayjs.extend(relativeTime) dayjs.extend(duration) function getTaskStatusIcon(status: ExecutionTaskRecord['status']) { if (status === 'completed') { return } if (status === 'running') { return } if (status === 'stopped') { return } return } function getTaskStatusLabel(status: ExecutionTaskRecord['status']) { if (status === 'completed') return 'Completed' if (status === 'running') return 'Running' if (status === 'stopped') return 'Stopped' if (status === 'interrupted') return 'Interrupted' return 'Failed' } function formatDuration(task: ExecutionTaskRecord): string | null { if (!task.completedAt) return null const diff = dayjs(task.completedAt).diff(task.startedAt) const parsed = dayjs.duration(diff) const minutes = Math.floor(parsed.asMinutes()) const seconds = parsed.seconds() if (minutes === 0) return `${seconds}s` return `${minutes}m ${seconds}s` } export const ExecutionTaskCard: FC<{ task: ExecutionTaskRecord defaultOpen?: boolean onDelete?: (task: ExecutionTaskRecord) => void }> = ({ task, defaultOpen = false, onDelete }) => { const [open, setOpen] = useState(defaultOpen) const startedAgo = useMemo( () => dayjs(task.startedAt).fromNow(), [task.startedAt], ) return (
{onDelete ? ( ) : null}
{task.steps.length === 0 ? (
No tool actions were recorded for this task.
) : (
{task.steps.map((step, index) => ( ))}
)}
) }