"use client"; import { makeAssistantToolUI } from "@assistant-ui/react"; import { AlertCircleIcon, ExternalLinkIcon, LinkIcon } from "lucide-react"; import { MediaCard, MediaCardErrorBoundary, MediaCardLoading, parseSerializableMediaCard, type SerializableMediaCard, } from "@/components/tool-ui/media-card"; /** * Type definitions for the link_preview tool */ interface LinkPreviewArgs { url: string; title?: string; } interface LinkPreviewResult { id: string; assetId: string; kind: "link"; href: string; title: string; description?: string; thumb?: string; domain?: string; error?: string; } /** * Error state component shown when link preview fails */ function LinkPreviewErrorState({ url, error }: { url: string; error: string }) { return (

Failed to load preview

{url}

{error}

); } /** * Cancelled state component */ function LinkPreviewCancelledState({ url }: { url: string }) { return (

Preview: {url}

); } /** * Parsed MediaCard component with error handling */ function ParsedMediaCard({ result }: { result: unknown }) { const card = parseSerializableMediaCard(result); return ( { if (id === "open" && card.href) { window.open(card.href, "_blank", "noopener,noreferrer"); } }} /> ); } /** * Link Preview Tool UI Component * * This component is registered with assistant-ui to render a rich * link preview card when the link_preview tool is called by the agent. * * It displays website metadata including: * - Title and description * - Thumbnail/Open Graph image * - Domain name * - Clickable link to open in new tab */ export const LinkPreviewToolUI = makeAssistantToolUI({ toolName: "link_preview", render: function LinkPreviewUI({ args, result, status }) { const url = args.url || "Unknown URL"; // Loading state - tool is still running if (status.type === "running" || status.type === "requires-action") { return (
); } // Incomplete/cancelled state if (status.type === "incomplete") { if (status.reason === "cancelled") { return ; } if (status.reason === "error") { return ( ); } } // No result yet if (!result) { return (
); } // Error result from the tool if (result.error) { return ; } // Success - render the media card return (
); }, }); /** * Multiple Link Previews Tool UI Component * * This component handles cases where multiple links need to be previewed. * It renders a grid of link preview cards. */ interface MultiLinkPreviewArgs { urls: string[]; } interface MultiLinkPreviewResult { previews: LinkPreviewResult[]; errors?: { url: string; error: string }[]; } export const MultiLinkPreviewToolUI = makeAssistantToolUI< MultiLinkPreviewArgs, MultiLinkPreviewResult >({ toolName: "multi_link_preview", render: function MultiLinkPreviewUI({ args, result, status }) { const urls = args.urls || []; // Loading state if (status.type === "running" || status.type === "requires-action") { return (
{urls.slice(0, 4).map((url, index) => ( ))}
); } // Incomplete state if (status.type === "incomplete") { return (

Link previews cancelled

); } // No result if (!result || !result.previews) { return null; } // Render grid of previews return (
{result.previews.map((preview) => ( ))} {result.errors?.map((err) => ( ))}
); }, }); export type { LinkPreviewArgs, LinkPreviewResult, MultiLinkPreviewArgs, MultiLinkPreviewResult };