From 56353ae4b2fc42b2cb97e7e9a8ea600014b49874 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 17 Feb 2026 01:25:47 +0900 Subject: [PATCH] fix: enforce disabled_agents config in call_omo_agent (#1716) --- src/plugin/tool-registry.ts | 6 ++- src/tools/call-omo-agent/tools.test.ts | 62 ++++++++++++++++++++++++++ src/tools/call-omo-agent/tools.ts | 11 ++++- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 src/tools/call-omo-agent/tools.test.ts diff --git a/src/plugin/tool-registry.ts b/src/plugin/tool-registry.ts index 14267fe0a..c03d5f429 100644 --- a/src/plugin/tool-registry.ts +++ b/src/plugin/tool-registry.ts @@ -48,7 +48,11 @@ export function createToolRegistry(args: { const { ctx, pluginConfig, managers, skillContext, availableCategories } = args const backgroundTools = createBackgroundTools(managers.backgroundManager, ctx.client) - const callOmoAgent = createCallOmoAgent(ctx, managers.backgroundManager) + const callOmoAgent = createCallOmoAgent( + ctx, + managers.backgroundManager, + pluginConfig.disabled_agents ?? [], + ) const isMultimodalLookerEnabled = !(pluginConfig.disabled_agents ?? []).some( (agent) => agent.toLowerCase() === "multimodal-looker", diff --git a/src/tools/call-omo-agent/tools.test.ts b/src/tools/call-omo-agent/tools.test.ts new file mode 100644 index 000000000..d968ce4ca --- /dev/null +++ b/src/tools/call-omo-agent/tools.test.ts @@ -0,0 +1,62 @@ +import { describe, expect, test } from "bun:test" +import { createCallOmoAgent } from "./tools" + +const TEST_TOOL_CONTEXT = { + sessionID: "ses-parent", + messageID: "msg-1", + agent: "sisyphus", + abort: new AbortController().signal, +} + +describe("call_omo_agent disabled_agents enforcement", () => { + test("rejects disabled agent from config with clear error", async () => { + //#given + const tool = createCallOmoAgent( + { client: {} } as Parameters[0], + {} as Parameters[1], + ["explore"], + ) + + //#when + const result = await tool.execute( + { + description: "run search", + prompt: "find implementation", + subagent_type: "ExPlOrE", + run_in_background: false, + }, + TEST_TOOL_CONTEXT, + ) + + //#then + expect(result).toBe( + 'Error: Agent "ExPlOrE" is disabled via disabled_agents config.', + ) + }) + + test("allows enabled agent even when other agents are disabled", async () => { + //#given + const tool = createCallOmoAgent( + { client: {} } as Parameters[0], + {} as Parameters[1], + ["explore"], + ) + + //#when + const result = await tool.execute( + { + description: "continue session", + prompt: "read docs", + subagent_type: "librarian", + run_in_background: true, + session_id: "ses-child", + }, + TEST_TOOL_CONTEXT, + ) + + //#then + expect(result).toBe( + "Error: session_id is not supported in background mode. Use run_in_background=false to continue an existing session.", + ) + }) +}) diff --git a/src/tools/call-omo-agent/tools.ts b/src/tools/call-omo-agent/tools.ts index b773d21ab..a69597d94 100644 --- a/src/tools/call-omo-agent/tools.ts +++ b/src/tools/call-omo-agent/tools.ts @@ -8,8 +8,10 @@ import { executeSync } from "./sync-executor" export function createCallOmoAgent( ctx: PluginInput, - backgroundManager: BackgroundManager + backgroundManager: BackgroundManager, + disabledAgents: string[] = [], ): ToolDefinition { + const disabledAgentSet = new Set(disabledAgents.map((name) => name.toLowerCase())) const agentDescriptions = ALLOWED_AGENTS.map( (name) => `- ${name}: Specialized agent for ${name} tasks` ).join("\n") @@ -41,7 +43,12 @@ export function createCallOmoAgent( return `Error: Invalid agent type "${args.subagent_type}". Only ${ALLOWED_AGENTS.join(", ")} are allowed.` } - const normalizedAgent = args.subagent_type.toLowerCase() as AllowedAgentType + const normalizedAgentName = args.subagent_type.toLowerCase() + if (disabledAgentSet.has(normalizedAgentName)) { + return `Error: Agent "${args.subagent_type}" is disabled via disabled_agents config.` + } + + const normalizedAgent = normalizedAgentName as AllowedAgentType args = { ...args, subagent_type: normalizedAgent } if (args.run_in_background) {