test(tools): add tests for agent-specific tool filtering
Add 5 tests for agent-specific tool restrictions: - Apply global tool policy when no agent-specific policy exists - Apply agent-specific tool policy - Allow different tool policies for different agents - Combine global and agent-specific deny lists - Work with sandbox tools filtering All tests pass.
This commit is contained in:
207
src/agents/pi-tools-agent-config.test.ts
Normal file
207
src/agents/pi-tools-agent-config.test.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { createClawdbotCodingTools } from "./pi-tools.js";
|
||||
|
||||
describe("Agent-specific tool filtering", () => {
|
||||
it("should apply global tool policy when no agent-specific policy exists", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
agent: {
|
||||
tools: {
|
||||
allow: ["read", "write"],
|
||||
deny: ["bash"],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
agents: {
|
||||
main: {
|
||||
workspace: "~/clawd",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:main:main",
|
||||
workspaceDir: "/tmp/test",
|
||||
agentDir: "/tmp/agent",
|
||||
});
|
||||
|
||||
const toolNames = tools.map((t) => t.name);
|
||||
expect(toolNames).toContain("read");
|
||||
expect(toolNames).toContain("write");
|
||||
expect(toolNames).not.toContain("bash");
|
||||
});
|
||||
|
||||
it("should apply agent-specific tool policy", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
agent: {
|
||||
tools: {
|
||||
allow: ["read", "write", "bash"],
|
||||
deny: [],
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
agents: {
|
||||
restricted: {
|
||||
workspace: "~/clawd-restricted",
|
||||
tools: {
|
||||
allow: ["read"], // Agent override: only read
|
||||
deny: ["bash", "write", "edit"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:restricted:main",
|
||||
workspaceDir: "/tmp/test-restricted",
|
||||
agentDir: "/tmp/agent-restricted",
|
||||
});
|
||||
|
||||
const toolNames = tools.map((t) => t.name);
|
||||
expect(toolNames).toContain("read");
|
||||
expect(toolNames).not.toContain("bash");
|
||||
expect(toolNames).not.toContain("write");
|
||||
expect(toolNames).not.toContain("edit");
|
||||
});
|
||||
|
||||
it("should allow different tool policies for different agents", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
routing: {
|
||||
agents: {
|
||||
main: {
|
||||
workspace: "~/clawd",
|
||||
// No tools restriction - all tools available
|
||||
},
|
||||
family: {
|
||||
workspace: "~/clawd-family",
|
||||
tools: {
|
||||
allow: ["read"],
|
||||
deny: ["bash", "write", "edit", "process"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// main agent: all tools
|
||||
const mainTools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:main:main",
|
||||
workspaceDir: "/tmp/test-main",
|
||||
agentDir: "/tmp/agent-main",
|
||||
});
|
||||
const mainToolNames = mainTools.map((t) => t.name);
|
||||
expect(mainToolNames).toContain("bash");
|
||||
expect(mainToolNames).toContain("write");
|
||||
expect(mainToolNames).toContain("edit");
|
||||
|
||||
// family agent: restricted
|
||||
const familyTools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:family:whatsapp:group:123",
|
||||
workspaceDir: "/tmp/test-family",
|
||||
agentDir: "/tmp/agent-family",
|
||||
});
|
||||
const familyToolNames = familyTools.map((t) => t.name);
|
||||
expect(familyToolNames).toContain("read");
|
||||
expect(familyToolNames).not.toContain("bash");
|
||||
expect(familyToolNames).not.toContain("write");
|
||||
expect(familyToolNames).not.toContain("edit");
|
||||
});
|
||||
|
||||
it("should combine global and agent-specific deny lists", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
agent: {
|
||||
tools: {
|
||||
deny: ["browser"], // Global deny
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
agents: {
|
||||
work: {
|
||||
workspace: "~/clawd-work",
|
||||
tools: {
|
||||
deny: ["bash", "process"], // Agent deny
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:work:slack:dm:user123",
|
||||
workspaceDir: "/tmp/test-work",
|
||||
agentDir: "/tmp/agent-work",
|
||||
});
|
||||
|
||||
const toolNames = tools.map((t) => t.name);
|
||||
// Both global and agent denies should be applied
|
||||
expect(toolNames).not.toContain("browser");
|
||||
expect(toolNames).not.toContain("bash");
|
||||
expect(toolNames).not.toContain("process");
|
||||
});
|
||||
|
||||
it("should work with sandbox tools filtering", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
agent: {
|
||||
sandbox: {
|
||||
mode: "all",
|
||||
scope: "agent",
|
||||
tools: {
|
||||
allow: ["read", "write", "bash"], // Sandbox allows these
|
||||
deny: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
agents: {
|
||||
restricted: {
|
||||
workspace: "~/clawd-restricted",
|
||||
sandbox: {
|
||||
mode: "all",
|
||||
scope: "agent",
|
||||
},
|
||||
tools: {
|
||||
allow: ["read"], // Agent further restricts to only read
|
||||
deny: ["bash", "write"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tools = createClawdbotCodingTools({
|
||||
config: cfg,
|
||||
sessionKey: "agent:restricted:main",
|
||||
workspaceDir: "/tmp/test-restricted",
|
||||
agentDir: "/tmp/agent-restricted",
|
||||
sandbox: {
|
||||
enabled: true,
|
||||
sessionKey: "agent:restricted:main",
|
||||
workspaceDir: "/tmp/sandbox",
|
||||
agentWorkspaceDir: "/tmp/test-restricted",
|
||||
workspaceAccess: "none",
|
||||
containerName: "test-container",
|
||||
containerWorkdir: "/workspace",
|
||||
docker: {} as any,
|
||||
tools: {
|
||||
allow: ["read", "write", "bash"],
|
||||
deny: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const toolNames = tools.map((t) => t.name);
|
||||
// Agent policy should be applied first, then sandbox
|
||||
// Agent allows only "read", sandbox allows ["read", "write", "bash"]
|
||||
// Result: only "read" (most restrictive wins)
|
||||
expect(toolNames).toContain("read");
|
||||
expect(toolNames).not.toContain("bash");
|
||||
expect(toolNames).not.toContain("write");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user