feat(browser): implement experimental browser agent (#19284)

This commit is contained in:
Gaurav
2026-02-24 09:22:09 -08:00
committed by GitHub
parent 182c858e67
commit 9e95b8b3c5
23 changed files with 3506 additions and 1 deletions

View File

@@ -0,0 +1,139 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { BrowserAgentInvocation } from './browserAgentInvocation.js';
import { makeFakeConfig } from '../../test-utils/config.js';
import type { Config } from '../../config/config.js';
import type { MessageBus } from '../../confirmation-bus/message-bus.js';
import type { AgentInputs } from '../types.js';
// Mock dependencies before imports
vi.mock('../../utils/debugLogger.js', () => ({
debugLogger: {
log: vi.fn(),
error: vi.fn(),
},
}));
describe('BrowserAgentInvocation', () => {
let mockConfig: Config;
let mockMessageBus: MessageBus;
let mockParams: AgentInputs;
beforeEach(() => {
vi.clearAllMocks();
mockConfig = makeFakeConfig({
agents: {
overrides: {
browser_agent: {
enabled: true,
},
},
browser: {
headless: false,
sessionMode: 'isolated',
},
},
});
mockMessageBus = {
publish: vi.fn().mockResolvedValue(undefined),
subscribe: vi.fn(),
unsubscribe: vi.fn(),
} as unknown as MessageBus;
mockParams = {
task: 'Navigate to example.com and click the button',
};
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('constructor', () => {
it('should create invocation with params', () => {
const invocation = new BrowserAgentInvocation(
mockConfig,
mockParams,
mockMessageBus,
);
expect(invocation.params).toEqual(mockParams);
});
it('should use browser_agent as default tool name', () => {
const invocation = new BrowserAgentInvocation(
mockConfig,
mockParams,
mockMessageBus,
);
expect(invocation['_toolName']).toBe('browser_agent');
});
it('should use custom tool name if provided', () => {
const invocation = new BrowserAgentInvocation(
mockConfig,
mockParams,
mockMessageBus,
'custom_name',
'Custom Display Name',
);
expect(invocation['_toolName']).toBe('custom_name');
expect(invocation['_toolDisplayName']).toBe('Custom Display Name');
});
});
describe('getDescription', () => {
it('should return description with input summary', () => {
const invocation = new BrowserAgentInvocation(
mockConfig,
mockParams,
mockMessageBus,
);
const description = invocation.getDescription();
expect(description).toContain('browser agent');
expect(description).toContain('task');
});
it('should truncate long input values', () => {
const longParams = {
task: 'A'.repeat(100),
};
const invocation = new BrowserAgentInvocation(
mockConfig,
longParams,
mockMessageBus,
);
const description = invocation.getDescription();
// Should be truncated to max length
expect(description.length).toBeLessThanOrEqual(200);
});
});
describe('toolLocations', () => {
it('should return empty array by default', () => {
const invocation = new BrowserAgentInvocation(
mockConfig,
mockParams,
mockMessageBus,
);
const locations = invocation.toolLocations();
expect(locations).toEqual([]);
});
});
});