diff --git a/src/agents/sandbox-agent-config.test.ts b/src/agents/sandbox-agent-config.test.ts index ac56c97f9..1fcf0d4ed 100644 --- a/src/agents/sandbox-agent-config.test.ts +++ b/src/agents/sandbox-agent-config.test.ts @@ -464,7 +464,7 @@ describe("Agent-specific sandbox config", () => { expect(context).toBeDefined(); expect(context?.tools).toEqual({ - allow: ["read", "write"], + allow: ["read", "write", "image"], deny: ["edit"], }); }); @@ -504,4 +504,30 @@ describe("Agent-specific sandbox config", () => { const sandbox = resolveSandboxConfigForAgent(cfg, "main"); expect(sandbox.tools.allow).toContain("image"); }); + + it("injects image into explicit sandbox allowlists", async () => { + const { resolveSandboxConfigForAgent } = await import("./sandbox.js"); + + const cfg: ClawdbotConfig = { + tools: { + sandbox: { + tools: { + allow: ["bash", "read"], + deny: [], + }, + }, + }, + agents: { + defaults: { + sandbox: { + mode: "all", + scope: "agent", + }, + }, + }, + }; + + const sandbox = resolveSandboxConfigForAgent(cfg, "main"); + expect(sandbox.tools.allow).toContain("image"); + }); }); diff --git a/src/agents/sandbox.ts b/src/agents/sandbox.ts index 4d9a61b60..58f1c6e60 100644 --- a/src/agents/sandbox.ts +++ b/src/agents/sandbox.ts @@ -475,17 +475,26 @@ export function resolveSandboxToolPolicyForAgent( key: "tools.sandbox.tools.deny", } satisfies SandboxToolPolicySource); + const deny = Array.isArray(agentDeny) + ? agentDeny + : Array.isArray(globalDeny) + ? globalDeny + : DEFAULT_TOOL_DENY; + let allow = Array.isArray(agentAllow) + ? agentAllow + : Array.isArray(globalAllow) + ? globalAllow + : DEFAULT_TOOL_ALLOW; + + // `image` is essential for multimodal workflows; always include it in sandboxed + // sessions unless explicitly denied. + if (!deny.includes("image") && !allow.includes("image")) { + allow = [...allow, "image"]; + } + return { - allow: Array.isArray(agentAllow) - ? agentAllow - : Array.isArray(globalAllow) - ? globalAllow - : DEFAULT_TOOL_ALLOW, - deny: Array.isArray(agentDeny) - ? agentDeny - : Array.isArray(globalDeny) - ? globalDeny - : DEFAULT_TOOL_DENY, + allow, + deny, sources: { allow: allowSource, deny: denySource,