From 9c185faba9d30ec89d7c8495d85d1df8abbda5b1 Mon Sep 17 00:00:00 2001 From: Vignesh Natarajan Date: Sat, 28 Mar 2026 18:44:51 -0700 Subject: [PATCH] Agents: cover subagent memory tool policy --- src/agents/pi-tools.policy.test.ts | 24 +++++++++++++++++++++--- src/agents/pi-tools.policy.ts | 2 -- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/agents/pi-tools.policy.test.ts b/src/agents/pi-tools.policy.test.ts index ef286445948..85f3a7913e8 100644 --- a/src/agents/pi-tools.policy.test.ts +++ b/src/agents/pi-tools.policy.test.ts @@ -99,6 +99,22 @@ describe("resolveSubagentToolPolicy depth awareness", () => { expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(false); }); + it("applies configured deny to memory tools even though they are allowed by default", () => { + const cfg = { + agents: { defaults: { subagents: { maxSpawnDepth: 2 } } }, + tools: { + subagents: { + tools: { + deny: ["memory_search", "memory_get"], + }, + }, + }, + } as unknown as OpenClawConfig; + const policy = resolveSubagentToolPolicy(cfg, 1); + expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(false); + expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(false); + }); + it("does not create a restrictive allowlist when only alsoAllow is configured", () => { const cfg = { agents: { defaults: { subagents: { maxSpawnDepth: 2 } } }, @@ -129,12 +145,12 @@ describe("resolveSubagentToolPolicy depth awareness", () => { expect(isToolAllowedByPolicyName("sessions_history", policy)).toBe(true); }); - it("depth-1 orchestrator still denies gateway, cron, memory", () => { + it("depth-1 orchestrator still denies gateway and cron but allows memory tools", () => { const policy = resolveSubagentToolPolicy(baseCfg, 1); expect(isToolAllowedByPolicyName("gateway", policy)).toBe(false); expect(isToolAllowedByPolicyName("cron", policy)).toBe(false); - expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(false); - expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(false); + expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(true); + expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(true); }); it("depth-2 leaf denies sessions_spawn", () => { @@ -206,6 +222,8 @@ describe("resolveSubagentToolPolicy depth awareness", () => { const policy = resolveSubagentToolPolicyForSession(cfg, "agent:main:subagent:flat-leaf"); expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(false); expect(isToolAllowedByPolicyName("subagents", policy)).toBe(false); + expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(true); + expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(true); }); it("defaults to leaf behavior when no depth is provided", () => { diff --git a/src/agents/pi-tools.policy.ts b/src/agents/pi-tools.policy.ts index 9901abea325..cc5770015ee 100644 --- a/src/agents/pi-tools.policy.ts +++ b/src/agents/pi-tools.policy.ts @@ -30,8 +30,6 @@ const SUBAGENT_TOOL_DENY_ALWAYS = [ // Status/scheduling - main agent coordinates "session_status", "cron", - // Memory - pass relevant info in spawn prompt instead - // (removed: memory_search, memory_get — read-only, essential for multi-agent setups) // Direct session sends - subagents communicate through announce chain "sessions_send", ];