feat(telemetry): add browser agent clearcut metrics (#24688)

This commit is contained in:
Gaurav
2026-04-07 15:48:38 +08:00
committed by GitHub
parent 83096c68b0
commit 4c5e887732
10 changed files with 494 additions and 23 deletions
@@ -1692,4 +1692,187 @@ describe('ClearcutLogger', () => {
]);
});
});
describe('logBrowserAgentConnectionEvent', () => {
it('logs a successful connection event', () => {
const { logger } = setup();
logger?.logBrowserAgentConnectionEvent({
session_mode: 'isolated',
headless: true,
success: true,
duration_ms: 1500,
});
const events = getEvents(logger!);
expect(events.length).toBe(1);
expect(events[0]).toHaveEventName(EventNames.BROWSER_AGENT_CONNECTION);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
'isolated',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_HEADLESS,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
'1500',
]);
});
it('logs a failed connection event with error_type', () => {
const { logger } = setup();
logger?.logBrowserAgentConnectionEvent({
session_mode: 'persistent',
headless: false,
success: false,
duration_ms: 30000,
error_type: 'timeout',
});
const events = getEvents(logger!);
expect(events.length).toBe(1);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
'false',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_ERROR_TYPE,
'timeout',
]);
});
it('logs tool_count when provided', () => {
const { logger } = setup();
logger?.logBrowserAgentConnectionEvent({
session_mode: 'existing',
headless: true,
success: true,
duration_ms: 800,
tool_count: 12,
});
const events = getEvents(logger!);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_TOOL_COUNT,
'12',
]);
});
});
describe('logBrowserAgentVisionStatusEvent', () => {
it('logs vision enabled', () => {
const { logger } = setup();
logger?.logBrowserAgentVisionStatusEvent({ enabled: true });
const events = getEvents(logger!);
expect(events.length).toBe(1);
expect(events[0]).toHaveEventName(EventNames.BROWSER_AGENT_VISION_STATUS);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED,
'true',
]);
});
it('logs vision disabled with reason', () => {
const { logger } = setup();
logger?.logBrowserAgentVisionStatusEvent({
enabled: false,
disabled_reason: 'no_visual_model',
});
const events = getEvents(logger!);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED,
'false',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_DISABLED_REASON,
'no_visual_model',
]);
});
});
describe('logBrowserAgentTaskOutcomeEvent', () => {
it('logs a task outcome event with all attributes', () => {
const { logger } = setup();
logger?.logBrowserAgentTaskOutcomeEvent({
success: true,
session_mode: 'isolated',
vision_enabled: true,
headless: true,
duration_ms: 5000,
});
const events = getEvents(logger!);
expect(events.length).toBe(1);
expect(events[0]).toHaveEventName(EventNames.BROWSER_AGENT_TASK_OUTCOME);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
'isolated',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_HEADLESS,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
'5000',
]);
});
});
describe('logBrowserAgentCleanupEvent', () => {
it('logs a cleanup event with all attributes', () => {
const { logger } = setup();
logger?.logBrowserAgentCleanupEvent({
session_mode: 'isolated',
success: true,
duration_ms: 200,
});
const events = getEvents(logger!);
expect(events.length).toBe(1);
expect(events[0]).toHaveEventName(EventNames.BROWSER_AGENT_CLEANUP);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
'isolated',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
'true',
]);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
'200',
]);
});
it('logs a failed cleanup event', () => {
const { logger } = setup();
logger?.logBrowserAgentCleanupEvent({
session_mode: 'persistent',
success: false,
duration_ms: 5000,
});
const events = getEvents(logger!);
expect(events[0]).toHaveMetadataValue([
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
'false',
]);
});
});
});
@@ -135,6 +135,10 @@ export enum EventNames {
OVERAGE_OPTION_SELECTED = 'overage_option_selected',
EMPTY_WALLET_MENU_SHOWN = 'empty_wallet_menu_shown',
CREDIT_PURCHASE_CLICK = 'credit_purchase_click',
BROWSER_AGENT_CONNECTION = 'browser_agent_connection',
BROWSER_AGENT_VISION_STATUS = 'browser_agent_vision_status',
BROWSER_AGENT_TASK_OUTCOME = 'browser_agent_task_outcome',
BROWSER_AGENT_CLEANUP = 'browser_agent_cleanup',
}
export interface LogResponse {
@@ -1935,6 +1939,146 @@ export class ClearcutLogger {
this.flushIfNeeded();
}
// ==========================================================================
// Browser Agent Events
// ==========================================================================
logBrowserAgentConnectionEvent(attrs: {
session_mode: string;
headless: boolean;
success: boolean;
duration_ms: number;
error_type?: string;
tool_count?: number;
}): void {
const data: EventValue[] = [
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
value: attrs.session_mode,
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_HEADLESS,
value: attrs.headless.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
value: attrs.success.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
value: attrs.duration_ms.toString(),
},
];
if (attrs.error_type) {
data.push({
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_ERROR_TYPE,
value: attrs.error_type,
});
}
if (attrs.tool_count !== undefined) {
data.push({
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_TOOL_COUNT,
value: attrs.tool_count.toString(),
});
}
this.enqueueLogEvent(
this.createLogEvent(EventNames.BROWSER_AGENT_CONNECTION, data),
);
this.flushIfNeeded();
}
logBrowserAgentVisionStatusEvent(attrs: {
enabled: boolean;
disabled_reason?: string;
}): void {
const data: EventValue[] = [
{
gemini_cli_key:
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED,
value: attrs.enabled.toString(),
},
];
if (attrs.disabled_reason) {
data.push({
gemini_cli_key:
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_DISABLED_REASON,
value: attrs.disabled_reason,
});
}
this.enqueueLogEvent(
this.createLogEvent(EventNames.BROWSER_AGENT_VISION_STATUS, data),
);
this.flushIfNeeded();
}
logBrowserAgentTaskOutcomeEvent(attrs: {
success: boolean;
session_mode: string;
vision_enabled: boolean;
headless: boolean;
duration_ms: number;
}): void {
const data: EventValue[] = [
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
value: attrs.success.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
value: attrs.session_mode,
},
{
gemini_cli_key:
EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED,
value: attrs.vision_enabled.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_HEADLESS,
value: attrs.headless.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
value: attrs.duration_ms.toString(),
},
];
this.enqueueLogEvent(
this.createLogEvent(EventNames.BROWSER_AGENT_TASK_OUTCOME, data),
);
this.flushIfNeeded();
}
logBrowserAgentCleanupEvent(attrs: {
session_mode: string;
success: boolean;
duration_ms: number;
}): void {
const data: EventValue[] = [
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SESSION_MODE,
value: attrs.session_mode,
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_SUCCESS,
value: attrs.success.toString(),
},
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_BROWSER_AGENT_DURATION_MS,
value: attrs.duration_ms.toString(),
},
];
this.enqueueLogEvent(
this.createLogEvent(EventNames.BROWSER_AGENT_CLEANUP, data),
);
this.flushIfNeeded();
}
/**
* Adds default fields to data, and returns a new data array. This fields
* should exist on all log events.
@@ -7,7 +7,7 @@
// Defines valid event metadata keys for Clearcut logging.
export enum EventMetadataKey {
// Deleted enums: 24
// Next ID: 195
// Next ID: 203
GEMINI_CLI_KEY_UNKNOWN = 0,
@@ -725,4 +725,32 @@ export enum EventMetadataKey {
// Logs the duration of the onboarding process in milliseconds.
GEMINI_CLI_ONBOARDING_DURATION_MS = 194,
// ==========================================================================
// Browser Agent Event Keys
// ==========================================================================
// Logs the browser agent session mode (persistent, isolated, existing).
GEMINI_CLI_BROWSER_AGENT_SESSION_MODE = 195,
// Logs whether the browser agent ran in headless mode.
GEMINI_CLI_BROWSER_AGENT_HEADLESS = 196,
// Logs whether the browser agent operation was successful.
GEMINI_CLI_BROWSER_AGENT_SUCCESS = 197,
// Logs the error type for a browser agent connection failure.
GEMINI_CLI_BROWSER_AGENT_ERROR_TYPE = 198,
// Logs the duration in milliseconds for a browser agent operation.
GEMINI_CLI_BROWSER_AGENT_DURATION_MS = 199,
// Logs whether vision mode was enabled for the browser agent.
GEMINI_CLI_BROWSER_AGENT_VISION_ENABLED = 200,
// Logs the reason vision mode was disabled for the browser agent.
GEMINI_CLI_BROWSER_AGENT_VISION_DISABLED_REASON = 201,
// Logs the number of tools discovered from the MCP server.
GEMINI_CLI_BROWSER_AGENT_TOOL_COUNT = 202,
}