mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Add exp.gws_experiment field to LogEventEntry (#16062)
This commit is contained in:
@@ -93,6 +93,22 @@ expect.extend({
|
|||||||
`event ${received} ${isNot ? 'has' : 'does not have'} the metadata key ${key}`,
|
`event ${received} ${isNot ? 'has' : 'does not have'} the metadata key ${key}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toHaveGwsExperiments(received: LogEventEntry[], exps: number[]) {
|
||||||
|
const { isNot } = this;
|
||||||
|
const gwsExperiment = received[0].exp?.gws_experiment;
|
||||||
|
|
||||||
|
const pass =
|
||||||
|
gwsExperiment !== undefined &&
|
||||||
|
gwsExperiment.length === exps.length &&
|
||||||
|
gwsExperiment.every((val, idx) => val === exps[idx]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
pass,
|
||||||
|
message: () =>
|
||||||
|
`exp.gws_experiment ${JSON.stringify(gwsExperiment)} does${isNot ? '' : ' not'} match ${JSON.stringify(exps)}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
vi.mock('../../utils/userAccountManager.js');
|
vi.mock('../../utils/userAccountManager.js');
|
||||||
@@ -850,19 +866,53 @@ describe('ClearcutLogger', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('logExperiments', () => {
|
describe('logExperiments', () => {
|
||||||
it('logs an event with gws_experiment field containing exp ids', () => {
|
it('async path includes exp.gws_experiment field with experiment IDs', async () => {
|
||||||
const { logger } = setup();
|
const { logger } = setup();
|
||||||
const event = new AgentStartEvent('agent-123', 'TestAgent');
|
const event = logger!.createLogEvent(EventNames.START_SESSION, []);
|
||||||
|
|
||||||
logger?.logAgentStartEvent(event);
|
await logger?.enqueueLogEventAfterExperimentsLoadAsync(event);
|
||||||
|
await vi.runAllTimersAsync();
|
||||||
|
|
||||||
const events = getEvents(logger!);
|
const events = getEvents(logger!);
|
||||||
expect(events.length).toBe(1);
|
expect(events.length).toBe(1);
|
||||||
expect(events[0]).toHaveEventName(EventNames.AGENT_START);
|
expect(events[0]).toHaveEventName(EventNames.START_SESSION);
|
||||||
|
// Both metadata and exp.gws_experiment should be populated
|
||||||
expect(events[0]).toHaveMetadataValue([
|
expect(events[0]).toHaveMetadataValue([
|
||||||
EventMetadataKey.GEMINI_CLI_EXPERIMENT_IDS,
|
EventMetadataKey.GEMINI_CLI_EXPERIMENT_IDS,
|
||||||
'123,456,789',
|
'123,456,789',
|
||||||
]);
|
]);
|
||||||
|
expect(events[0]).toHaveGwsExperiments([123, 456, 789]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('async path includes empty gws_experiment array when no experiments', async () => {
|
||||||
|
const { logger } = setup({
|
||||||
|
config: {
|
||||||
|
experiments: {
|
||||||
|
experimentIds: [],
|
||||||
|
},
|
||||||
|
} as unknown as Partial<ConfigParameters>,
|
||||||
|
});
|
||||||
|
const event = logger!.createLogEvent(EventNames.START_SESSION, []);
|
||||||
|
|
||||||
|
await logger?.enqueueLogEventAfterExperimentsLoadAsync(event);
|
||||||
|
await vi.runAllTimersAsync();
|
||||||
|
|
||||||
|
const events = getEvents(logger!);
|
||||||
|
expect(events.length).toBe(1);
|
||||||
|
expect(events[0]).toHaveGwsExperiments([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('non-async path does not include exp.gws_experiment field', () => {
|
||||||
|
const { logger } = setup();
|
||||||
|
const event = new AgentStartEvent('agent-123', 'TestAgent');
|
||||||
|
|
||||||
|
// logAgentStartEvent uses the non-async enqueueLogEvent path
|
||||||
|
logger?.logAgentStartEvent(event);
|
||||||
|
|
||||||
|
const events = getEvents(logger!);
|
||||||
|
expect(events.length).toBe(1);
|
||||||
|
// exp.gws_experiment should NOT be present for non-async events
|
||||||
|
expect(events[0][0].exp).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ export interface LogResponse {
|
|||||||
export interface LogEventEntry {
|
export interface LogEventEntry {
|
||||||
event_time_ms: number;
|
event_time_ms: number;
|
||||||
source_extension_json: string;
|
source_extension_json: string;
|
||||||
|
exp?: {
|
||||||
|
gws_experiment: number[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventValue {
|
export interface EventValue {
|
||||||
@@ -250,7 +253,7 @@ export class ClearcutLogger {
|
|||||||
ClearcutLogger.instance = undefined;
|
ClearcutLogger.instance = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
enqueueHelper(event: LogEvent): void {
|
enqueueHelper(event: LogEvent, experimentIds?: number[]): void {
|
||||||
// Manually handle overflow for FixedDeque, which throws when full.
|
// Manually handle overflow for FixedDeque, which throws when full.
|
||||||
const wasAtCapacity = this.events.size >= MAX_EVENTS;
|
const wasAtCapacity = this.events.size >= MAX_EVENTS;
|
||||||
|
|
||||||
@@ -258,12 +261,18 @@ export class ClearcutLogger {
|
|||||||
this.events.shift(); // Evict oldest element to make space.
|
this.events.shift(); // Evict oldest element to make space.
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.push([
|
const logEventEntry: LogEventEntry = {
|
||||||
{
|
event_time_ms: Date.now(),
|
||||||
event_time_ms: Date.now(),
|
source_extension_json: safeJsonStringify(event),
|
||||||
source_extension_json: safeJsonStringify(event),
|
};
|
||||||
},
|
|
||||||
]);
|
if (experimentIds !== undefined) {
|
||||||
|
logEventEntry.exp = {
|
||||||
|
gws_experiment: experimentIds,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.events.push([logEventEntry]);
|
||||||
|
|
||||||
if (wasAtCapacity && this.config?.getDebugMode()) {
|
if (wasAtCapacity && this.config?.getDebugMode()) {
|
||||||
debugLogger.debug(
|
debugLogger.debug(
|
||||||
@@ -298,7 +307,7 @@ export class ClearcutLogger {
|
|||||||
event.event_metadata = [[...event.event_metadata[0], ...exp_id_data]];
|
event.event_metadata = [[...event.event_metadata[0], ...exp_id_data]];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.enqueueHelper(event);
|
this.enqueueHelper(event, experiments?.experimentIds);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debugLogger.warn('ClearcutLogger: Failed to enqueue log event.', error);
|
debugLogger.warn('ClearcutLogger: Failed to enqueue log event.', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user