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:
@@ -1,4 +1,5 @@
|
||||
import type { Tool, ToolInputSchema } from './types.js';
|
||||
import type { ToolPolicy, ToolPolicyContext } from './policy.js';
|
||||
|
||||
export interface AnthropicToolDef {
|
||||
name: string;
|
||||
@@ -17,6 +18,7 @@ export interface OpenAIToolDef {
|
||||
|
||||
export class ToolRegistry {
|
||||
private tools: Map<string, Tool> = new Map();
|
||||
private _policy?: ToolPolicy;
|
||||
|
||||
register(tool: Tool): void {
|
||||
if (this.tools.has(tool.name)) {
|
||||
@@ -37,6 +39,22 @@ export class ToolRegistry {
|
||||
return Array.from(this.tools.values());
|
||||
}
|
||||
|
||||
/** Set the tool policy for filtering. */
|
||||
setPolicy(policy: ToolPolicy): void {
|
||||
this._policy = policy;
|
||||
}
|
||||
|
||||
/** Get the tool policy (if set). */
|
||||
getPolicy(): ToolPolicy | undefined {
|
||||
return this._policy;
|
||||
}
|
||||
|
||||
/** Return tools filtered by the policy for a given context. */
|
||||
filteredList(context?: ToolPolicyContext): Tool[] {
|
||||
if (!this._policy) return this.list();
|
||||
return this._policy.filterTools(this.list(), context);
|
||||
}
|
||||
|
||||
toAnthropicFormat(): AnthropicToolDef[] {
|
||||
return this.list().map(t => ({
|
||||
name: t.name,
|
||||
@@ -45,6 +63,15 @@ export class ToolRegistry {
|
||||
}));
|
||||
}
|
||||
|
||||
/** Return Anthropic-format tools filtered by policy. */
|
||||
filteredToAnthropicFormat(context?: ToolPolicyContext): AnthropicToolDef[] {
|
||||
return this.filteredList(context).map(t => ({
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
input_schema: t.inputSchema,
|
||||
}));
|
||||
}
|
||||
|
||||
toOpenAIFormat(): OpenAIToolDef[] {
|
||||
return this.list().map(t => ({
|
||||
type: 'function' as const,
|
||||
@@ -55,4 +82,16 @@ export class ToolRegistry {
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
/** Return OpenAI-format tools filtered by policy. */
|
||||
filteredToOpenAIFormat(context?: ToolPolicyContext): OpenAIToolDef[] {
|
||||
return this.filteredList(context).map(t => ({
|
||||
type: 'function' as const,
|
||||
function: {
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
parameters: t.inputSchema,
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user