mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-12 07:01:09 -07:00
chore(core): reassign telemetry keys to avoid server conflict (#18161)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
@@ -122,7 +122,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL,
|
||||
metadata: {
|
||||
source: 'Classifier (Control)',
|
||||
source: 'NumericalClassifier (Control)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 40 / Threshold: 50'),
|
||||
},
|
||||
@@ -148,7 +148,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_MODEL,
|
||||
metadata: {
|
||||
source: 'Classifier (Control)',
|
||||
source: 'NumericalClassifier (Control)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 60 / Threshold: 50'),
|
||||
},
|
||||
@@ -174,7 +174,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL, // Routed to Flash because 60 < 80
|
||||
metadata: {
|
||||
source: 'Classifier (Strict)',
|
||||
source: 'NumericalClassifier (Strict)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 60 / Threshold: 80'),
|
||||
},
|
||||
@@ -200,7 +200,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_MODEL,
|
||||
metadata: {
|
||||
source: 'Classifier (Strict)',
|
||||
source: 'NumericalClassifier (Strict)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 90 / Threshold: 80'),
|
||||
},
|
||||
@@ -228,7 +228,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL, // Score 60 < Threshold 70
|
||||
metadata: {
|
||||
source: 'Classifier (Remote)',
|
||||
source: 'NumericalClassifier (Remote)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 60 / Threshold: 70'),
|
||||
},
|
||||
@@ -254,7 +254,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL, // Score 40 < Threshold 45.5
|
||||
metadata: {
|
||||
source: 'Classifier (Remote)',
|
||||
source: 'NumericalClassifier (Remote)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 40 / Threshold: 45.5'),
|
||||
},
|
||||
@@ -280,7 +280,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_MODEL, // Score 35 >= Threshold 30
|
||||
metadata: {
|
||||
source: 'Classifier (Remote)',
|
||||
source: 'NumericalClassifier (Remote)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 35 / Threshold: 30'),
|
||||
},
|
||||
@@ -308,7 +308,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL, // Score 40 < Default A/B Threshold 50
|
||||
metadata: {
|
||||
source: 'Classifier (Control)',
|
||||
source: 'NumericalClassifier (Control)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 40 / Threshold: 50'),
|
||||
},
|
||||
@@ -335,7 +335,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_FLASH_MODEL,
|
||||
metadata: {
|
||||
source: 'Classifier (Control)',
|
||||
source: 'NumericalClassifier (Control)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 40 / Threshold: 50'),
|
||||
},
|
||||
@@ -362,7 +362,7 @@ describe('NumericalClassifierStrategy', () => {
|
||||
expect(decision).toEqual({
|
||||
model: DEFAULT_GEMINI_MODEL,
|
||||
metadata: {
|
||||
source: 'Classifier (Control)',
|
||||
source: 'NumericalClassifier (Control)',
|
||||
latencyMs: expect.any(Number),
|
||||
reasoning: expect.stringContaining('Score: 60 / Threshold: 50'),
|
||||
},
|
||||
|
||||
@@ -187,7 +187,7 @@ export class NumericalClassifierStrategy implements RoutingStrategy {
|
||||
return {
|
||||
model: selectedModel,
|
||||
metadata: {
|
||||
source: `Classifier (${groupLabel})`,
|
||||
source: `NumericalClassifier (${groupLabel})`,
|
||||
latencyMs,
|
||||
reasoning: `[Score: ${score} / Threshold: ${threshold}] ${routerResponse.complexity_reasoning}`,
|
||||
},
|
||||
|
||||
@@ -941,6 +941,38 @@ describe('ClearcutLogger', () => {
|
||||
'Something went wrong',
|
||||
]);
|
||||
});
|
||||
|
||||
it('logs a successful routing event with numerical routing fields', () => {
|
||||
const { logger } = setup();
|
||||
const event = new ModelRoutingEvent(
|
||||
'gemini-pro',
|
||||
'NumericalClassifier (Strict)',
|
||||
123,
|
||||
'[Score: 90 / Threshold: 80] reasoning',
|
||||
false,
|
||||
undefined,
|
||||
true,
|
||||
'80',
|
||||
);
|
||||
|
||||
logger?.logModelRoutingEvent(event);
|
||||
|
||||
const events = getEvents(logger!);
|
||||
expect(events.length).toBe(1);
|
||||
expect(events[0]).toHaveEventName(EventNames.MODEL_ROUTING);
|
||||
expect(events[0]).toHaveMetadataValue([
|
||||
EventMetadataKey.GEMINI_CLI_ROUTING_REASONING,
|
||||
'[Score: 90 / Threshold: 80] reasoning',
|
||||
]);
|
||||
expect(events[0]).toHaveMetadataValue([
|
||||
EventMetadataKey.GEMINI_CLI_ROUTING_NUMERICAL_ENABLED,
|
||||
'true',
|
||||
]);
|
||||
expect(events[0]).toHaveMetadataValue([
|
||||
EventMetadataKey.GEMINI_CLI_ROUTING_CLASSIFIER_THRESHOLD,
|
||||
'80',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logAgentStartEvent', () => {
|
||||
|
||||
@@ -1234,6 +1234,28 @@ export class ClearcutLogger {
|
||||
});
|
||||
}
|
||||
|
||||
if (event.reasoning && this.config?.getTelemetryLogPromptsEnabled()) {
|
||||
data.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_ROUTING_REASONING,
|
||||
value: event.reasoning,
|
||||
});
|
||||
}
|
||||
|
||||
if (event.enable_numerical_routing !== undefined) {
|
||||
data.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_ROUTING_NUMERICAL_ENABLED,
|
||||
value: event.enable_numerical_routing.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
if (event.classifier_threshold) {
|
||||
data.push({
|
||||
gemini_cli_key:
|
||||
EventMetadataKey.GEMINI_CLI_ROUTING_CLASSIFIER_THRESHOLD,
|
||||
value: event.classifier_threshold,
|
||||
});
|
||||
}
|
||||
|
||||
this.enqueueLogEvent(this.createLogEvent(EventNames.MODEL_ROUTING, data));
|
||||
this.flushIfNeeded();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Defines valid event metadata keys for Clearcut logging.
|
||||
export enum EventMetadataKey {
|
||||
// Deleted enums: 24
|
||||
// Next ID: 144
|
||||
// Next ID: 148
|
||||
|
||||
GEMINI_CLI_KEY_UNKNOWN = 0,
|
||||
|
||||
@@ -542,4 +542,17 @@ export enum EventMetadataKey {
|
||||
|
||||
// Logs the duration spent in an approval mode in milliseconds.
|
||||
GEMINI_CLI_APPROVAL_MODE_DURATION_MS = 143,
|
||||
|
||||
// ==========================================================================
|
||||
// Model Routing Event Keys (Cont.)
|
||||
// ==========================================================================
|
||||
|
||||
// Logs the reasoning for the routing decision.
|
||||
GEMINI_CLI_ROUTING_REASONING = 145,
|
||||
|
||||
// Logs whether numerical routing was enabled.
|
||||
GEMINI_CLI_ROUTING_NUMERICAL_ENABLED = 146,
|
||||
|
||||
// Logs the classifier threshold used.
|
||||
GEMINI_CLI_ROUTING_CLASSIFIER_THRESHOLD = 147,
|
||||
}
|
||||
|
||||
@@ -1734,6 +1734,37 @@ describe('loggers', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should log the event with numerical routing fields', () => {
|
||||
const event = new ModelRoutingEvent(
|
||||
'gemini-pro',
|
||||
'NumericalClassifier (Strict)',
|
||||
150,
|
||||
'[Score: 90 / Threshold: 80] reasoning',
|
||||
false,
|
||||
undefined,
|
||||
true,
|
||||
'80',
|
||||
);
|
||||
|
||||
logModelRouting(mockConfig, event);
|
||||
|
||||
expect(
|
||||
ClearcutLogger.prototype.logModelRoutingEvent,
|
||||
).toHaveBeenCalledWith(event);
|
||||
|
||||
expect(mockLogger.emit).toHaveBeenCalledWith({
|
||||
body: 'Model routing decision. Model: gemini-pro, Source: NumericalClassifier (Strict)',
|
||||
attributes: {
|
||||
'session.id': 'test-session-id',
|
||||
'user.email': 'test-user@example.com',
|
||||
'installation.id': 'test-installation-id',
|
||||
...event,
|
||||
'event.name': EVENT_MODEL_ROUTING,
|
||||
interactive: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should only log to Clearcut if OTEL SDK is not initialized', () => {
|
||||
vi.spyOn(sdk, 'isTelemetrySdkInitialized').mockReturnValue(false);
|
||||
vi.spyOn(sdk, 'bufferTelemetryEvent').mockImplementation(() => {});
|
||||
|
||||
@@ -489,7 +489,7 @@ describe('Telemetry Metrics', () => {
|
||||
initializeMetricsModule(mockConfig);
|
||||
const event = new ModelRoutingEvent(
|
||||
'gemini-pro',
|
||||
'classifier',
|
||||
'Classifier',
|
||||
200,
|
||||
'test-reason',
|
||||
true,
|
||||
@@ -502,7 +502,7 @@ describe('Telemetry Metrics', () => {
|
||||
'installation.id': 'test-installation-id',
|
||||
'user.email': 'test@example.com',
|
||||
'routing.decision_model': 'gemini-pro',
|
||||
'routing.decision_source': 'classifier',
|
||||
'routing.decision_source': 'Classifier',
|
||||
'routing.failed': true,
|
||||
'routing.reasoning': 'test-reason',
|
||||
});
|
||||
@@ -513,7 +513,7 @@ describe('Telemetry Metrics', () => {
|
||||
'installation.id': 'test-installation-id',
|
||||
'user.email': 'test@example.com',
|
||||
'routing.decision_model': 'gemini-pro',
|
||||
'routing.decision_source': 'classifier',
|
||||
'routing.decision_source': 'Classifier',
|
||||
'routing.failed': true,
|
||||
'routing.reasoning': 'test-reason',
|
||||
'routing.error_message': 'test-error',
|
||||
|
||||
Reference in New Issue
Block a user