feat(browser): add browser agent settings schema

Add extensible browser agent configuration using the agents.overrides pattern:
- Extended AgentOverride interface with customConfig field for agent-specific settings
- Added BrowserAgentCustomConfig type for browser-specific configuration
- Added getAgentOverride() and getBrowserAgentConfig() methods to Config class
- Settings configured via agents.overrides.browser_agent.customConfig
- Updated settings schema with customConfig in AgentOverride definition

This establishes the foundational pattern for configuring the browser agent
through the standard agents.overrides infrastructure.
This commit is contained in:
Gaurav Ghosh
2026-01-06 05:10:59 +00:00
parent 7cfbb6fb71
commit 0b93c868e9
3 changed files with 135 additions and 0 deletions
@@ -2275,6 +2275,12 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record<
type: 'boolean',
description: 'Whether to enable the agent.',
},
customConfig: {
type: 'object',
description:
'Agent-specific custom configuration. Each agent defines its own schema.',
additionalProperties: true,
},
},
},
CustomTheme: {
+70
View File
@@ -1323,6 +1323,76 @@ describe('Server Config (config.ts)', () => {
expect(mockCoreEvents.emitFeedback).not.toHaveBeenCalled();
});
});
describe('BrowserAgentConfig', () => {
it('should return default browser agent config when not provided', () => {
const config = new Config(baseParams);
const browserConfig = config.getBrowserAgentConfig();
expect(browserConfig.enabled).toBe(false);
expect(browserConfig.model).toBeUndefined();
expect(browserConfig.customConfig.sessionMode).toBe('isolated');
expect(browserConfig.customConfig.headless).toBe(false);
expect(browserConfig.customConfig.chromeProfilePath).toBeUndefined();
expect(browserConfig.customConfig.visualModel).toBeUndefined();
});
it('should return custom browser agent config from agents.overrides', () => {
const params: ConfigParameters = {
...baseParams,
agents: {
overrides: {
browser_agent: {
enabled: true,
modelConfig: { model: 'custom-model' },
customConfig: {
sessionMode: 'existing',
headless: true,
chromeProfilePath: '/path/to/profile',
visualModel: 'custom-visual-model',
},
},
},
},
};
const config = new Config(params);
const browserConfig = config.getBrowserAgentConfig();
expect(browserConfig.enabled).toBe(true);
expect(browserConfig.model).toBe('custom-model');
expect(browserConfig.customConfig.sessionMode).toBe('existing');
expect(browserConfig.customConfig.headless).toBe(true);
expect(browserConfig.customConfig.chromeProfilePath).toBe(
'/path/to/profile',
);
expect(browserConfig.customConfig.visualModel).toBe(
'custom-visual-model',
);
});
it('should apply defaults for partial custom config', () => {
const params: ConfigParameters = {
...baseParams,
agents: {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: true,
},
},
},
},
};
const config = new Config(params);
const browserConfig = config.getBrowserAgentConfig();
expect(browserConfig.enabled).toBe(true);
expect(browserConfig.customConfig.headless).toBe(true);
// Defaults for unspecified fields
expect(browserConfig.customConfig.sessionMode).toBe('isolated');
});
});
});
describe('setApprovalMode with folder trust', () => {
+59
View File
@@ -193,10 +193,21 @@ export interface AgentRunConfig {
maxTurns?: number;
}
/**
* Override configuration for a specific agent.
* Generic fields (modelConfig, runConfig, enabled) are standard across all agents.
* Agent-specific settings go in customConfig - each agent defines its own type.
*/
export interface AgentOverride {
modelConfig?: ModelConfig;
runConfig?: AgentRunConfig;
enabled?: boolean;
/**
* Agent-specific custom configuration.
* Each agent defines and documents its own customConfig structure.
* Example: browser_agent uses BrowserAgentCustomConfig for sessionMode, headless, etc.
*/
customConfig?: Record<string, unknown>;
}
export interface AgentSettings {
@@ -254,6 +265,21 @@ export interface CustomTheme {
GradientColors?: string[];
}
/**
* Browser agent custom configuration.
* Used in agents.overrides.browser_agent.customConfig
*/
export interface BrowserAgentCustomConfig {
/** Session mode: 'isolated' (launch new browser) or 'existing' (attach to Chrome M144+). Default: 'isolated' */
sessionMode?: 'isolated' | 'existing';
/** Run browser in headless mode. Default: false */
headless?: boolean;
/** Path to Chrome profile directory for session persistence. */
chromeProfilePath?: string;
/** Model override for the visual agent. */
visualModel?: string;
}
/**
* All information required in CLI to handle an extension. Defined in Core so
* that the collection of loaded, active, and inactive extensions can be passed
@@ -2488,6 +2514,39 @@ export class Config {
return this.enableHooksUI;
}
/**
* Get override settings for a specific agent.
* Reads from agents.overrides.<agentName>.
*/
getAgentOverride(agentName: string): AgentOverride | undefined {
return this.getAgentsSettings()?.overrides?.[agentName];
}
/**
* Get browser agent configuration.
* Combines generic AgentOverride fields with browser-specific customConfig.
* This is the canonical way to access browser agent settings.
*/
getBrowserAgentConfig(): {
enabled: boolean;
model?: string;
customConfig: BrowserAgentCustomConfig;
} {
const override = this.getAgentOverride('browser_agent');
const customConfig = (override?.customConfig ??
{}) as BrowserAgentCustomConfig;
return {
enabled: override?.enabled ?? false,
model: override?.modelConfig?.model,
customConfig: {
sessionMode: customConfig.sessionMode ?? 'isolated',
headless: customConfig.headless ?? false,
chromeProfilePath: customConfig.chromeProfilePath,
visualModel: customConfig.visualModel,
},
};
}
async createToolRegistry(): Promise<ToolRegistry> {
const registry = new ToolRegistry(this, this.messageBus);