/** * Thinking Process Component * * Displays the agent's reasoning path including: * - Step-by-step reasoning (Claude, o1 style) * - Tool execution visualization * - Re-ranking progress * - HyDE query expansion * - Knowledge base indicators */ "use client" import { useState } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { ScrollArea } from "@/components/ui/scroll-area" import { Progress } from "@/components/ui/progress" import { ChevronDown, ChevronRight, Brain, Check, Clock, Search, Lightbulb, AlertCircle, TrendingUp, Eye, Layers, Zap, Database, RefreshCw, Filter, Sparkles, FileText, Scale, Newspaper } from "lucide-react" import { cn } from "@/lib/utils" // Enhanced Types interface ToolExecution { name: string status: 'pending' | 'running' | 'completed' | 'error' input?: Record output?: unknown duration_ms?: number } interface RetrievalStep { namespace: string docs_retrieved: number docs_after_rerank?: number used_hyde?: boolean query_expanded?: string } interface ThoughtStep { step: number action: string observation: string reasoning: string duration_ms?: number confidence?: number tool_executions?: ToolExecution[] retrieval?: RetrievalStep } interface ReasoningPath { query: string thoughts: ThoughtStep[] total_duration_ms: number final_conclusion: string knowledge_bases_used?: string[] used_reranking?: boolean used_hyde?: boolean model_used?: string } interface ThinkingProcessProps { reasoning: ReasoningPath | string className?: string defaultExpanded?: boolean showEnhancements?: boolean } export function ThinkingProcess({ reasoning, className, defaultExpanded = false }: ThinkingProcessProps) { const [isExpanded, setIsExpanded] = useState(defaultExpanded) const [expandedSteps, setExpandedSteps] = useState>(new Set()) // Handle string reasoning (new format) if (typeof reasoning === 'string') { return ( setIsExpanded(!isExpanded)} >
Thinking Process
Analysis {isExpanded ? ( ) : ( )}
{isExpanded && (
{reasoning}
)}
) } // Handle structured reasoning (legacy/future format) const toggleStep = (step: number) => { const newExpanded = new Set(expandedSteps) if (newExpanded.has(step)) { newExpanded.delete(step) } else { newExpanded.add(step) } setExpandedSteps(newExpanded) } const toggleAll = () => { if (isExpanded) { setIsExpanded(false) setExpandedSteps(new Set()) } else { setIsExpanded(true) setExpandedSteps(new Set(reasoning.thoughts.map(t => t.step))) } } return (
Thinking Process
{reasoning.thoughts.length} steps {reasoning.total_duration_ms}ms {isExpanded ? ( ) : ( )}
Step-by-step reasoning for: {reasoning.query}
{isExpanded && (
{/* Timeline line */}
{reasoning.thoughts.map((thought, idx) => ( toggleStep(thought.step)} isLast={idx === reasoning.thoughts.length - 1} /> ))} {/* Final Conclusion */}

Conclusion

{reasoning.final_conclusion}

)} ) } // Individual Thought Step Card function ThoughtStepCard({ thought, isExpanded, onToggle, isLast }: { thought: ThoughtStep isExpanded: boolean onToggle: () => void isLast: boolean }) { const getActionIcon = (action: string) => { const actionLower = action.toLowerCase() if (actionLower.includes("search") || actionLower.includes("retriev")) { return } if (actionLower.includes("analyz") || actionLower.includes("check")) { return } if (actionLower.includes("reason") || actionLower.includes("think")) { return } if (actionLower.includes("synthesiz") || actionLower.includes("combin")) { return } return } return (
{/* Step number bubble */}
{thought.step}
{/* Step card */}
{/* Header */}
{getActionIcon(thought.action)} {thought.action}
{thought.duration_ms && ( {thought.duration_ms}ms )} {thought.confidence !== undefined && ( = 0.8 ? "default" : "secondary"} className="text-xs font-mono" > {(thought.confidence * 100).toFixed(0)}% )} {isExpanded ? ( ) : ( )}
{/* Expanded content */} {isExpanded && (
{/* Observation */}
Observation

{thought.observation}

{/* Reasoning */}
Reasoning

{thought.reasoning}

)}
) } // Compact version for inline display export function ThinkingProcessCompact({ reasoning }: { reasoning: ReasoningPath }) { const [isExpanded, setIsExpanded] = useState(false) return (
{isExpanded && (
{reasoning.thoughts.map((thought) => (
{thought.step}. {thought.action}

{thought.observation}

))}
)}
) } // Loading skeleton export function ThinkingProcessSkeleton() { return (
Thinking...
Processing
{[1, 2, 3].map((i) => (
))}
) } export default ThinkingProcess