"use client";
import { makeAssistantToolUI } from "@assistant-ui/react";
import { AlertCircleIcon, FileTextIcon } from "lucide-react";
import {
Article,
ArticleErrorBoundary,
ArticleLoading,
parseSerializableArticle,
} from "@/components/tool-ui/article";
/**
* Type definitions for the scrape_webpage tool
*/
interface ScrapeWebpageArgs {
url: string;
max_length?: number;
}
interface ScrapeWebpageResult {
id: string;
assetId: string;
kind: "article";
href: string;
title: string;
description?: string;
content?: string;
domain?: string;
author?: string;
date?: string;
word_count?: number;
was_truncated?: boolean;
crawler_type?: string;
error?: string;
}
/**
* Error state component shown when webpage scraping fails
*/
function ScrapeErrorState({ url, error }: { url: string; error: string }) {
return (
Failed to scrape webpage
{url}
{error}
);
}
/**
* Cancelled state component
*/
function ScrapeCancelledState({ url }: { url: string }) {
return (
);
}
/**
* Parsed Article component with error handling
*/
function ParsedArticle({ result }: { result: unknown }) {
const article = parseSerializableArticle(result);
return (
{
if (id === "open" && article.href) {
window.open(article.href, "_blank", "noopener,noreferrer");
}
}}
/>
);
}
/**
* Scrape Webpage Tool UI Component
*
* This component is registered with assistant-ui to render an article card
* when the scrape_webpage tool is called by the agent.
*
* It displays scraped webpage content including:
* - Title and description
* - Author and date (if available)
* - Word count
* - Link to original source
*/
export const ScrapeWebpageToolUI = makeAssistantToolUI({
toolName: "scrape_webpage",
render: function ScrapeWebpageUI({ 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 article card
return (
);
},
});
export type { ScrapeWebpageArgs, ScrapeWebpageResult };