"use client" import { BrainIcon, ChevronDownIcon } from "lucide-react" import type { ReactNode } from "react" import { useEffect, useState } from "react" import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible" import { cn } from "@/lib/utils" export type ReasoningProps = { className?: string isStreaming?: boolean /** Open while streaming, then folds once about a second after it ends */ defaultOpen?: boolean getThinkingMessage: (isStreaming: boolean, duration?: number) => ReactNode children: string } const AUTO_CLOSE_DELAY = 1000 const MS_IN_S = 1000 export function Reasoning({ className, isStreaming = false, defaultOpen = true, getThinkingMessage, children, }: ReasoningProps) { const [isOpen, setIsOpen] = useState(defaultOpen) const [duration, setDuration] = useState() const [hasAutoClosed, setHasAutoClosed] = useState(false) const [startTime, setStartTime] = useState(null) // Track duration when streaming starts and ends useEffect(() => { if (isStreaming) { if (startTime === null) { setStartTime(Date.now()) } } else if (startTime !== null) { setDuration(Math.ceil((Date.now() - startTime) / MS_IN_S)) setStartTime(null) } }, [isStreaming, startTime]) // Auto-close once when streaming ends, after a short delay so the user // sees the content useEffect(() => { if (defaultOpen && !isStreaming && isOpen && !hasAutoClosed) { const timer = setTimeout(() => { setIsOpen(false) setHasAutoClosed(true) }, AUTO_CLOSE_DELAY) return () => clearTimeout(timer) } }, [isStreaming, isOpen, defaultOpen, hasAutoClosed]) return ( {getThinkingMessage(isStreaming, duration)}
{children}
) }