'use client'; import { Brain, Search, FileText, ChevronDown, ChevronUp, BookSearch, } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; import { useEffect, useState } from 'react'; import { ResearchBlock, ResearchBlockSubStep } from '@/lib/types'; import { useChat } from '@/lib/hooks/useChat'; const getStepIcon = (step: ResearchBlockSubStep) => { if (step.type === 'reasoning') { return ; } else if (step.type === 'searching' || step.type === 'upload_searching') { return ; } else if ( step.type === 'search_results' || step.type === 'upload_search_results' ) { return ; } else if (step.type === 'reading') { return ; } return null; }; const getStepTitle = ( step: ResearchBlockSubStep, isStreaming: boolean, ): string => { if (step.type === 'reasoning') { return isStreaming && !step.reasoning ? 'Thinking...' : 'Thinking'; } else if (step.type === 'searching') { return `Searching ${step.searching.length} ${step.searching.length === 1 ? 'query' : 'queries'}`; } else if (step.type === 'search_results') { return `Found ${step.reading.length} ${step.reading.length === 1 ? 'result' : 'results'}`; } else if (step.type === 'reading') { return `Reading ${step.reading.length} ${step.reading.length === 1 ? 'source' : 'sources'}`; } else if (step.type === 'upload_searching') { return 'Scanning your uploaded documents'; } else if (step.type === 'upload_search_results') { return `Reading ${step.results.length} ${step.results.length === 1 ? 'document' : 'documents'}`; } return 'Processing'; }; const AssistantSteps = ({ block, status, }: { block: ResearchBlock; status: 'answering' | 'completed' | 'error'; }) => { const [isExpanded, setIsExpanded] = useState(true); const { researchEnded, loading } = useChat(); useEffect(() => { if (researchEnded) { setIsExpanded(false); } else if (status === 'answering') { setIsExpanded(true); } }, [researchEnded, status]); if (!block || block.data.subSteps.length === 0) return null; return (
{isExpanded && (
{block.data.subSteps.map((step, index) => { const isLastStep = index === block.data.subSteps.length - 1; const isStreaming = loading && isLastStep && !researchEnded; return (
{getStepIcon(step)}
{index < block.data.subSteps.length - 1 && (
)}
{getStepTitle(step, isStreaming)} {step.type === 'reasoning' && ( <> {step.reasoning && (

{step.reasoning}

)} {isStreaming && !step.reasoning && (
)} )} {step.type === 'searching' && step.searching.length > 0 && (
{step.searching.map((query, idx) => ( {query} ))}
)} {(step.type === 'search_results' || step.type === 'reading') && step.reading.length > 0 && (
{step.reading.slice(0, 4).map((result, idx) => { const url = result.metadata.url || ''; const title = result.metadata.title || 'Untitled'; const domain = url ? new URL(url).hostname : ''; const faviconUrl = domain ? `https://s2.googleusercontent.com/s2/favicons?domain=${domain}&sz=128` : ''; return ( {faviconUrl && ( { e.currentTarget.style.display = 'none'; }} /> )} {title} ); })}
)} {step.type === 'upload_searching' && step.queries.length > 0 && (
{step.queries.map((query, idx) => ( {query} ))}
)} {step.type === 'upload_search_results' && step.results.length > 0 && (
{step.results.slice(0, 4).map((result, idx) => { const title = (result.metadata && (result.metadata.title || result.metadata.fileName)) || 'Untitled document'; const snippet = (result.content || '') .replace(/\s+/g, ' ') .trim() .slice(0, 220); return (
{title}
{snippet || 'No preview available.'}
); })}
)}
); })}
)}
); }; export default AssistantSteps;