mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-26 13:04:49 -07:00
Fix rough edges around extension updates (#10926)
This commit is contained in:
@@ -36,6 +36,7 @@ import type {
|
||||
AgentStartEvent,
|
||||
AgentFinishEvent,
|
||||
WebFetchFallbackAttemptEvent,
|
||||
ExtensionUpdateEvent,
|
||||
} from '../types.js';
|
||||
import { EventMetadataKey } from './event-metadata-key.js';
|
||||
import type { Config } from '../../config/config.js';
|
||||
@@ -77,6 +78,7 @@ export enum EventNames {
|
||||
EXTENSION_DISABLE = 'extension_disable',
|
||||
EXTENSION_INSTALL = 'extension_install',
|
||||
EXTENSION_UNINSTALL = 'extension_uninstall',
|
||||
EXTENSION_UPDATE = 'extension_update',
|
||||
TOOL_OUTPUT_TRUNCATED = 'tool_output_truncated',
|
||||
MODEL_ROUTING = 'model_routing',
|
||||
MODEL_SLASH_COMMAND = 'model_slash_command',
|
||||
@@ -929,6 +931,38 @@ export class ClearcutLogger {
|
||||
});
|
||||
}
|
||||
|
||||
logExtensionUpdateEvent(event: ExtensionUpdateEvent): void {
|
||||
const data: EventValue[] = [
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME,
|
||||
value: event.extension_name,
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_VERSION,
|
||||
value: event.extension_version,
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_PREVIOUS_VERSION,
|
||||
value: event.extension_previous_version,
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_SOURCE,
|
||||
value: event.extension_source,
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_UPDATE_STATUS,
|
||||
value: event.status,
|
||||
},
|
||||
];
|
||||
|
||||
this.enqueueLogEvent(
|
||||
this.createLogEvent(EventNames.EXTENSION_UPDATE, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
logToolOutputTruncatedEvent(event: ToolOutputTruncatedEvent): void {
|
||||
const data: EventValue[] = [
|
||||
{
|
||||
|
||||
@@ -367,7 +367,7 @@ export enum EventMetadataKey {
|
||||
GEMINI_CLI_NODE_VERSION = 83,
|
||||
|
||||
// ==========================================================================
|
||||
// Extension Install Event Keys
|
||||
// Extension Event Keys
|
||||
// ===========================================================================
|
||||
|
||||
// Logs the name of the extension.
|
||||
@@ -376,6 +376,9 @@ export enum EventMetadataKey {
|
||||
// Logs the version of the extension.
|
||||
GEMINI_CLI_EXTENSION_VERSION = 86,
|
||||
|
||||
// Logs the previous version of the extension.
|
||||
GEMINI_CLI_EXTENSION_PREVIOUS_VERSION = 117,
|
||||
|
||||
// Logs the source of the extension.
|
||||
GEMINI_CLI_EXTENSION_SOURCE = 87,
|
||||
|
||||
@@ -385,6 +388,9 @@ export enum EventMetadataKey {
|
||||
// Logs the status of the extension uninstall
|
||||
GEMINI_CLI_EXTENSION_UNINSTALL_STATUS = 96,
|
||||
|
||||
// Logs the status of the extension uninstall
|
||||
GEMINI_CLI_EXTENSION_UPDATE_STATUS = 118,
|
||||
|
||||
// Logs the setting scope for an extension enablement.
|
||||
GEMINI_CLI_EXTENSION_ENABLE_SETTING_SCOPE = 102,
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ export {
|
||||
logExtensionEnable,
|
||||
logExtensionInstallEvent,
|
||||
logExtensionUninstall,
|
||||
logExtensionUpdateEvent,
|
||||
logWebFetchFallbackAttempt,
|
||||
} from './loggers.js';
|
||||
export type { SlashCommandEvent, ChatCompressionEvent } from './types.js';
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
logAgentStart,
|
||||
logAgentFinish,
|
||||
logWebFetchFallbackAttempt,
|
||||
logExtensionUpdateEvent,
|
||||
} from './loggers.js';
|
||||
import { ToolCallDecision } from './tool-call-decision.js';
|
||||
import {
|
||||
@@ -82,6 +83,8 @@ import {
|
||||
AgentStartEvent,
|
||||
AgentFinishEvent,
|
||||
WebFetchFallbackAttemptEvent,
|
||||
ExtensionUpdateEvent,
|
||||
EVENT_EXTENSION_UPDATE,
|
||||
} from './types.js';
|
||||
import * as metrics from './metrics.js';
|
||||
import {
|
||||
@@ -1292,6 +1295,9 @@ describe('loggers', () => {
|
||||
const mockConfig = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getContentGeneratorConfig: () => null,
|
||||
getUseSmartEdit: () => null,
|
||||
getUseModelRouter: () => null,
|
||||
} as unknown as Config;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -1333,10 +1339,63 @@ describe('loggers', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('logExtensionUpdate', () => {
|
||||
const mockConfig = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getContentGeneratorConfig: () => null,
|
||||
getUseSmartEdit: () => null,
|
||||
getUseModelRouter: () => null,
|
||||
} as unknown as Config;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.spyOn(ClearcutLogger.prototype, 'logExtensionUpdateEvent');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should log extension update event', () => {
|
||||
const event = new ExtensionUpdateEvent(
|
||||
'vscode',
|
||||
'0.1.0',
|
||||
'0.1.1',
|
||||
'git',
|
||||
'success',
|
||||
);
|
||||
|
||||
logExtensionUpdateEvent(mockConfig, event);
|
||||
|
||||
expect(
|
||||
ClearcutLogger.prototype.logExtensionUpdateEvent,
|
||||
).toHaveBeenCalledWith(event);
|
||||
|
||||
expect(mockLogger.emit).toHaveBeenCalledWith({
|
||||
body: 'Updated extension vscode',
|
||||
attributes: {
|
||||
'session.id': 'test-session-id',
|
||||
'user.email': 'test-user@example.com',
|
||||
'installation.id': 'test-installation-id',
|
||||
'event.name': EVENT_EXTENSION_UPDATE,
|
||||
'event.timestamp': '2025-01-01T00:00:00.000Z',
|
||||
extension_name: 'vscode',
|
||||
extension_version: '0.1.0',
|
||||
extension_previous_version: '0.1.1',
|
||||
extension_source: 'git',
|
||||
status: 'success',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('logExtensionUninstall', () => {
|
||||
const mockConfig = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getContentGeneratorConfig: () => null,
|
||||
getUseSmartEdit: () => null,
|
||||
getUseModelRouter: () => null,
|
||||
} as unknown as Config;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -47,6 +47,7 @@ import type {
|
||||
AgentStartEvent,
|
||||
AgentFinishEvent,
|
||||
WebFetchFallbackAttemptEvent,
|
||||
ExtensionUpdateEvent,
|
||||
} from './types.js';
|
||||
import {
|
||||
recordApiErrorMetrics,
|
||||
@@ -531,6 +532,21 @@ export function logExtensionUninstall(
|
||||
logger.emit(logRecord);
|
||||
}
|
||||
|
||||
export function logExtensionUpdateEvent(
|
||||
config: Config,
|
||||
event: ExtensionUpdateEvent,
|
||||
): void {
|
||||
ClearcutLogger.getInstance(config)?.logExtensionUpdateEvent(event);
|
||||
if (!isTelemetrySdkInitialized()) return;
|
||||
|
||||
const logger = logs.getLogger(SERVICE_NAME);
|
||||
const logRecord: LogRecord = {
|
||||
body: event.toLogBody(),
|
||||
attributes: event.toOpenTelemetryAttributes(config),
|
||||
};
|
||||
logger.emit(logRecord);
|
||||
}
|
||||
|
||||
export function logExtensionEnable(
|
||||
config: Config,
|
||||
event: ExtensionEnableEvent,
|
||||
|
||||
@@ -1156,6 +1156,50 @@ export class ExtensionUninstallEvent implements BaseTelemetryEvent {
|
||||
}
|
||||
}
|
||||
|
||||
export const EVENT_EXTENSION_UPDATE = 'gemini_cli.extension_update';
|
||||
export class ExtensionUpdateEvent implements BaseTelemetryEvent {
|
||||
'event.name': 'extension_update';
|
||||
'event.timestamp': string;
|
||||
extension_name: string;
|
||||
extension_previous_version: string;
|
||||
extension_version: string;
|
||||
extension_source: string;
|
||||
status: 'success' | 'error';
|
||||
|
||||
constructor(
|
||||
extension_name: string,
|
||||
extension_version: string,
|
||||
extension_previous_version: string,
|
||||
extension_source: string,
|
||||
status: 'success' | 'error',
|
||||
) {
|
||||
this['event.name'] = 'extension_update';
|
||||
this['event.timestamp'] = new Date().toISOString();
|
||||
this.extension_name = extension_name;
|
||||
this.extension_version = extension_version;
|
||||
this.extension_previous_version = extension_previous_version;
|
||||
this.extension_source = extension_source;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
||||
return {
|
||||
...getCommonAttributes(config),
|
||||
'event.name': EVENT_EXTENSION_UPDATE,
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
extension_name: this.extension_name,
|
||||
extension_version: this.extension_version,
|
||||
extension_previous_version: this.extension_previous_version,
|
||||
extension_source: this.extension_source,
|
||||
status: this.status,
|
||||
};
|
||||
}
|
||||
|
||||
toLogBody(): string {
|
||||
return `Updated extension ${this.extension_name}`;
|
||||
}
|
||||
}
|
||||
|
||||
export const EVENT_EXTENSION_ENABLE = 'gemini_cli.extension_enable';
|
||||
export class ExtensionEnableEvent implements BaseTelemetryEvent {
|
||||
'event.name': 'extension_enable';
|
||||
|
||||
Reference in New Issue
Block a user