web-search.ts

 1import { Type } from "@sinclair/typebox";
 2import type { AgentTool } from "@mariozechner/pi-agent-core";
 3import { search } from "kagi-ken";
 4import { FetchError, ToolInputError } from "../../util/errors.js";
 5
 6const SearchSchema = Type.Object({
 7  query: Type.String({ description: "Search query" }),
 8});
 9
10export const createWebSearchTool = (sessionToken: string): AgentTool => ({
11  name: "web_search",
12  label: "Web Search",
13  description: "Search the web. Returns structured results with titles, URLs, and snippets.",
14  parameters: SearchSchema as any,
15  execute: async (_toolCallId: string, params: any) => {
16    if (!sessionToken) {
17      throw new ToolInputError("Web search is not configured");
18    }
19
20    try {
21      const result = await search(params.query, sessionToken);
22      return {
23        content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
24        details: { query: params.query, resultCount: result?.data?.length ?? 0 },
25      };
26    } catch (error: any) {
27      throw new FetchError(
28        `kagi:search?q=${encodeURIComponent(params.query)}`,
29        error?.message ?? String(error),
30      );
31    }
32  },
33});