From 43cc92dc07abd77d539628ddd52f3090c654067d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 07:20:17 +0100 Subject: [PATCH] perf(agents): isolate plugin tool resolution for tests --- src/agents/openclaw-plugin-tools.ts | 69 +++++++++++++++++++ ...w-tools.browser-plugin.integration.test.ts | 29 ++++++-- src/agents/openclaw-tools.ts | 25 ++----- 3 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 src/agents/openclaw-plugin-tools.ts diff --git a/src/agents/openclaw-plugin-tools.ts b/src/agents/openclaw-plugin-tools.ts new file mode 100644 index 00000000000..e3f26ec0a1f --- /dev/null +++ b/src/agents/openclaw-plugin-tools.ts @@ -0,0 +1,69 @@ +import type { OpenClawConfig } from "../config/config.js"; +import { resolvePluginTools } from "../plugins/tools.js"; +import { getActiveSecretsRuntimeSnapshot } from "../secrets/runtime.js"; +import { normalizeDeliveryContext } from "../utils/delivery-context.js"; +import type { GatewayMessageChannel } from "../utils/message-channel.js"; +import { resolveOpenClawPluginToolInputs } from "./openclaw-tools.plugin-context.js"; +import { applyPluginToolDeliveryDefaults } from "./plugin-tool-delivery-defaults.js"; +import type { AnyAgentTool } from "./tools/common.js"; + +type ResolveOpenClawPluginToolsOptions = { + config?: OpenClawConfig; + pluginToolAllowlist?: string[]; + agentChannel?: GatewayMessageChannel; + agentAccountId?: string; + agentTo?: string; + agentThreadId?: string | number; + requesterSenderId?: string | null; + senderIsOwner?: boolean; + allowGatewaySubagentBinding?: boolean; + sandboxed?: boolean; + agentSessionKey?: string; + sessionId?: string; + currentChannelId?: string; + currentThreadTs?: string; + currentMessageId?: string | number; + workspaceDir?: string; + agentDir?: string; + sandboxRoot?: string; + modelHasVision?: boolean; + modelProvider?: string; + allowMediaInvokeCommands?: boolean; + requesterAgentIdOverride?: string; + requireExplicitMessageTarget?: boolean; + disableMessageTool?: boolean; + disablePluginTools?: boolean; +}; + +export function resolveOpenClawPluginToolsForOptions(params: { + options?: ResolveOpenClawPluginToolsOptions; + resolvedConfig?: OpenClawConfig; + existingToolNames?: Set; +}): AnyAgentTool[] { + if (params.options?.disablePluginTools) { + return []; + } + + const runtimeSnapshot = getActiveSecretsRuntimeSnapshot(); + const deliveryContext = normalizeDeliveryContext({ + channel: params.options?.agentChannel, + to: params.options?.agentTo, + accountId: params.options?.agentAccountId, + threadId: params.options?.agentThreadId, + }); + + const pluginTools = resolvePluginTools({ + ...resolveOpenClawPluginToolInputs({ + options: params.options, + resolvedConfig: params.resolvedConfig, + runtimeConfig: runtimeSnapshot?.config, + }), + existingToolNames: params.existingToolNames ?? new Set(), + toolAllowlist: params.options?.pluginToolAllowlist, + }); + + return applyPluginToolDeliveryDefaults({ + tools: pluginTools, + deliveryContext, + }); +} diff --git a/src/agents/openclaw-tools.browser-plugin.integration.test.ts b/src/agents/openclaw-tools.browser-plugin.integration.test.ts index f04e034fc7a..f71f3656b37 100644 --- a/src/agents/openclaw-tools.browser-plugin.integration.test.ts +++ b/src/agents/openclaw-tools.browser-plugin.integration.test.ts @@ -5,7 +5,7 @@ import { clearPluginDiscoveryCache } from "../plugins/discovery.js"; import { clearPluginLoaderCache } from "../plugins/loader.js"; import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js"; import { resetPluginRuntimeStateForTest } from "../plugins/runtime.js"; -import { createOpenClawTools } from "./openclaw-tools.js"; +import { resolveOpenClawPluginToolsForOptions } from "./openclaw-plugin-tools.js"; function resetPluginState() { clearPluginLoaderCache(); @@ -31,8 +31,15 @@ describe("createOpenClawTools browser plugin integration", () => { }); it("loads the bundled browser plugin through normal plugin resolution", () => { - const tools = createOpenClawTools({ - config: { + const tools = resolveOpenClawPluginToolsForOptions({ + options: { + config: { + plugins: { + allow: ["browser"], + }, + } as OpenClawConfig, + }, + resolvedConfig: { plugins: { allow: ["browser"], }, @@ -43,8 +50,20 @@ describe("createOpenClawTools browser plugin integration", () => { }); it("omits the browser tool when the bundled browser plugin is disabled", () => { - const tools = createOpenClawTools({ - config: { + const tools = resolveOpenClawPluginToolsForOptions({ + options: { + config: { + plugins: { + allow: ["browser"], + entries: { + browser: { + enabled: false, + }, + }, + }, + } as OpenClawConfig, + }, + resolvedConfig: { plugins: { allow: ["browser"], entries: { diff --git a/src/agents/openclaw-tools.ts b/src/agents/openclaw-tools.ts index 77f423e25a7..548fd0e9e2c 100644 --- a/src/agents/openclaw-tools.ts +++ b/src/agents/openclaw-tools.ts @@ -1,15 +1,10 @@ import type { OpenClawConfig } from "../config/config.js"; import { callGateway } from "../gateway/call.js"; -import { resolvePluginTools } from "../plugins/tools.js"; -import { - getActiveSecretsRuntimeSnapshot, - getActiveRuntimeWebToolsMetadata, -} from "../secrets/runtime.js"; +import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime.js"; import { normalizeDeliveryContext } from "../utils/delivery-context.js"; import type { GatewayMessageChannel } from "../utils/message-channel.js"; import { resolveAgentWorkspaceDir, resolveSessionAgentId } from "./agent-scope.js"; -import { resolveOpenClawPluginToolInputs } from "./openclaw-tools.plugin-context.js"; -import { applyPluginToolDeliveryDefaults } from "./plugin-tool-delivery-defaults.js"; +import { resolveOpenClawPluginToolsForOptions } from "./openclaw-plugin-tools.js"; import type { SandboxFsBridge } from "./sandbox/fs-bridge.js"; import type { SpawnedToolContext } from "./spawned-context.js"; import type { ToolFsPolicy } from "./tool-fs-policy.js"; @@ -140,7 +135,6 @@ export function createOpenClawTools( threadId: options?.agentThreadId, }); const runtimeWebTools = getActiveRuntimeWebToolsMetadata(); - const runtimeSnapshot = getActiveSecretsRuntimeSnapshot(); const sandbox = options?.sandboxRoot && options?.sandboxFsBridge ? { root: options.sandboxRoot, bridge: options.sandboxFsBridge } @@ -304,19 +298,10 @@ export function createOpenClawTools( return tools; } - const pluginTools = resolvePluginTools({ - ...resolveOpenClawPluginToolInputs({ - options, - resolvedConfig, - runtimeConfig: runtimeSnapshot?.config, - }), + const wrappedPluginTools = resolveOpenClawPluginToolsForOptions({ + options, + resolvedConfig, existingToolNames: new Set(tools.map((tool) => tool.name)), - toolAllowlist: options?.pluginToolAllowlist, - }); - - const wrappedPluginTools = applyPluginToolDeliveryDefaults({ - tools: pluginTools, - deliveryContext, }); return [...tools, ...wrappedPluginTools];