({
input,
result,
isError = false,
isRunning = false,
startedAt,
completedAt,
}: ToolWebSearchProps)
| 41 | } |
| 42 | |
| 43 | export function ToolWebSearch({ |
| 44 | input, |
| 45 | result, |
| 46 | isError = false, |
| 47 | isRunning = false, |
| 48 | startedAt, |
| 49 | completedAt, |
| 50 | }: ToolWebSearchProps) { |
| 51 | const results = result && !isError ? parseSearchResults(result) : []; |
| 52 | |
| 53 | return ( |
| 54 | <ToolUseBlock |
| 55 | toolName="websearch" |
| 56 | toolInput={input} |
| 57 | toolResult={result} |
| 58 | isError={isError} |
| 59 | isRunning={isRunning} |
| 60 | startedAt={startedAt} |
| 61 | completedAt={completedAt} |
| 62 | > |
| 63 | {/* Query header */} |
| 64 | <div className="flex items-center gap-2 px-3 py-2 bg-surface-850 border-b border-surface-700/50"> |
| 65 | <Search className="w-3.5 h-3.5 text-surface-500 flex-shrink-0" /> |
| 66 | <span className="text-sm text-surface-200 flex-1">{input.query}</span> |
| 67 | {!isRunning && results.length > 0 && ( |
| 68 | <span className="text-xs text-surface-500"> |
| 69 | {results.length} result{results.length !== 1 ? "s" : ""} |
| 70 | </span> |
| 71 | )} |
| 72 | </div> |
| 73 | |
| 74 | {/* Results */} |
| 75 | {isRunning ? ( |
| 76 | <div className="px-3 py-4 text-surface-500 text-xs animate-pulse"> |
| 77 | Searching… |
| 78 | </div> |
| 79 | ) : isError ? ( |
| 80 | <div className="px-3 py-3 text-red-400 text-xs font-mono">{result}</div> |
| 81 | ) : results.length === 0 ? ( |
| 82 | <div className="px-3 py-3 text-surface-500 text-xs">No results.</div> |
| 83 | ) : ( |
| 84 | <div className="overflow-auto max-h-[480px] divide-y divide-surface-700/40"> |
| 85 | {results.map((r, i) => ( |
| 86 | <div key={i} className="px-3 py-3 hover:bg-surface-800/30 transition-colors"> |
| 87 | {r.url ? ( |
| 88 | <a |
| 89 | href={r.url} |
| 90 | target="_blank" |
| 91 | rel="noopener noreferrer" |
| 92 | className="group flex flex-col gap-1" |
| 93 | > |
| 94 | <div className="flex items-center gap-1"> |
| 95 | <span className="text-sm font-medium text-brand-400 group-hover:text-brand-300 group-hover:underline"> |
| 96 | {r.title} |
| 97 | </span> |
| 98 | <ExternalLink className="w-3 h-3 text-surface-500 flex-shrink-0" /> |
| 99 | </div> |
| 100 | <span className="text-xs text-surface-500 truncate">{r.url}</span> |
nothing calls this directly
no test coverage detected