feat(tools): add agent-specific tool filtering

Add tool filtering layer for per-agent restrictions:
- Extract agentId from sessionKey
- Load routing.agents[agentId].tools via resolveAgentConfig()
- Apply agent-specific allow/deny before sandbox filtering

Filtering order:
1. Global (agent.tools)
2. Agent-specific (routing.agents[id].tools) ← NEW
3. Sandbox (agent.sandbox.tools)
4. Subagent policy

This enables different tool permissions per agent
(e.g., main: all tools, family: read only).
This commit is contained in:
sheeek
2026-01-07 11:58:19 +01:00
parent 1e3caf07d4
commit 0fffde00a8

View File

@@ -11,6 +11,10 @@ import type { ClawdbotConfig } from "../config/config.js";
import { detectMime } from "../media/mime.js";
import { isSubagentSessionKey } from "../routing/session-key.js";
import { startWebLoginWithQr, waitForWebLogin } from "../web/login-qr.js";
import {
resolveAgentConfig,
resolveAgentIdFromSessionKey,
} from "./agent-scope.js";
import {
type BashToolDefaults,
createBashTool,
@@ -592,9 +596,20 @@ export function createClawdbotCodingTools(options?: {
options.config.agent.tools.deny?.length)
? filterToolsByPolicy(filtered, options.config.agent.tools)
: filtered;
// Agent-specific tool policy
let agentFiltered = globallyFiltered;
if (options?.sessionKey && options?.config) {
const agentId = resolveAgentIdFromSessionKey(options.sessionKey);
const agentConfig = resolveAgentConfig(options.config, agentId);
if (agentConfig?.tools) {
agentFiltered = filterToolsByPolicy(globallyFiltered, agentConfig.tools);
}
}
const sandboxed = sandbox
? filterToolsByPolicy(globallyFiltered, sandbox.tools)
: globallyFiltered;
? filterToolsByPolicy(agentFiltered, sandbox.tools)
: agentFiltered;
const subagentFiltered =
isSubagentSessionKey(options?.sessionKey) && options?.sessionKey
? filterToolsByPolicy(