import React, { useMemo } from 'react'; import { Text } from 'react-native'; import { Search } from 'lucide-react-native'; import { flattenToolCall } from '../../features/conversation/agentPhase'; import type { SuperagentToolRendererProps } from '../../types'; import { ToolWidgetRow } from '../primitives/ToolWidgetRow'; import { toolWidgetStyles } from '../primitives/toolWidgetStyles'; import { getGrepPattern, isGrepCallDone, parseGrepCounts, pluralize, truncateDisplayText, } from '../searchWidgetUtils'; /** * grep — native port of the web GrepSearch card. A run of consecutive grep * calls (grouped by createToolChunks) renders as ONE card, with the totals * summed across the whole batch. */ export function GrepSearchWidget({ message, toolCall }: SuperagentToolRendererProps) { const calls = useMemo(() => flattenToolCall(toolCall), [toolCall]); // The search is done when the AI already responded with text after the tools, // or every call has a terminal status / populated results (web parity — the // status can lag behind the streamed payload). const messageHasContent = Boolean(message.content?.trim()); const allDone = messageHasContent || (calls.length > 0 && calls.every(isGrepCallDone)); const anyFailed = calls.some((call) => call.status === 'error' || call.status === 'failed'); const status = !allDone ? 'running' : anyFailed ? 'error' : 'success'; const activeCall = calls.find((call) => !isGrepCallDone(call)); const currentPattern = getGrepPattern(activeCall ?? calls[0] ?? toolCall); const hasAnyResults = calls.some((call) => call.results != null); const totals = useMemo(() => { if (!hasAnyResults) return null; return calls.reduce( (acc, call) => { const counts = parseGrepCounts(call.results); return { matchCount: acc.matchCount + counts.matchCount, fileCount: acc.fileCount + counts.fileCount }; }, { matchCount: 0, fileCount: 0 }, ); }, [calls, hasAnyResults]); const showTotals = allDone && totals !== null; return ( {showTotals ? ( {`Found ${pluralize(totals.matchCount, 'result')} in ${pluralize(totals.fileCount, 'file')}`} ) : null} ); }