|
| 1 | +import { describe, it, expect } from "vitest"; |
| 2 | +import { resolveSubAgentType, getExcludeToolsForType, SUB_AGENT_TYPES } from "./sub_agent_types"; |
| 3 | + |
| 4 | +describe("Sub-Agent 类型系统", () => { |
| 5 | + describe("resolveSubAgentType", () => { |
| 6 | + it.concurrent("返回指定的内置类型", () => { |
| 7 | + expect(resolveSubAgentType("researcher")).toBe(SUB_AGENT_TYPES.researcher); |
| 8 | + expect(resolveSubAgentType("page_operator")).toBe(SUB_AGENT_TYPES.page_operator); |
| 9 | + expect(resolveSubAgentType("general")).toBe(SUB_AGENT_TYPES.general); |
| 10 | + }); |
| 11 | + |
| 12 | + it.concurrent("未知类型 fallback 到 general", () => { |
| 13 | + expect(resolveSubAgentType("unknown_type")).toBe(SUB_AGENT_TYPES.general); |
| 14 | + expect(resolveSubAgentType("")).toBe(SUB_AGENT_TYPES.general); |
| 15 | + }); |
| 16 | + |
| 17 | + it.concurrent("undefined/不传参数返回 general", () => { |
| 18 | + expect(resolveSubAgentType()).toBe(SUB_AGENT_TYPES.general); |
| 19 | + expect(resolveSubAgentType(undefined)).toBe(SUB_AGENT_TYPES.general); |
| 20 | + }); |
| 21 | + }); |
| 22 | + |
| 23 | + describe("getExcludeToolsForType", () => { |
| 24 | + const allTools = [ |
| 25 | + "web_fetch", |
| 26 | + "web_search", |
| 27 | + "opfs_read", |
| 28 | + "opfs_write", |
| 29 | + "opfs_list", |
| 30 | + "opfs_delete", |
| 31 | + "execute_script", |
| 32 | + "get_tab_content", |
| 33 | + "list_tabs", |
| 34 | + "open_tab", |
| 35 | + "close_tab", |
| 36 | + "activate_tab", |
| 37 | + "ask_user", |
| 38 | + "agent", |
| 39 | + "create_task", |
| 40 | + "update_task", |
| 41 | + "get_task", |
| 42 | + "list_tasks", |
| 43 | + "delete_task", |
| 44 | + ]; |
| 45 | + |
| 46 | + it.concurrent("researcher 类型排除 tab 工具和其他不在白名单中的工具", () => { |
| 47 | + const config = SUB_AGENT_TYPES.researcher; |
| 48 | + const excluded = getExcludeToolsForType(config, allTools); |
| 49 | + |
| 50 | + // researcher 不包含 tab 工具、ask_user、agent |
| 51 | + expect(excluded).toContain("get_tab_content"); |
| 52 | + expect(excluded).toContain("list_tabs"); |
| 53 | + expect(excluded).toContain("open_tab"); |
| 54 | + expect(excluded).toContain("close_tab"); |
| 55 | + expect(excluded).toContain("activate_tab"); |
| 56 | + expect(excluded).toContain("ask_user"); |
| 57 | + expect(excluded).toContain("agent"); |
| 58 | + |
| 59 | + // task 工具始终可用(ALWAYS_ALLOWED_TOOLS) |
| 60 | + expect(excluded).not.toContain("create_task"); |
| 61 | + expect(excluded).not.toContain("update_task"); |
| 62 | + expect(excluded).not.toContain("list_tasks"); |
| 63 | + |
| 64 | + // 应该保留的工具不在排除列表中 |
| 65 | + expect(excluded).not.toContain("web_fetch"); |
| 66 | + expect(excluded).not.toContain("web_search"); |
| 67 | + expect(excluded).not.toContain("execute_script"); |
| 68 | + expect(excluded).not.toContain("opfs_read"); |
| 69 | + }); |
| 70 | + |
| 71 | + it.concurrent("page_operator 类型排除 web_search 和其他不在白名单中的工具", () => { |
| 72 | + const config = SUB_AGENT_TYPES.page_operator; |
| 73 | + const excluded = getExcludeToolsForType(config, allTools); |
| 74 | + |
| 75 | + // page_operator 不包含 web_search、ask_user、agent |
| 76 | + expect(excluded).toContain("web_search"); |
| 77 | + expect(excluded).toContain("ask_user"); |
| 78 | + expect(excluded).toContain("agent"); |
| 79 | + |
| 80 | + // 应该保留 tab 工具 |
| 81 | + expect(excluded).not.toContain("get_tab_content"); |
| 82 | + expect(excluded).not.toContain("list_tabs"); |
| 83 | + expect(excluded).not.toContain("open_tab"); |
| 84 | + expect(excluded).not.toContain("execute_script"); |
| 85 | + expect(excluded).not.toContain("web_fetch"); |
| 86 | + |
| 87 | + // task 工具始终可用 |
| 88 | + expect(excluded).not.toContain("create_task"); |
| 89 | + expect(excluded).not.toContain("update_task"); |
| 90 | + }); |
| 91 | + |
| 92 | + it.concurrent("general 类型使用黑名单模式,只排除 ask_user 和 agent", () => { |
| 93 | + const config = SUB_AGENT_TYPES.general; |
| 94 | + const excluded = getExcludeToolsForType(config, allTools); |
| 95 | + |
| 96 | + expect(excluded).toEqual(["ask_user", "agent"]); |
| 97 | + }); |
| 98 | + |
| 99 | + it.concurrent("allowedTools 和 excludeTools 都未指定时返回空数组", () => { |
| 100 | + const config: any = { name: "empty", maxIterations: 10, timeoutMs: 60000, systemPromptAddition: "" }; |
| 101 | + const excluded = getExcludeToolsForType(config, allTools); |
| 102 | + expect(excluded).toEqual([]); |
| 103 | + }); |
| 104 | + |
| 105 | + it.concurrent("allowedTools 优先于 excludeTools", () => { |
| 106 | + const config: any = { |
| 107 | + name: "test", |
| 108 | + allowedTools: ["web_fetch"], |
| 109 | + excludeTools: ["web_search"], |
| 110 | + maxIterations: 10, |
| 111 | + timeoutMs: 60000, |
| 112 | + systemPromptAddition: "", |
| 113 | + }; |
| 114 | + const excluded = getExcludeToolsForType(config, ["web_fetch", "web_search", "execute_script"]); |
| 115 | + |
| 116 | + // 使用白名单模式,排除不在 allowedTools 中的 |
| 117 | + expect(excluded).toContain("web_search"); |
| 118 | + expect(excluded).toContain("execute_script"); |
| 119 | + expect(excluded).not.toContain("web_fetch"); |
| 120 | + }); |
| 121 | + }); |
| 122 | +}); |
0 commit comments