helloya20's picture
Upload 2345 files
f0743f4 verified
import { useMemo } from 'react';
import type { TAttachment } from 'librechat-data-provider';
import { StackedFavicons } from '~/components/Web/Sources';
import { useSearchContext } from '~/Providers';
import ProgressText from './ProgressText';
import { useLocalize } from '~/hooks';
type ProgressKeys =
| 'com_ui_web_searching'
| 'com_ui_web_searching_again'
| 'com_ui_web_search_processing'
| 'com_ui_web_search_reading';
export default function WebSearch({
initialProgress: progress = 0.1,
isSubmitting,
isLast,
output,
}: {
isLast?: boolean;
isSubmitting: boolean;
output?: string | null;
initialProgress: number;
attachments?: TAttachment[];
}) {
const localize = useLocalize();
const { searchResults } = useSearchContext();
const error = typeof output === 'string' && output.toLowerCase().includes('error processing');
const cancelled = (!isSubmitting && progress < 1) || error === true;
const complete = !isLast && progress === 1;
const finalizing = isSubmitting && isLast && progress === 1;
const processedSources = useMemo(() => {
if (complete && !finalizing) {
return [];
}
if (!searchResults) return [];
const values = Object.values(searchResults);
const result = values[values.length - 1];
if (!result) return [];
if (finalizing) {
return [...(result.organic || []), ...(result.topStories || [])];
}
return [...(result.organic || []), ...(result.topStories || [])].filter(
(source) => source.processed === true,
);
}, [searchResults, complete, finalizing]);
const turns = useMemo(() => {
if (!searchResults) return 0;
return Object.values(searchResults).length;
}, [searchResults]);
const clampedProgress = useMemo(() => {
return Math.min(progress, 0.99);
}, [progress]);
const showSources = processedSources.length > 0;
const progressText = useMemo(() => {
let text: ProgressKeys = turns > 1 ? 'com_ui_web_searching_again' : 'com_ui_web_searching';
if (showSources) {
text = 'com_ui_web_search_processing';
}
if (finalizing) {
text = 'com_ui_web_search_reading';
}
return localize(text);
}, [turns, localize, showSources, finalizing]);
if (complete || cancelled) {
return null;
}
return (
<>
<div className="relative my-2.5 flex size-5 shrink-0 items-center gap-2.5">
{showSources && (
<div className="mr-2">
<StackedFavicons sources={processedSources} start={-5} />
</div>
)}
<ProgressText
finishedText=""
hasInput={false}
error={cancelled}
isExpanded={false}
progress={clampedProgress}
inProgressText={progressText}
/>
</div>
</>
);
}