diff --git a/apps/x/apps/renderer/src/App.tsx b/apps/x/apps/renderer/src/App.tsx index c177cf5f..9bf73d36 100644 --- a/apps/x/apps/renderer/src/App.tsx +++ b/apps/x/apps/renderer/src/App.tsx @@ -36,6 +36,7 @@ import { import { Reasoning, ReasoningContent, ReasoningTrigger } from '@/components/ai-elements/reasoning'; import { Shimmer } from '@/components/ai-elements/shimmer'; import { Tool, ToolContent, ToolHeader, ToolInput, ToolOutput } from '@/components/ai-elements/tool'; +import { WebSearchResult } from '@/components/ai-elements/web-search-result'; import { PermissionRequest } from '@/components/ai-elements/permission-request'; import { AskHumanRequest } from '@/components/ai-elements/ask-human-request'; import { Suggestions } from '@/components/ai-elements/suggestions'; @@ -2203,6 +2204,18 @@ function App() { } if (isToolCall(item)) { + if (item.name === 'web-search') { + const input = normalizeToolInput(item.input) as Record | undefined + const result = item.result as Record | undefined + return ( + ) || []} + status={item.status} + /> + ) + } const errorText = item.status === 'error' ? 'Tool error' : '' const output = normalizeToolOutput(item.result, item.status) const input = normalizeToolInput(item.input) diff --git a/apps/x/apps/renderer/src/components/ai-elements/web-search-result.tsx b/apps/x/apps/renderer/src/components/ai-elements/web-search-result.tsx new file mode 100644 index 00000000..a498e661 --- /dev/null +++ b/apps/x/apps/renderer/src/components/ai-elements/web-search-result.tsx @@ -0,0 +1,108 @@ +"use client"; + +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { + CheckCircleIcon, + ChevronDownIcon, + GlobeIcon, + LoaderIcon, +} from "lucide-react"; + +interface WebSearchResultProps { + query: string; + results: Array<{ title: string; url: string; description: string }>; + status: "pending" | "running" | "completed" | "error"; +} + +function getDomain(url: string): string { + try { + return new URL(url).hostname; + } catch { + return url; + } +} + +export function WebSearchResult({ query, results, status }: WebSearchResultProps) { + const isRunning = status === "pending" || status === "running"; + + return ( + + +
+ + Searched the web +
+ +
+ +
+ {/* Query + result count */} +
+
+ + {query} +
+ {results.length > 0 && ( + + {results.length} result{results.length !== 1 ? "s" : ""} + + )} +
+ + {/* Results list */} + {results.length > 0 && ( + + )} + + {/* Status */} +
+ {isRunning ? ( + <> + + Searching... + + ) : ( + <> + + Done + + )} +
+
+
+
+ ); +}