
























@@ -15,7 +15,6 @@ import {
1515resolveEffectiveToolPolicy,
1616resolveGroupToolPolicy,
1717resolveInheritedToolPolicyForSession,
18-resolveSubagentToolPolicy,
1918resolveSubagentToolPolicyForSession,
2019resolveTrustedGroupId,
2120} from "./agent-tools.policy.js";
@@ -188,156 +187,11 @@ describe("resolveGroupToolPolicy group context validation", () => {
188187});
189188});
190189191-describe("resolveSubagentToolPolicy depth awareness", () => {
190+describe("resolveSubagentToolPolicyForSession", () => {
192191const baseCfg = {
193192agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
194193} as unknown as OpenClawConfig;
195194196-const deepCfg = {
197-agents: { defaults: { subagents: { maxSpawnDepth: 3 } } },
198-} as unknown as OpenClawConfig;
199-200-const leafCfg = {
201-agents: { defaults: { subagents: { maxSpawnDepth: 1 } } },
202-} as unknown as OpenClawConfig;
203-204-it("applies subagent tools.alsoAllow to re-enable default-denied tools", () => {
205-const cfg = {
206-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
207-tools: { subagents: { tools: { alsoAllow: ["sessions_send"] } } },
208-} as unknown as OpenClawConfig;
209-const policy = resolveSubagentToolPolicy(cfg, 1);
210-expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(true);
211-expect(isToolAllowedByPolicyName("cron", policy)).toBe(false);
212-});
213-214-it("applies subagent tools.allow to re-enable default-denied tools", () => {
215-const cfg = {
216-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
217-tools: { subagents: { tools: { allow: ["sessions_send"] } } },
218-} as unknown as OpenClawConfig;
219-const policy = resolveSubagentToolPolicy(cfg, 1);
220-expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(true);
221-});
222-223-it("merges subagent tools.alsoAllow into tools.allow when both are set", () => {
224-const cfg = {
225-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
226-tools: {
227-subagents: { tools: { allow: ["sessions_spawn"], alsoAllow: ["sessions_send"] } },
228-},
229-} as unknown as OpenClawConfig;
230-const policy = resolveSubagentToolPolicy(cfg, 1);
231-expect(policy.allow).toEqual(["sessions_spawn", "sessions_send"]);
232-});
233-234-it("keeps configured deny precedence over allow and alsoAllow", () => {
235-const cfg = {
236-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
237-tools: {
238-subagents: {
239-tools: {
240-allow: ["sessions_send"],
241-alsoAllow: ["sessions_send"],
242-deny: ["sessions_send"],
243-},
244-},
245-},
246-} as unknown as OpenClawConfig;
247-const policy = resolveSubagentToolPolicy(cfg, 1);
248-expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(false);
249-});
250-251-it("applies configured deny to memory tools even though they are allowed by default", () => {
252-const cfg = {
253-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
254-tools: {
255-subagents: {
256-tools: {
257-deny: ["memory_search", "memory_get"],
258-},
259-},
260-},
261-} as unknown as OpenClawConfig;
262-const policy = resolveSubagentToolPolicy(cfg, 1);
263-expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(false);
264-expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(false);
265-});
266-267-it("does not create a restrictive allowlist when only alsoAllow is configured", () => {
268-const cfg = {
269-agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
270-tools: { subagents: { tools: { alsoAllow: ["sessions_send"] } } },
271-} as unknown as OpenClawConfig;
272-const policy = resolveSubagentToolPolicy(cfg, 1);
273-expect(policy.allow).toBeUndefined();
274-expect(isToolAllowedByPolicyName("subagents", policy)).toBe(true);
275-});
276-277-it("depth-1 orchestrator (maxSpawnDepth=2) allows sessions_spawn", () => {
278-const policy = resolveSubagentToolPolicy(baseCfg, 1);
279-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(true);
280-});
281-282-it("depth-1 orchestrator (maxSpawnDepth=2) allows subagents", () => {
283-const policy = resolveSubagentToolPolicy(baseCfg, 1);
284-expect(isToolAllowedByPolicyName("subagents", policy)).toBe(true);
285-});
286-287-it("depth-1 orchestrator (maxSpawnDepth=2) allows sessions_list", () => {
288-const policy = resolveSubagentToolPolicy(baseCfg, 1);
289-expect(isToolAllowedByPolicyName("sessions_list", policy)).toBe(true);
290-});
291-292-it("depth-1 orchestrator (maxSpawnDepth=2) allows sessions_history", () => {
293-const policy = resolveSubagentToolPolicy(baseCfg, 1);
294-expect(isToolAllowedByPolicyName("sessions_history", policy)).toBe(true);
295-});
296-297-it("depth-1 orchestrator still denies gateway and cron but allows memory tools", () => {
298-const policy = resolveSubagentToolPolicy(baseCfg, 1);
299-expect(isToolAllowedByPolicyName("gateway", policy)).toBe(false);
300-expect(isToolAllowedByPolicyName("cron", policy)).toBe(false);
301-expect(isToolAllowedByPolicyName("memory_search", policy)).toBe(true);
302-expect(isToolAllowedByPolicyName("memory_get", policy)).toBe(true);
303-});
304-305-it("depth-2 leaf denies sessions_spawn", () => {
306-const policy = resolveSubagentToolPolicy(baseCfg, 2);
307-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(false);
308-});
309-310-it("depth-2 orchestrator (maxSpawnDepth=3) allows sessions_spawn", () => {
311-const policy = resolveSubagentToolPolicy(deepCfg, 2);
312-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(true);
313-});
314-315-it("depth-3 leaf (maxSpawnDepth=3) denies sessions_spawn", () => {
316-const policy = resolveSubagentToolPolicy(deepCfg, 3);
317-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(false);
318-});
319-320-it("depth-2 leaf denies subagents", () => {
321-const policy = resolveSubagentToolPolicy(baseCfg, 2);
322-expect(isToolAllowedByPolicyName("subagents", policy)).toBe(false);
323-});
324-325-it("depth-2 leaf denies sessions_list and sessions_history", () => {
326-const policy = resolveSubagentToolPolicy(baseCfg, 2);
327-expect(isToolAllowedByPolicyName("sessions_list", policy)).toBe(false);
328-expect(isToolAllowedByPolicyName("sessions_history", policy)).toBe(false);
329-});
330-331-it("depth-1 leaf (maxSpawnDepth=1) denies sessions_spawn", () => {
332-const policy = resolveSubagentToolPolicy(leafCfg, 1);
333-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(false);
334-});
335-336-it("depth-1 leaf (maxSpawnDepth=1) denies sessions_list", () => {
337-const policy = resolveSubagentToolPolicy(leafCfg, 1);
338-expect(isToolAllowedByPolicyName("sessions_list", policy)).toBe(false);
339-});
340-341195it("uses stored leaf role for flat depth-1 session keys", () => {
342196const storePath = path.join(
343197os.tmpdir(),
@@ -533,18 +387,6 @@ describe("resolveSubagentToolPolicy depth awareness", () => {
533387expect(isToolAllowedByPolicyName("custom_denied_tool", policy)).toBe(false);
534388expect(isToolAllowedByPolicyName("read", policy)).toBe(false);
535389});
536-537-it("defaults to leaf behavior when no depth is provided", () => {
538-const policy = resolveSubagentToolPolicy(baseCfg);
539-// Default depth=1, maxSpawnDepth=2 → orchestrator
540-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(true);
541-});
542-543-it("defaults to leaf behavior when depth is undefined and maxSpawnDepth is 1", () => {
544-const policy = resolveSubagentToolPolicy(leafCfg);
545-// Default depth=1, maxSpawnDepth=1 → leaf
546-expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(false);
547-});
548390});
549391550392describe("resolveEffectiveToolPolicy", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。