From 93f9e891147f3c29dd639a5e37a25d153414d33b Mon Sep 17 00:00:00 2001 From: Taylor Mullen Date: Sun, 8 Feb 2026 23:54:11 -0800 Subject: [PATCH] fix(core): enforce coreTools restrictions for sub-agents and skills - ensure sub-agent tools and ActivateSkillTool respect the coreTools configuration - prevents unauthorized tool calls when using restricted toolsets, particularly with Gemini 3 - added missing web_fetch tool to CodebaseInvestigatorAgent toolConfig to match its system prompt These changes resolve several behavioral evaluation failures (e.g., save_memory) that occurred when the agent attempted to use incorrectly registered sub-agents or skills in restricted environments. --- .../core/src/agents/codebase-investigator.ts | 2 ++ packages/core/src/config/config.ts | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/core/src/agents/codebase-investigator.ts b/packages/core/src/agents/codebase-investigator.ts index c4458a14d4..0624286adf 100644 --- a/packages/core/src/agents/codebase-investigator.ts +++ b/packages/core/src/agents/codebase-investigator.ts @@ -10,6 +10,7 @@ import { GREP_TOOL_NAME, LS_TOOL_NAME, READ_FILE_TOOL_NAME, + WEB_FETCH_TOOL_NAME, } from '../tools/tool-names.js'; import { DEFAULT_THINKING_MODE, @@ -120,6 +121,7 @@ export const CodebaseInvestigatorAgent = ( READ_FILE_TOOL_NAME, GLOB_TOOL_NAME, GREP_TOOL_NAME, + WEB_FETCH_TOOL_NAME, ], }, diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 92e20f9163..fa1028c656 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -947,7 +947,10 @@ export class Config { this.getSkillManager().setDisabledSkills(this.disabledSkills); // Re-register ActivateSkillTool to update its schema with the discovered enabled skill enums - if (this.getSkillManager().getSkills().length > 0) { + if ( + this.getSkillManager().getSkills().length > 0 && + this.isToolEnabledByCore(ActivateSkillTool.Name) + ) { this.getToolRegistry().unregisterTool(ActivateSkillTool.Name); this.getToolRegistry().registerTool( new ActivateSkillTool(this, this.messageBus), @@ -971,6 +974,21 @@ export class Config { this.syncPlanModeTools(); } + /** + * Returns true if the specified tool name is enabled based on the current + * coreTools configuration. + */ + private isToolEnabledByCore(toolName: string): boolean { + const coreTools = this.getCoreTools(); + if (!coreTools) { + return true; + } + + return coreTools.some( + (name) => name === toolName || name === toolName.toLowerCase(), + ); + } + getContentGenerator(): ContentGenerator { return this.contentGenerator; } @@ -2002,7 +2020,10 @@ export class Config { this.getSkillManager().setDisabledSkills(this.disabledSkills); // Re-register ActivateSkillTool to update its schema with the newly discovered skills - if (this.getSkillManager().getSkills().length > 0) { + if ( + this.getSkillManager().getSkills().length > 0 && + this.isToolEnabledByCore(ActivateSkillTool.Name) + ) { this.getToolRegistry().unregisterTool(ActivateSkillTool.Name); this.getToolRegistry().registerTool( new ActivateSkillTool(this, this.messageBus), @@ -2234,8 +2255,10 @@ export class Config { const definitions = this.agentRegistry.getAllDefinitions(); for (const definition of definitions) { - const isAllowed = + const isAllowedByTools = !allowedTools || allowedTools.includes(definition.name); + const isAllowed = + isAllowedByTools && this.isToolEnabledByCore(definition.name); if (isAllowed) { try {