import { describe, expect, it } from "vitest"; import { agentConnectionTools, builtinAgentTools } from "./builtin-tools.js"; import { builtinToolNamesForBot, filterBuiltinToolsForBot, MAIN_ONLY_BUILTIN_TOOLS, selectBuiltinToolsForRun, unknownBuiltinToolNames, } from "./executor-tools.js"; const unrestricted = { kind: "specialist", restrictBuiltinTools: false, allowedBuiltinTools: [] }; function select( bot: { kind: string; restrictBuiltinTools: boolean; allowedBuiltinTools: string[] }, options: { graphicalToolsAllowed?: boolean; agentConnectionsEnabled?: boolean } = {}, ) { return selectBuiltinToolsForRun({ graphicalToolsAllowed: options.graphicalToolsAllowed ?? true, groupId: null, trigger: "user", semanticMemoryEnabled: false, messagingChannelRun: false, agentConnectionsEnabled: options.agentConnectionsEnabled, bot, }).map((tool) => tool.name); } /** Every builtin a specialist can get: the catalog without the main bot's own tools. */ const specialistToolNames = builtinAgentTools .map((tool) => tool.name) .filter((name) => !MAIN_ONLY_BUILTIN_TOOLS.has(name)); describe("builtin tools per bot", () => { it("adds agent connection tools only for chat-linked bots", () => { expect(select(unrestricted)).not.toContain("message_agent"); expect(select(unrestricted, { agentConnectionsEnabled: true })).toEqual( expect.arrayContaining(agentConnectionTools.map((tool) => tool.name)), ); }); it("applies the allowlist to agent connection tools too", () => { const bot = { kind: "specialist", restrictBuiltinTools: true, allowedBuiltinTools: ["message_agent", "read_file"], }; expect(select(bot, { agentConnectionsEnabled: true })).toEqual(["read_file", "message_agent"]); }); it("never brings back a tool the run itself withholds", () => { const bot = { kind: "specialist", restrictBuiltinTools: true, allowedBuiltinTools: ["computer_observe", "read_file"], }; expect(select(bot, { graphicalToolsAllowed: false })).toEqual(["read_file"]); }); it("ignores the allowlist while the restriction is off", () => { const bot = { ...unrestricted, allowedBuiltinTools: ["read_file"] }; expect(filterBuiltinToolsForBot(builtinAgentTools, bot).map((tool) => tool.name)).toEqual( specialistToolNames, ); }); it("lists main-only tools for the main bot alone", () => { expect([...MAIN_ONLY_BUILTIN_TOOLS].sort()).toEqual(["delegate_task", "update_user_profile"]); const specialist = builtinToolNamesForBot({ kind: "specialist", chatLinked: false }); const main = builtinToolNamesForBot({ kind: "main", chatLinked: false }); for (const name of MAIN_ONLY_BUILTIN_TOOLS) { expect(specialist).not.toContain(name); expect(main).toContain(name); } }); it("lists agent connection tools only for chat-linked bots", () => { expect(builtinToolNamesForBot({ kind: "specialist", chatLinked: false })).toEqual( specialistToolNames, ); expect(builtinToolNamesForBot({ kind: "specialist", chatLinked: true })).toEqual([ ...specialistToolNames, ...agentConnectionTools.map((tool) => tool.name), ]); }); it("flags names that are not builtin tools", () => { expect( unknownBuiltinToolNames(["web_search", "message_agent", "web_serach", "mcp__notion__search"]), ).toEqual(["web_serach", "mcp__notion__search"]); }); });