import { Clock3, Globe, Search, Sparkles, } from 'lucide-react' import { ScrollArea } from '@/components/ui/scroll-area' import { cn } from '@/utils/cn' export interface WebSearchItem { url?: string title?: string snippet?: string date?: string position?: number [key: string]: unknown } export interface WebSearchPreviewProps { /** 搜索结果列表(通常来自 info_search_web 的 tool_output) */ results?: unknown /** 查询词,优先来自 tool_input.arguments[0] */ searchQuery?: string | null className?: string } function normalizeResults(results: unknown): WebSearchItem[] { if (!Array.isArray(results)) return [] return results .filter(item => item && typeof item === 'object') .map(item => item as WebSearchItem) .filter(item => typeof item.url === 'string' && !!item.url) } function getHostText(url?: string): string { if (!url) return 'Unknown source' try { return new URL(url).hostname.replace(/^www\./, '') } catch { return 'Unknown source' } } function getFaviconUrl(url?: string): string | null { if (!url) return null try { const host = new URL(url).hostname return `https://www.google.com/s2/favicons?domain=${host}&sz=64` } catch { return null } } function formatDateLabel(date?: string): string { if (!date) return '' const normalized = date.trim() if (!normalized) return '' // 常见相对时间(如 "3 days ago")直接保留 if (/\b(ago|yesterday|today)\b/i.test(normalized)) { return normalized } const parsed = new Date(normalized) if (Number.isNaN(parsed.getTime())) { return normalized } return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'short', day: 'numeric', }).format(parsed) } export function WebSearchPreview({ results, searchQuery, className }: WebSearchPreviewProps) { const items = normalizeResults(results) const queryText = searchQuery?.trim() || items[0]?.title || 'Search for premium insights...' if (!items.length) { return (
暂无搜索结果
) } return (

Search

AI

About {items.length.toLocaleString()} results

{items.map((item, idx) => { const favicon = getFaviconUrl(item.url) const host = getHostText(item.url) return (
{favicon ? ( {`${host} ) : ( )}
{host} {item.url}
{item.title || item.url} {item.snippet && (

{item.snippet}

)}
{item.date && ( {formatDateLabel(item.date)} )} {typeof item.position === 'number' && item.position <= 3 && ( Top Result )}
) })}
) } export default WebSearchPreview