refactor: Introduce dedicated browser agent configuration with session mode, headless, profile path, and visual model settings.

This commit is contained in:
Gaurav Ghosh
2026-02-23 11:52:00 -08:00
parent 52d9271e63
commit 64853dbfde
13 changed files with 179 additions and 77 deletions
@@ -73,11 +73,11 @@ describe('browserAgentFactory', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: false,
},
},
},
browser: {
headless: false,
},
},
});
@@ -160,12 +160,12 @@ describe('browserAgentFactory', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: false,
visualModel: 'gemini-2.5-flash-preview',
},
},
},
browser: {
headless: false,
visualModel: 'gemini-2.5-flash-preview',
},
},
});
@@ -185,12 +185,12 @@ describe('browserAgentFactory', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: false,
visualModel: 'gemini-2.5-flash-preview',
},
},
},
browser: {
headless: false,
visualModel: 'gemini-2.5-flash-preview',
},
},
});
@@ -32,11 +32,12 @@ describe('BrowserAgentInvocation', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: false,
},
},
},
browser: {
headless: false,
sessionMode: 'isolated',
},
},
});
@@ -56,11 +56,11 @@ describe('BrowserManager', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: false,
},
},
},
browser: {
headless: false,
},
},
});
@@ -165,11 +165,11 @@ describe('BrowserManager', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: true,
},
},
},
browser: {
headless: true,
},
},
});
@@ -182,17 +182,17 @@ describe('BrowserManager', () => {
});
});
it('should pass chromeProfilePath as --userDataDir when configured', async () => {
it('should pass profilePath as --userDataDir when configured', async () => {
const profileConfig = makeFakeConfig({
agents: {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
chromeProfilePath: '/path/to/profile',
},
},
},
browser: {
profilePath: '/path/to/profile',
},
},
});
@@ -211,11 +211,11 @@ describe('BrowserManager', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
sessionMode: 'isolated',
},
},
},
browser: {
sessionMode: 'isolated',
},
},
});
@@ -234,11 +234,11 @@ describe('BrowserManager', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
sessionMode: 'existing',
},
},
},
browser: {
sessionMode: 'existing',
},
},
});
@@ -268,11 +268,11 @@ describe('BrowserManager', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
sessionMode: 'existing',
},
},
},
browser: {
sessionMode: 'existing',
},
},
});
@@ -259,11 +259,8 @@ export class BrowserManager {
if (browserConfig.customConfig.headless) {
mcpArgs.push('--headless');
}
if (browserConfig.customConfig.chromeProfilePath) {
mcpArgs.push(
'--userDataDir',
browserConfig.customConfig.chromeProfilePath,
);
if (browserConfig.customConfig.profilePath) {
mcpArgs.push('--userDataDir', browserConfig.customConfig.profilePath);
}
debugLogger.log(
@@ -343,7 +340,7 @@ export class BrowserManager {
`To fix this:\n` +
` 1. Close all Chrome windows using this profile, OR\n` +
` 2. Set sessionMode to "isolated" in settings.json to use a temporary profile, OR\n` +
` 3. Set chromeProfilePath in settings.json to use a different profile directory`,
` 3. Set profilePath in settings.json to use a different profile directory`,
);
}
// existing mode — shouldn't normally hit this, but handle gracefully
+11 -13
View File
@@ -1333,7 +1333,7 @@ describe('Server Config (config.ts)', () => {
expect(browserConfig.model).toBeUndefined();
expect(browserConfig.customConfig.sessionMode).toBe('persistent');
expect(browserConfig.customConfig.headless).toBe(false);
expect(browserConfig.customConfig.chromeProfilePath).toBeUndefined();
expect(browserConfig.customConfig.profilePath).toBeUndefined();
expect(browserConfig.customConfig.visualModel).toBeUndefined();
});
@@ -1345,14 +1345,14 @@ describe('Server Config (config.ts)', () => {
browser_agent: {
enabled: true,
modelConfig: { model: 'custom-model' },
customConfig: {
sessionMode: 'existing',
headless: true,
chromeProfilePath: '/path/to/profile',
visualModel: 'custom-visual-model',
},
},
},
browser: {
sessionMode: 'existing',
headless: true,
profilePath: '/path/to/profile',
visualModel: 'custom-visual-model',
},
},
};
const config = new Config(params);
@@ -1362,9 +1362,7 @@ describe('Server Config (config.ts)', () => {
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.profilePath).toBe('/path/to/profile');
expect(browserConfig.customConfig.visualModel).toBe(
'custom-visual-model',
);
@@ -1377,11 +1375,11 @@ describe('Server Config (config.ts)', () => {
overrides: {
browser_agent: {
enabled: true,
customConfig: {
headless: true,
},
},
},
browser: {
headless: true,
},
},
};
const config = new Config(params);
+4 -10
View File
@@ -202,16 +202,11 @@ 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 {
overrides?: Record<string, AgentOverride>;
browser?: BrowserAgentCustomConfig;
}
export interface CustomTheme {
@@ -281,7 +276,7 @@ export interface BrowserAgentCustomConfig {
/** Run browser in headless mode. Default: false */
headless?: boolean;
/** Path to Chrome profile directory for session persistence. */
chromeProfilePath?: string;
profilePath?: string;
/** Model override for the visual agent. */
visualModel?: string;
}
@@ -2539,15 +2534,14 @@ export class Config {
customConfig: BrowserAgentCustomConfig;
} {
const override = this.getAgentOverride('browser_agent');
const customConfig = (override?.customConfig ??
{}) as BrowserAgentCustomConfig;
const customConfig = this.getAgentsSettings()?.browser ?? {};
return {
enabled: override?.enabled ?? false,
model: override?.modelConfig?.model,
customConfig: {
sessionMode: customConfig.sessionMode ?? 'persistent',
headless: customConfig.headless ?? false,
chromeProfilePath: customConfig.chromeProfilePath,
profilePath: customConfig.profilePath,
visualModel: customConfig.visualModel,
},
};