feat: add tool allow/deny profiles with per-agent and per-provider filtering

Implements configurable tool filtering with four built-in profiles
(minimal, messaging, coding, full), global and per-agent/per-provider
allow/deny lists with glob pattern support, and defense-in-depth
enforcement at both tool listing and execution time.

New: src/tools/policy.ts (ToolPolicy engine), src/tools/policy.test.ts (37 tests)
Modified: config schema, tool registry, tool executor, NativeAgent,
AgentOrchestrator, daemon wiring, gateway tool handler, test mocks
This commit is contained in:
William Valentin
2026-02-06 15:30:34 -08:00
parent 8238d3e981
commit ee0af0cc06
13 changed files with 794 additions and 8 deletions
+7 -2
View File
@@ -4,6 +4,7 @@ import type { Session } from '../../session/index.js';
import type { ToolRegistry } from '../../tools/registry.js';
import type { ToolExecutor } from '../../tools/executor.js';
import type { MemoryStore } from '../../memory/store.js';
import type { ToolPolicyContext } from '../../tools/policy.js';
import { NativeAgent } from './agent.js';
import type { ToolUseEvent } from './agent.js';
import { shouldCompact } from '../../context/tokens.js';
@@ -87,6 +88,8 @@ export interface OrchestratorConfig {
contextWindow?: number;
/** Optional memory store for injecting persistent memory into the system prompt. */
memoryStore?: MemoryStore;
/** Policy context for tool filtering (agent tier, provider). */
toolPolicyContext?: ToolPolicyContext;
}
// ── AgentOrchestrator ─────────────────────────────────────────────────
@@ -134,6 +137,7 @@ export class AgentOrchestrator {
toolExecutor: config.toolExecutor,
maxIterations: config.maxIterations,
onToolUse: config.onToolUse,
toolPolicyContext: config.toolPolicyContext,
});
// Set the primary tier on the agent
@@ -174,9 +178,10 @@ export class AgentOrchestrator {
maxTokens: request.maxTokens,
};
// Optionally include tools from the registry
// Optionally include tools from the registry (filtered by policy)
if (request.tools && this._toolRegistry) {
chatRequest.tools = this._toolRegistry.toAnthropicFormat();
const policyContext = this._agent.getToolPolicyContext();
chatRequest.tools = this._toolRegistry.filteredToAnthropicFormat(policyContext);
}
const response = await this._modelRouter.chat(chatRequest, tier);