import { useState } from "react"; import { cn } from "~/lib/utils"; import { ChevronDown, ChevronRight, Brain, Search, FileText, Lightbulb, CheckCircle, Loader2 } from "lucide-react"; export type ThinkingStepType = "thinking" | "searching" | "reading" | "analyzing" | "complete"; export interface ThinkingStep { /** Step ID */ id: string; /** Step type for icon selection */ type: ThinkingStepType; /** Step title/label */ title: string; /** Step description or content */ content?: string; /** Whether step is currently active */ isActive?: boolean; /** Whether step is complete */ isComplete?: boolean; /** Timestamp */ timestamp?: Date; } export interface ThinkingStepsDisplayProps { /** List of thinking steps */ steps: ThinkingStep[]; /** Whether AI is currently thinking */ isThinking?: boolean; /** Whether to show expanded by default */ defaultExpanded?: boolean; /** Additional class names */ className?: string; } const STEP_ICONS: Record = { thinking: Brain, searching: Search, reading: FileText, analyzing: Lightbulb, complete: CheckCircle, }; const STEP_COLORS: Record = { thinking: "text-purple-500", searching: "text-blue-500", reading: "text-green-500", analyzing: "text-orange-500", complete: "text-green-600", }; /** * ThinkingStepsDisplay - Shows AI reasoning process * * Features: * - Collapsible thinking steps * - Step-specific icons and colors * - Active step animation * - Expandable step details */ export function ThinkingStepsDisplay({ steps, isThinking = false, defaultExpanded = true, className, }: ThinkingStepsDisplayProps) { const [isExpanded, setIsExpanded] = useState(defaultExpanded); if (steps.length === 0 && !isThinking) { return null; } const activeStep = steps.find(s => s.isActive); const completedSteps = steps.filter(s => s.isComplete).length; return (
{/* Header - clickable to expand/collapse */} {/* Steps list */} {isExpanded && (
{steps.map((step, index) => ( ))} {/* Active thinking indicator */} {isThinking && !activeStep && (
Processing...
)}
)}
); } /** * Individual step item */ function StepItem({ step, index }: { step: ThinkingStep; index: number }) { const [isDetailExpanded, setIsDetailExpanded] = useState(false); const Icon = STEP_ICONS[step.type]; const colorClass = STEP_COLORS[step.type]; return (
step.content && setIsDetailExpanded(!isDetailExpanded)} > {/* Step number or icon */}
{step.isActive ? ( ) : step.isComplete ? ( ) : ( )}
{/* Step content */}

{step.title}

{/* Expandable detail */} {step.content && isDetailExpanded && (

{step.content}

)}
{/* Expand indicator */} {step.content && ( )}
); }