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.
This commit is contained in:
Taylor Mullen
2026-02-08 23:54:11 -08:00
committed by N. Taylor Mullen
parent fe70052baf
commit 93f9e89114
2 changed files with 28 additions and 3 deletions

View File

@@ -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,
],
},

View File

@@ -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 {