fix(patch): cherry-pick b2d6dc4 to release/v0.35.0-preview.4-pr-23546 [CONFLICTS] (#23585)

Co-authored-by: Abhi <43648792+abhipatel12@users.noreply.github.com>
Co-authored-by: Abhi <abhipatel@google.com>
This commit is contained in:
gemini-cli-robot
2026-03-23 15:40:50 -07:00
committed by GitHub
parent 63c6560a38
commit e88b56bbcb
10 changed files with 63 additions and 11 deletions
+1 -1
View File
@@ -1159,7 +1159,7 @@ their corresponding top-level category object in your `settings.json` file.
- **`experimental.enableAgents`** (boolean): - **`experimental.enableAgents`** (boolean):
- **Description:** Enable local and remote subagents. - **Description:** Enable local and remote subagents.
- **Default:** `true` - **Default:** `false`
- **Requires restart:** Yes - **Requires restart:** Yes
- **`experimental.extensionManagement`** (boolean): - **`experimental.extensionManagement`** (boolean):
@@ -325,6 +325,28 @@ describe('loadConfig', () => {
); );
}); });
it('should pass enableAgents to Config constructor', async () => {
const settings: Settings = {
experimental: {
enableAgents: false,
},
};
await loadConfig(settings, mockExtensionLoader, taskId);
expect(Config).toHaveBeenCalledWith(
expect.objectContaining({
enableAgents: false,
}),
);
});
it('should default enableAgents to false when not provided', async () => {
await loadConfig(mockSettings, mockExtensionLoader, taskId);
expect(Config).toHaveBeenCalledWith(
expect.objectContaining({
enableAgents: false,
}),
);
});
describe('interactivity', () => { describe('interactivity', () => {
it('should set interactive true when not headless', async () => { it('should set interactive true when not headless', async () => {
vi.mocked(isHeadlessMode).mockReturnValue(false); vi.mocked(isHeadlessMode).mockReturnValue(false);
+1
View File
@@ -110,6 +110,7 @@ export async function loadConfig(
interactive: !isHeadlessMode(), interactive: !isHeadlessMode(),
enableInteractiveShell: !isHeadlessMode(), enableInteractiveShell: !isHeadlessMode(),
ptyInfo: 'auto', ptyInfo: 'auto',
enableAgents: settings.experimental?.enableAgents ?? false,
}; };
const fileService = new FileDiscoveryService(workspaceDir, { const fileService = new FileDiscoveryService(workspaceDir, {
@@ -48,6 +48,9 @@ export interface Settings {
enableRecursiveFileSearch?: boolean; enableRecursiveFileSearch?: boolean;
customIgnoreFilePaths?: string[]; customIgnoreFilePaths?: string[];
}; };
experimental?: {
enableAgents?: boolean;
};
} }
export interface SettingsError { export interface SettingsError {
@@ -400,7 +400,7 @@ describe('SettingsSchema', () => {
expect(setting).toBeDefined(); expect(setting).toBeDefined();
expect(setting.type).toBe('boolean'); expect(setting.type).toBe('boolean');
expect(setting.category).toBe('Experimental'); expect(setting.category).toBe('Experimental');
expect(setting.default).toBe(true); expect(setting.default).toBe(false);
expect(setting.requiresRestart).toBe(true); expect(setting.requiresRestart).toBe(true);
expect(setting.showInDialog).toBe(false); expect(setting.showInDialog).toBe(false);
expect(setting.description).toBe('Enable local and remote subagents.'); expect(setting.description).toBe('Enable local and remote subagents.');
+1 -1
View File
@@ -1838,7 +1838,7 @@ const SETTINGS_SCHEMA = {
label: 'Enable Agents', label: 'Enable Agents',
category: 'Experimental', category: 'Experimental',
requiresRestart: true, requiresRestart: true,
default: true, default: false,
description: 'Enable local and remote subagents.', description: 'Enable local and remote subagents.',
showInDialog: false, showInDialog: false,
}, },
+22 -4
View File
@@ -44,6 +44,7 @@ export class AgentRegistry {
private readonly agents = new Map<string, AgentDefinition<any>>(); private readonly agents = new Map<string, AgentDefinition<any>>();
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
private readonly allDefinitions = new Map<string, AgentDefinition<any>>(); private readonly allDefinitions = new Map<string, AgentDefinition<any>>();
private readonly builtInAgents = new Set<string>();
constructor(private readonly config: Config) {} constructor(private readonly config: Config) {}
@@ -56,6 +57,13 @@ export class AgentRegistry {
await this.loadAgents(); await this.loadAgents();
} }
/**
* Returns true if the agent is a built-in agent.
*/
isBuiltIn(name: string): boolean {
return this.builtInAgents.has(name);
}
private onModelChanged = () => { private onModelChanged = () => {
this.refreshAgents().catch((e) => { this.refreshAgents().catch((e) => {
debugLogger.error( debugLogger.error(
@@ -240,15 +248,25 @@ export class AgentRegistry {
} }
private loadBuiltInAgents(): void { private loadBuiltInAgents(): void {
this.registerLocalAgent(CodebaseInvestigatorAgent(this.config)); const codebaseAgent = CodebaseInvestigatorAgent(this.config);
this.registerLocalAgent(CliHelpAgent(this.config)); this.builtInAgents.add(codebaseAgent.name);
this.registerLocalAgent(GeneralistAgent(this.config)); this.registerLocalAgent(codebaseAgent);
const helpAgent = CliHelpAgent(this.config);
this.builtInAgents.add(helpAgent.name);
this.registerLocalAgent(helpAgent);
const generalistAgent = GeneralistAgent(this.config);
this.builtInAgents.add(generalistAgent.name);
this.registerLocalAgent(generalistAgent);
// Register the browser agent if enabled in settings. // Register the browser agent if enabled in settings.
// Tools are configured dynamically at invocation time via browserAgentFactory. // Tools are configured dynamically at invocation time via browserAgentFactory.
const browserConfig = this.config.getBrowserAgentConfig(); const browserConfig = this.config.getBrowserAgentConfig();
if (browserConfig.enabled) { if (browserConfig.enabled) {
this.registerLocalAgent(BrowserAgentDefinition(this.config)); const browserAgent = BrowserAgentDefinition(this.config);
this.builtInAgents.add(browserAgent.name);
this.registerLocalAgent(browserAgent);
} }
} }
+7
View File
@@ -185,6 +185,7 @@ vi.mock('../agents/registry.js', () => {
AgentRegistryMock.prototype.initialize = vi.fn(); AgentRegistryMock.prototype.initialize = vi.fn();
AgentRegistryMock.prototype.getAllDefinitions = vi.fn(() => []); AgentRegistryMock.prototype.getAllDefinitions = vi.fn(() => []);
AgentRegistryMock.prototype.getDefinition = vi.fn(); AgentRegistryMock.prototype.getDefinition = vi.fn();
AgentRegistryMock.prototype.isBuiltIn = vi.fn();
return { AgentRegistry: AgentRegistryMock }; return { AgentRegistry: AgentRegistryMock };
}); });
@@ -1262,6 +1263,9 @@ describe('Server Config (config.ts)', () => {
AgentRegistryMock.prototype.getAllDefinitions.mockReturnValue([ AgentRegistryMock.prototype.getAllDefinitions.mockReturnValue([
mockAgentDefinition, mockAgentDefinition,
]); ]);
AgentRegistryMock.prototype.isBuiltIn.mockImplementation(
(name: string) => name === 'codebase_investigator',
);
const SubAgentToolMock = ( const SubAgentToolMock = (
(await vi.importMock('../agents/subagent-tool.js')) as { (await vi.importMock('../agents/subagent-tool.js')) as {
@@ -1317,6 +1321,9 @@ describe('Server Config (config.ts)', () => {
AgentRegistryMock.prototype.getAllDefinitions.mockReturnValue([ AgentRegistryMock.prototype.getAllDefinitions.mockReturnValue([
mockAgentDefinition, mockAgentDefinition,
]); ]);
AgentRegistryMock.prototype.isBuiltIn.mockImplementation(
(name: string) => name === 'codebase_investigator',
);
const SubAgentToolMock = ( const SubAgentToolMock = (
(await vi.importMock('../agents/subagent-tool.js')) as { (await vi.importMock('../agents/subagent-tool.js')) as {
+3 -2
View File
@@ -951,7 +951,7 @@ export class Config implements McpContext, AgentLoopContext {
this.model = params.model; this.model = params.model;
this.disableLoopDetection = params.disableLoopDetection ?? false; this.disableLoopDetection = params.disableLoopDetection ?? false;
this._activeModel = params.model; this._activeModel = params.model;
this.enableAgents = params.enableAgents ?? true; this.enableAgents = params.enableAgents ?? false;
this.agents = params.agents ?? {}; this.agents = params.agents ?? {};
this.disableLLMCorrection = params.disableLLMCorrection ?? true; this.disableLLMCorrection = params.disableLLMCorrection ?? true;
this.planEnabled = params.plan ?? true; this.planEnabled = params.plan ?? true;
@@ -3196,7 +3196,8 @@ export class Config implements McpContext, AgentLoopContext {
for (const definition of definitions) { for (const definition of definitions) {
try { try {
if ( if (
!this.isAgentsEnabled() || (!this.isAgentsEnabled() &&
!this.agentRegistry.isBuiltIn(definition.name)) ||
agentsOverrides[definition.name]?.enabled === false agentsOverrides[definition.name]?.enabled === false
) { ) {
continue; continue;
+2 -2
View File
@@ -1971,8 +1971,8 @@
"enableAgents": { "enableAgents": {
"title": "Enable Agents", "title": "Enable Agents",
"description": "Enable local and remote subagents.", "description": "Enable local and remote subagents.",
"markdownDescription": "Enable local and remote subagents.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `true`", "markdownDescription": "Enable local and remote subagents.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `false`",
"default": true, "default": false,
"type": "boolean" "type": "boolean"
}, },
"extensionManagement": { "extensionManagement": {