web-search.ts

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