web-fetch.ts

 1import { Type } from "@sinclair/typebox";
 2import type { AgentTool } from "@mariozechner/pi-agent-core";
 3import Tabstack from "@tabstack/sdk";
 4import { FetchError, ToolInputError } from "../../util/errors.js";
 5
 6export interface WebFetchResult {
 7  content: string;
 8  url: string;
 9}
10
11const FetchSchema = Type.Object({
12  url: Type.String({ description: "URL to fetch" }),
13  nocache: Type.Optional(Type.Boolean({ description: "Force fresh fetch" })),
14});
15
16export function createWebFetchTool(apiKey: string): AgentTool {
17  return {
18    name: "web_fetch",
19    label: "Web Fetch",
20    description: "Fetch a URL and return markdown using Tabstack.",
21    parameters: FetchSchema as any,
22    execute: async (_toolCallId: string, params: any) => {
23      if (!apiKey) {
24        throw new ToolInputError("Missing Tabstack API key");
25      }
26
27      const client = new Tabstack({ apiKey });
28
29      try {
30        const result = await client.extract.markdown({
31          url: params.url,
32          nocache: params.nocache ?? false,
33        });
34
35        return {
36          content: [{ type: "text", text: result.content ?? "" }],
37          details: { url: params.url, length: result.content?.length ?? 0 },
38        };
39      } catch (error: any) {
40        throw new FetchError(params.url, error?.message ?? String(error));
41      }
42    },
43  };
44}