import { CheckCircleIcon, ChevronUp, ClipboardListIcon, Loader2Icon, XCircleIcon, } from "lucide-react"; import { useMemo, useState } from "react"; import { Streamdown } from "streamdown"; import { ChainOfThought, ChainOfThoughtContent, ChainOfThoughtStep, } from "@/components/ai-elements/chain-of-thought"; import { Shimmer } from "@/components/ai-elements/shimmer"; import { Button } from "@/components/ui/button"; import { ShineBorder } from "@/components/ui/shine-border"; import { useI18n } from "@/core/i18n/hooks"; import { hasToolCalls } from "@/core/messages/utils"; import { useRehypeSplitWordsIntoSpans } from "@/core/rehype"; import { streamdownPluginsWithWordAnimation } from "@/core/streamdown"; import type { Subtask } from "@/core/tasks"; import { useLatestSubtaskMessage } from "@/core/tasks/context"; import { explainLastToolCall } from "@/core/tools/utils"; import { cn } from "@/lib/utils"; import { CitationLink } from "../citations/citation-link"; import { FlipDisplay } from "../flip-display"; import { MarkdownContent } from "./markdown-content"; export function SubtaskCard({ className, task, isLoading, }: { className?: string; task: Subtask; isLoading: boolean; }) { const { t } = useI18n(); const [collapsed, setCollapsed] = useState(true); const rehypePlugins = useRehypeSplitWordsIntoSpans(isLoading); const latestMessage = useLatestSubtaskMessage(task.id); const mergedTask = useMemo( () => (latestMessage ? { ...task, latestMessage } : task), [latestMessage, task], ); const icon = useMemo(() => { if (mergedTask.status === "completed") { return ; } else if (mergedTask.status === "failed") { return ; } else if (mergedTask.status === "in_progress") { return ; } }, [mergedTask.status]); return ( {mergedTask.status === "in_progress" && ( <> > )} setCollapsed(!collapsed)} > {mergedTask.description} ) : ( mergedTask.description ) } icon={} > {collapsed && ( {icon} {mergedTask.status === "in_progress" && mergedTask.latestMessage && hasToolCalls(mergedTask.latestMessage) ? explainLastToolCall(mergedTask.latestMessage, t) : t.subtasks[mergedTask.status]} )} {mergedTask.prompt && ( {mergedTask.prompt} } > )} {mergedTask.status === "in_progress" && mergedTask.latestMessage && hasToolCalls(mergedTask.latestMessage) && ( } > {explainLastToolCall(mergedTask.latestMessage, t)} )} {mergedTask.status === "completed" && ( <> } > ) : null } > > )} {mergedTask.status === "failed" && ( {mergedTask.error}} icon={} > )} ); }