fix: apply disallowedTools filtering to runtime-added custom tools

Previously runtime-added tools bypassed all filtering including
disallowedTools, contradicting the documented behavior. Now custom
tools still bypass preset/allowlist but respect the denylist.
This commit is contained in:
JackChen 2026-04-15 15:11:12 +08:00
parent 9b487ca368
commit 93795db09f
2 changed files with 12 additions and 7 deletions

View File

@ -448,8 +448,10 @@ export class AgentRunner {
}
// 3. Apply denylist filter if set
if (this.options.disallowedTools) {
const denied = new Set(this.options.disallowedTools)
const denied = this.options.disallowedTools
? new Set(this.options.disallowedTools)
: undefined
if (denied) {
filteredTools = filteredTools.filter(t => !denied.has(t.name))
}
@ -457,8 +459,11 @@ export class AgentRunner {
const frameworkDenied = new Set(AGENT_FRAMEWORK_DISALLOWED)
filteredTools = filteredTools.filter(t => !frameworkDenied.has(t.name))
// Runtime-added custom tools stay available regardless of filtering rules.
return [...filteredTools, ...runtimeCustomTools]
// Runtime-added custom tools bypass preset / allowlist but respect denylist.
const finalRuntime = denied
? runtimeCustomTools.filter(t => !denied.has(t.name))
: runtimeCustomTools
return [...filteredTools, ...finalRuntime]
}
// -------------------------------------------------------------------------

View File

@ -216,8 +216,8 @@ describe('Tool filtering', () => {
const tools = (runner as any).resolveTools() as LLMToolDef[]
const toolNames = tools.map((t: LLMToolDef) => t.name).sort()
// custom_tool is runtime-added but disallowedTools still blocks it
expect(toolNames).toEqual([
'custom_tool',
'file_edit',
'file_read',
'file_write',
@ -286,7 +286,7 @@ describe('Tool filtering', () => {
expect(toolNames).toEqual(['custom_tool'])
})
it('runtime-added tools bypass filtering regardless of tool name', () => {
it('runtime-added tools are blocked by disallowedTools', () => {
const runtimeBuiltinNamedRegistry = new ToolRegistry()
runtimeBuiltinNamedRegistry.register(defineTool({
name: 'file_read',
@ -306,7 +306,7 @@ describe('Tool filtering', () => {
)
const tools = (runtimeBuiltinNamedRunner as any).resolveTools() as LLMToolDef[]
expect(tools.map(t => t.name)).toEqual(['file_read'])
expect(tools.map(t => t.name)).toEqual([])
})
})