mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 08:51:23 +00:00
Agents/Subagents: honor subagent alsoAllow grants
This commit is contained in:
@@ -54,6 +54,63 @@ describe("resolveSubagentToolPolicy depth awareness", () => {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 1 } } },
|
||||
} as unknown as OpenClawConfig;
|
||||
|
||||
it("applies subagent tools.alsoAllow to re-enable default-denied tools", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
|
||||
tools: { subagents: { tools: { alsoAllow: ["sessions_send"] } } },
|
||||
} as unknown as OpenClawConfig;
|
||||
const policy = resolveSubagentToolPolicy(cfg, 1);
|
||||
expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(true);
|
||||
expect(isToolAllowedByPolicyName("cron", policy)).toBe(false);
|
||||
});
|
||||
|
||||
it("applies subagent tools.allow to re-enable default-denied tools", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
|
||||
tools: { subagents: { tools: { allow: ["sessions_send"] } } },
|
||||
} as unknown as OpenClawConfig;
|
||||
const policy = resolveSubagentToolPolicy(cfg, 1);
|
||||
expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(true);
|
||||
});
|
||||
|
||||
it("merges subagent tools.alsoAllow into tools.allow when both are set", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
|
||||
tools: {
|
||||
subagents: { tools: { allow: ["sessions_spawn"], alsoAllow: ["sessions_send"] } },
|
||||
},
|
||||
} as unknown as OpenClawConfig;
|
||||
const policy = resolveSubagentToolPolicy(cfg, 1);
|
||||
expect(policy.allow).toEqual(["sessions_spawn", "sessions_send"]);
|
||||
});
|
||||
|
||||
it("keeps configured deny precedence over allow and alsoAllow", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
|
||||
tools: {
|
||||
subagents: {
|
||||
tools: {
|
||||
allow: ["sessions_send"],
|
||||
alsoAllow: ["sessions_send"],
|
||||
deny: ["sessions_send"],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as OpenClawConfig;
|
||||
const policy = resolveSubagentToolPolicy(cfg, 1);
|
||||
expect(isToolAllowedByPolicyName("sessions_send", policy)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not create a restrictive allowlist when only alsoAllow is configured", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { subagents: { maxSpawnDepth: 2 } } },
|
||||
tools: { subagents: { tools: { alsoAllow: ["sessions_send"] } } },
|
||||
} as unknown as OpenClawConfig;
|
||||
const policy = resolveSubagentToolPolicy(cfg, 1);
|
||||
expect(policy.allow).toBeUndefined();
|
||||
expect(isToolAllowedByPolicyName("subagents", policy)).toBe(true);
|
||||
});
|
||||
|
||||
it("depth-1 orchestrator (maxSpawnDepth=2) allows sessions_spawn", () => {
|
||||
const policy = resolveSubagentToolPolicy(baseCfg, 1);
|
||||
expect(isToolAllowedByPolicyName("sessions_spawn", policy)).toBe(true);
|
||||
|
||||
@@ -88,9 +88,17 @@ export function resolveSubagentToolPolicy(cfg?: OpenClawConfig, depth?: number):
|
||||
cfg?.agents?.defaults?.subagents?.maxSpawnDepth ?? DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH;
|
||||
const effectiveDepth = typeof depth === "number" && depth >= 0 ? depth : 1;
|
||||
const baseDeny = resolveSubagentDenyList(effectiveDepth, maxSpawnDepth);
|
||||
const deny = [...baseDeny, ...(Array.isArray(configured?.deny) ? configured.deny : [])];
|
||||
const allow = Array.isArray(configured?.allow) ? configured.allow : undefined;
|
||||
return { allow, deny };
|
||||
const alsoAllow = Array.isArray(configured?.alsoAllow) ? configured.alsoAllow : undefined;
|
||||
const explicitAllow = new Set(
|
||||
[...(allow ?? []), ...(alsoAllow ?? [])].map((toolName) => normalizeToolName(toolName)),
|
||||
);
|
||||
const deny = [
|
||||
...baseDeny.filter((toolName) => !explicitAllow.has(normalizeToolName(toolName))),
|
||||
...(Array.isArray(configured?.deny) ? configured.deny : []),
|
||||
];
|
||||
const mergedAllow = allow && alsoAllow ? Array.from(new Set([...allow, ...alsoAllow])) : allow;
|
||||
return { allow: mergedAllow, deny };
|
||||
}
|
||||
|
||||
export function isToolAllowedByPolicyName(name: string, policy?: SandboxToolPolicy): boolean {
|
||||
|
||||
Reference in New Issue
Block a user