@google/gemini-cli-core 0.8.0-nightly.20250930.ddcbd0c2 → 0.8.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/src/agents/codebase-investigator.d.ts +11 -0
  2. package/dist/src/agents/codebase-investigator.js +73 -0
  3. package/dist/src/agents/codebase-investigator.js.map +1 -0
  4. package/dist/src/agents/executor.d.ts +88 -0
  5. package/dist/src/agents/executor.js +417 -0
  6. package/dist/src/agents/executor.js.map +1 -0
  7. package/dist/src/agents/executor.test.d.ts +6 -0
  8. package/dist/src/agents/executor.test.js +419 -0
  9. package/dist/src/agents/executor.test.js.map +1 -0
  10. package/dist/src/agents/invocation.d.ts +43 -0
  11. package/dist/src/agents/invocation.js +100 -0
  12. package/dist/src/agents/invocation.js.map +1 -0
  13. package/dist/src/agents/invocation.test.d.ts +6 -0
  14. package/dist/src/agents/invocation.test.js +206 -0
  15. package/dist/src/agents/invocation.test.js.map +1 -0
  16. package/dist/src/agents/registry.d.ts +35 -0
  17. package/dist/src/agents/registry.js +58 -0
  18. package/dist/src/agents/registry.js.map +1 -0
  19. package/dist/src/agents/registry.test.d.ts +6 -0
  20. package/dist/src/agents/registry.test.js +146 -0
  21. package/dist/src/agents/registry.test.js.map +1 -0
  22. package/dist/src/agents/schema-utils.d.ts +39 -0
  23. package/dist/src/agents/schema-utils.js +57 -0
  24. package/dist/src/agents/schema-utils.js.map +1 -0
  25. package/dist/src/agents/schema-utils.test.d.ts +6 -0
  26. package/dist/src/agents/schema-utils.test.js +144 -0
  27. package/dist/src/agents/schema-utils.test.js.map +1 -0
  28. package/dist/src/agents/subagent-tool-wrapper.d.ts +36 -0
  29. package/dist/src/agents/subagent-tool-wrapper.js +47 -0
  30. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
  31. package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
  32. package/dist/src/agents/subagent-tool-wrapper.test.js +105 -0
  33. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
  34. package/dist/src/agents/types.d.ts +116 -0
  35. package/dist/src/agents/types.js +17 -0
  36. package/dist/src/agents/types.js.map +1 -0
  37. package/dist/src/agents/utils.d.ts +15 -0
  38. package/dist/src/agents/utils.js +29 -0
  39. package/dist/src/agents/utils.js.map +1 -0
  40. package/dist/src/agents/utils.test.d.ts +6 -0
  41. package/dist/src/agents/utils.test.js +87 -0
  42. package/dist/src/agents/utils.test.js.map +1 -0
  43. package/dist/src/generated/git-commit.d.ts +2 -2
  44. package/dist/src/generated/git-commit.js +2 -2
  45. package/dist/src/generated/git-commit.js.map +1 -1
  46. package/dist/src/ide/detect-ide.d.ts +1 -0
  47. package/dist/src/ide/detect-ide.js +4 -1
  48. package/dist/src/ide/detect-ide.js.map +1 -1
  49. package/dist/src/services/shellExecutionService.d.ts +2 -0
  50. package/dist/src/services/shellExecutionService.js +48 -7
  51. package/dist/src/services/shellExecutionService.js.map +1 -1
  52. package/dist/src/services/shellExecutionService.test.js +13 -4
  53. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  54. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +4 -1
  55. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  56. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +18 -0
  57. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  58. package/dist/src/telemetry/constants.d.ts +0 -24
  59. package/dist/src/telemetry/constants.js +0 -25
  60. package/dist/src/telemetry/constants.js.map +1 -1
  61. package/dist/src/telemetry/loggers.js +42 -9
  62. package/dist/src/telemetry/loggers.js.map +1 -1
  63. package/dist/src/telemetry/loggers.test.js +39 -8
  64. package/dist/src/telemetry/loggers.test.js.map +1 -1
  65. package/dist/src/telemetry/metrics.d.ts +278 -19
  66. package/dist/src/telemetry/metrics.js +303 -235
  67. package/dist/src/telemetry/metrics.js.map +1 -1
  68. package/dist/src/telemetry/metrics.test.js +191 -54
  69. package/dist/src/telemetry/metrics.test.js.map +1 -1
  70. package/dist/src/tools/smart-edit.js +56 -0
  71. package/dist/src/tools/smart-edit.js.map +1 -1
  72. package/dist/src/tools/smart-edit.test.js +19 -0
  73. package/dist/src/tools/smart-edit.test.js.map +1 -1
  74. package/dist/src/utils/llm-edit-fixer.js +10 -1
  75. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  76. package/dist/src/utils/llm-edit-fixer.test.js +81 -0
  77. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  78. package/dist/src/utils/memoryImportProcessor.js +13 -20
  79. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  80. package/dist/src/utils/memoryImportProcessor.test.js +14 -0
  81. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  82. package/dist/src/utils/terminalSerializer.d.ts +1 -4
  83. package/dist/src/utils/terminalSerializer.js +3 -3
  84. package/dist/src/utils/terminalSerializer.js.map +1 -1
  85. package/dist/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +1 -1
@@ -4,9 +4,208 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { diag, metrics, ValueType } from '@opentelemetry/api';
7
- import { SERVICE_NAME, METRIC_TOOL_CALL_COUNT, METRIC_TOOL_CALL_LATENCY, METRIC_API_REQUEST_COUNT, METRIC_API_REQUEST_LATENCY, METRIC_TOKEN_USAGE, METRIC_SESSION_COUNT, METRIC_FILE_OPERATION_COUNT, EVENT_CHAT_COMPRESSION, METRIC_INVALID_CHUNK_COUNT, METRIC_CONTENT_RETRY_COUNT, METRIC_CONTENT_RETRY_FAILURE_COUNT, METRIC_MODEL_ROUTING_LATENCY, METRIC_MODEL_ROUTING_FAILURE_COUNT, METRIC_MODEL_SLASH_COMMAND_CALL_COUNT,
7
+ import { SERVICE_NAME, EVENT_CHAT_COMPRESSION } from './constants.js';
8
+ const TOOL_CALL_COUNT = 'gemini_cli.tool.call.count';
9
+ const TOOL_CALL_LATENCY = 'gemini_cli.tool.call.latency';
10
+ const API_REQUEST_COUNT = 'gemini_cli.api.request.count';
11
+ const API_REQUEST_LATENCY = 'gemini_cli.api.request.latency';
12
+ const TOKEN_USAGE = 'gemini_cli.token.usage';
13
+ const SESSION_COUNT = 'gemini_cli.session.count';
14
+ const FILE_OPERATION_COUNT = 'gemini_cli.file.operation.count';
15
+ const INVALID_CHUNK_COUNT = 'gemini_cli.chat.invalid_chunk.count';
16
+ const CONTENT_RETRY_COUNT = 'gemini_cli.chat.content_retry.count';
17
+ const CONTENT_RETRY_FAILURE_COUNT = 'gemini_cli.chat.content_retry_failure.count';
18
+ const MODEL_ROUTING_LATENCY = 'gemini_cli.model_routing.latency';
19
+ const MODEL_ROUTING_FAILURE_COUNT = 'gemini_cli.model_routing.failure.count';
20
+ const MODEL_SLASH_COMMAND_CALL_COUNT = 'gemini_cli.slash_command.model.call_count';
8
21
  // Performance Monitoring Metrics
9
- METRIC_STARTUP_TIME, METRIC_MEMORY_USAGE, METRIC_CPU_USAGE, METRIC_TOOL_QUEUE_DEPTH, METRIC_TOOL_EXECUTION_BREAKDOWN, METRIC_TOKEN_EFFICIENCY, METRIC_API_REQUEST_BREAKDOWN, METRIC_PERFORMANCE_SCORE, METRIC_REGRESSION_DETECTION, METRIC_REGRESSION_PERCENTAGE_CHANGE, METRIC_BASELINE_COMPARISON, } from './constants.js';
22
+ const STARTUP_TIME = 'gemini_cli.startup.duration';
23
+ const MEMORY_USAGE = 'gemini_cli.memory.usage';
24
+ const CPU_USAGE = 'gemini_cli.cpu.usage';
25
+ const TOOL_QUEUE_DEPTH = 'gemini_cli.tool.queue.depth';
26
+ const TOOL_EXECUTION_BREAKDOWN = 'gemini_cli.tool.execution.breakdown';
27
+ const TOKEN_EFFICIENCY = 'gemini_cli.token.efficiency';
28
+ const API_REQUEST_BREAKDOWN = 'gemini_cli.api.request.breakdown';
29
+ const PERFORMANCE_SCORE = 'gemini_cli.performance.score';
30
+ const REGRESSION_DETECTION = 'gemini_cli.performance.regression';
31
+ const REGRESSION_PERCENTAGE_CHANGE = 'gemini_cli.performance.regression.percentage_change';
32
+ const BASELINE_COMPARISON = 'gemini_cli.performance.baseline.comparison';
33
+ const baseMetricDefinition = {
34
+ getCommonAttributes: (config) => ({
35
+ 'session.id': config.getSessionId(),
36
+ }),
37
+ };
38
+ const COUNTER_DEFINITIONS = {
39
+ [TOOL_CALL_COUNT]: {
40
+ description: 'Counts tool calls, tagged by function name and success.',
41
+ valueType: ValueType.INT,
42
+ assign: (c) => (toolCallCounter = c),
43
+ attributes: {},
44
+ },
45
+ [API_REQUEST_COUNT]: {
46
+ description: 'Counts API requests, tagged by model and status.',
47
+ valueType: ValueType.INT,
48
+ assign: (c) => (apiRequestCounter = c),
49
+ attributes: {},
50
+ },
51
+ [TOKEN_USAGE]: {
52
+ description: 'Counts the total number of tokens used.',
53
+ valueType: ValueType.INT,
54
+ assign: (c) => (tokenUsageCounter = c),
55
+ attributes: {},
56
+ },
57
+ [SESSION_COUNT]: {
58
+ description: 'Count of CLI sessions started.',
59
+ valueType: ValueType.INT,
60
+ assign: (c) => (sessionCounter = c),
61
+ attributes: {},
62
+ },
63
+ [FILE_OPERATION_COUNT]: {
64
+ description: 'Counts file operations (create, read, update).',
65
+ valueType: ValueType.INT,
66
+ assign: (c) => (fileOperationCounter = c),
67
+ attributes: {},
68
+ },
69
+ [INVALID_CHUNK_COUNT]: {
70
+ description: 'Counts invalid chunks received from a stream.',
71
+ valueType: ValueType.INT,
72
+ assign: (c) => (invalidChunkCounter = c),
73
+ attributes: {},
74
+ },
75
+ [CONTENT_RETRY_COUNT]: {
76
+ description: 'Counts retries due to content errors (e.g., empty stream).',
77
+ valueType: ValueType.INT,
78
+ assign: (c) => (contentRetryCounter = c),
79
+ attributes: {},
80
+ },
81
+ [CONTENT_RETRY_FAILURE_COUNT]: {
82
+ description: 'Counts occurrences of all content retries failing.',
83
+ valueType: ValueType.INT,
84
+ assign: (c) => (contentRetryFailureCounter = c),
85
+ attributes: {},
86
+ },
87
+ [MODEL_ROUTING_FAILURE_COUNT]: {
88
+ description: 'Counts model routing failures.',
89
+ valueType: ValueType.INT,
90
+ assign: (c) => (modelRoutingFailureCounter = c),
91
+ attributes: {},
92
+ },
93
+ [MODEL_SLASH_COMMAND_CALL_COUNT]: {
94
+ description: 'Counts model slash command calls.',
95
+ valueType: ValueType.INT,
96
+ assign: (c) => (modelSlashCommandCallCounter = c),
97
+ attributes: {},
98
+ },
99
+ [EVENT_CHAT_COMPRESSION]: {
100
+ description: 'Counts chat compression events.',
101
+ valueType: ValueType.INT,
102
+ assign: (c) => (chatCompressionCounter = c),
103
+ attributes: {},
104
+ },
105
+ };
106
+ const HISTOGRAM_DEFINITIONS = {
107
+ [TOOL_CALL_LATENCY]: {
108
+ description: 'Latency of tool calls in milliseconds.',
109
+ unit: 'ms',
110
+ valueType: ValueType.INT,
111
+ assign: (h) => (toolCallLatencyHistogram = h),
112
+ attributes: {},
113
+ },
114
+ [API_REQUEST_LATENCY]: {
115
+ description: 'Latency of API requests in milliseconds.',
116
+ unit: 'ms',
117
+ valueType: ValueType.INT,
118
+ assign: (h) => (apiRequestLatencyHistogram = h),
119
+ attributes: {},
120
+ },
121
+ [MODEL_ROUTING_LATENCY]: {
122
+ description: 'Latency of model routing decisions in milliseconds.',
123
+ unit: 'ms',
124
+ valueType: ValueType.INT,
125
+ assign: (h) => (modelRoutingLatencyHistogram = h),
126
+ attributes: {},
127
+ },
128
+ };
129
+ const PERFORMANCE_COUNTER_DEFINITIONS = {
130
+ [REGRESSION_DETECTION]: {
131
+ description: 'Performance regression detection events.',
132
+ valueType: ValueType.INT,
133
+ assign: (c) => (regressionDetectionCounter = c),
134
+ attributes: {},
135
+ },
136
+ };
137
+ const PERFORMANCE_HISTOGRAM_DEFINITIONS = {
138
+ [STARTUP_TIME]: {
139
+ description: 'CLI startup time in milliseconds, broken down by initialization phase.',
140
+ unit: 'ms',
141
+ valueType: ValueType.DOUBLE,
142
+ assign: (h) => (startupTimeHistogram = h),
143
+ attributes: {},
144
+ },
145
+ [MEMORY_USAGE]: {
146
+ description: 'Memory usage in bytes.',
147
+ unit: 'bytes',
148
+ valueType: ValueType.INT,
149
+ assign: (h) => (memoryUsageGauge = h),
150
+ attributes: {},
151
+ },
152
+ [CPU_USAGE]: {
153
+ description: 'CPU usage percentage.',
154
+ unit: 'percent',
155
+ valueType: ValueType.DOUBLE,
156
+ assign: (h) => (cpuUsageGauge = h),
157
+ attributes: {},
158
+ },
159
+ [TOOL_QUEUE_DEPTH]: {
160
+ description: 'Number of tools in execution queue.',
161
+ unit: 'count',
162
+ valueType: ValueType.INT,
163
+ assign: (h) => (toolQueueDepthGauge = h),
164
+ attributes: {},
165
+ },
166
+ [TOOL_EXECUTION_BREAKDOWN]: {
167
+ description: 'Tool execution time breakdown by phase in milliseconds.',
168
+ unit: 'ms',
169
+ valueType: ValueType.INT,
170
+ assign: (h) => (toolExecutionBreakdownHistogram = h),
171
+ attributes: {},
172
+ },
173
+ [TOKEN_EFFICIENCY]: {
174
+ description: 'Token efficiency metrics (tokens per operation, cache hit rate, etc.).',
175
+ unit: 'ratio',
176
+ valueType: ValueType.DOUBLE,
177
+ assign: (h) => (tokenEfficiencyHistogram = h),
178
+ attributes: {},
179
+ },
180
+ [API_REQUEST_BREAKDOWN]: {
181
+ description: 'API request time breakdown by phase in milliseconds.',
182
+ unit: 'ms',
183
+ valueType: ValueType.INT,
184
+ assign: (h) => (apiRequestBreakdownHistogram = h),
185
+ attributes: {},
186
+ },
187
+ [PERFORMANCE_SCORE]: {
188
+ description: 'Composite performance score (0-100).',
189
+ unit: 'score',
190
+ valueType: ValueType.DOUBLE,
191
+ assign: (h) => (performanceScoreGauge = h),
192
+ attributes: {},
193
+ },
194
+ [REGRESSION_PERCENTAGE_CHANGE]: {
195
+ description: 'Percentage change compared to baseline for detected regressions.',
196
+ unit: 'percent',
197
+ valueType: ValueType.DOUBLE,
198
+ assign: (h) => (regressionPercentageChangeHistogram = h),
199
+ attributes: {},
200
+ },
201
+ [BASELINE_COMPARISON]: {
202
+ description: 'Performance comparison to established baseline (percentage change).',
203
+ unit: 'percent',
204
+ valueType: ValueType.DOUBLE,
205
+ assign: (h) => (baselineComparisonHistogram = h),
206
+ attributes: {},
207
+ },
208
+ };
10
209
  export var FileOperation;
11
210
  (function (FileOperation) {
12
211
  FileOperation["CREATE"] = "create";
@@ -49,6 +248,7 @@ let toolCallLatencyHistogram;
49
248
  let apiRequestCounter;
50
249
  let apiRequestLatencyHistogram;
51
250
  let tokenUsageCounter;
251
+ let sessionCounter;
52
252
  let fileOperationCounter;
53
253
  let chatCompressionCounter;
54
254
  let invalidChunkCounter;
@@ -71,11 +271,6 @@ let regressionPercentageChangeHistogram;
71
271
  let baselineComparisonHistogram;
72
272
  let isMetricsInitialized = false;
73
273
  let isPerformanceMonitoringEnabled = false;
74
- function getCommonAttributes(config) {
75
- return {
76
- 'session.id': config.getSessionId(),
77
- };
78
- }
79
274
  export function getMeter() {
80
275
  if (!cliMeter) {
81
276
  cliMeter = metrics.getMeter(SERVICE_NAME);
@@ -89,154 +284,87 @@ export function initializeMetrics(config) {
89
284
  if (!meter)
90
285
  return;
91
286
  // Initialize core metrics
92
- toolCallCounter = meter.createCounter(METRIC_TOOL_CALL_COUNT, {
93
- description: 'Counts tool calls, tagged by function name and success.',
94
- valueType: ValueType.INT,
287
+ Object.entries(COUNTER_DEFINITIONS).forEach(([name, { description, valueType, assign }]) => {
288
+ assign(meter.createCounter(name, { description, valueType }));
95
289
  });
96
- toolCallLatencyHistogram = meter.createHistogram(METRIC_TOOL_CALL_LATENCY, {
97
- description: 'Latency of tool calls in milliseconds.',
98
- unit: 'ms',
99
- valueType: ValueType.INT,
290
+ Object.entries(HISTOGRAM_DEFINITIONS).forEach(([name, { description, unit, valueType, assign }]) => {
291
+ assign(meter.createHistogram(name, { description, unit, valueType }));
100
292
  });
101
- apiRequestCounter = meter.createCounter(METRIC_API_REQUEST_COUNT, {
102
- description: 'Counts API requests, tagged by model and status.',
103
- valueType: ValueType.INT,
104
- });
105
- apiRequestLatencyHistogram = meter.createHistogram(METRIC_API_REQUEST_LATENCY, {
106
- description: 'Latency of API requests in milliseconds.',
107
- unit: 'ms',
108
- valueType: ValueType.INT,
109
- });
110
- tokenUsageCounter = meter.createCounter(METRIC_TOKEN_USAGE, {
111
- description: 'Counts the total number of tokens used.',
112
- valueType: ValueType.INT,
113
- });
114
- fileOperationCounter = meter.createCounter(METRIC_FILE_OPERATION_COUNT, {
115
- description: 'Counts file operations (create, read, update).',
116
- valueType: ValueType.INT,
117
- });
118
- chatCompressionCounter = meter.createCounter(EVENT_CHAT_COMPRESSION, {
119
- description: 'Counts chat compression events.',
120
- valueType: ValueType.INT,
121
- });
122
- // New counters for content errors
123
- invalidChunkCounter = meter.createCounter(METRIC_INVALID_CHUNK_COUNT, {
124
- description: 'Counts invalid chunks received from a stream.',
125
- valueType: ValueType.INT,
126
- });
127
- contentRetryCounter = meter.createCounter(METRIC_CONTENT_RETRY_COUNT, {
128
- description: 'Counts retries due to content errors (e.g., empty stream).',
129
- valueType: ValueType.INT,
130
- });
131
- contentRetryFailureCounter = meter.createCounter(METRIC_CONTENT_RETRY_FAILURE_COUNT, {
132
- description: 'Counts occurrences of all content retries failing.',
133
- valueType: ValueType.INT,
134
- });
135
- modelRoutingLatencyHistogram = meter.createHistogram(METRIC_MODEL_ROUTING_LATENCY, {
136
- description: 'Latency of model routing decisions in milliseconds.',
137
- unit: 'ms',
138
- valueType: ValueType.INT,
139
- });
140
- modelRoutingFailureCounter = meter.createCounter(METRIC_MODEL_ROUTING_FAILURE_COUNT, {
141
- description: 'Counts model routing failures.',
142
- valueType: ValueType.INT,
143
- });
144
- modelSlashCommandCallCounter = meter.createCounter(METRIC_MODEL_SLASH_COMMAND_CALL_COUNT, {
145
- description: 'Counts model slash command calls.',
146
- valueType: ValueType.INT,
147
- });
148
- const sessionCounter = meter.createCounter(METRIC_SESSION_COUNT, {
149
- description: 'Count of CLI sessions started.',
150
- valueType: ValueType.INT,
151
- });
152
- sessionCounter.add(1, getCommonAttributes(config));
293
+ // Increment session counter after all metrics are initialized
294
+ sessionCounter?.add(1, baseMetricDefinition.getCommonAttributes(config));
153
295
  // Initialize performance monitoring metrics if enabled
154
296
  initializePerformanceMonitoring(config);
155
297
  isMetricsInitialized = true;
156
298
  }
157
- export function recordChatCompressionMetrics(config, args) {
299
+ export function recordChatCompressionMetrics(config, attributes) {
158
300
  if (!chatCompressionCounter || !isMetricsInitialized)
159
301
  return;
160
302
  chatCompressionCounter.add(1, {
161
- ...getCommonAttributes(config),
162
- ...args,
303
+ ...baseMetricDefinition.getCommonAttributes(config),
304
+ ...attributes,
163
305
  });
164
306
  }
165
- export function recordToolCallMetrics(config, functionName, durationMs, success, decision, tool_type) {
307
+ export function recordToolCallMetrics(config, durationMs, attributes) {
166
308
  if (!toolCallCounter || !toolCallLatencyHistogram || !isMetricsInitialized)
167
309
  return;
168
310
  const metricAttributes = {
169
- ...getCommonAttributes(config),
170
- function_name: functionName,
171
- success,
172
- decision,
173
- tool_type,
311
+ ...baseMetricDefinition.getCommonAttributes(config),
312
+ ...attributes,
174
313
  };
175
314
  toolCallCounter.add(1, metricAttributes);
176
315
  toolCallLatencyHistogram.record(durationMs, {
177
- ...getCommonAttributes(config),
178
- function_name: functionName,
316
+ ...baseMetricDefinition.getCommonAttributes(config),
317
+ function_name: attributes.function_name,
179
318
  });
180
319
  }
181
- export function recordTokenUsageMetrics(config, model, tokenCount, type) {
320
+ export function recordTokenUsageMetrics(config, tokenCount, attributes) {
182
321
  if (!tokenUsageCounter || !isMetricsInitialized)
183
322
  return;
184
323
  tokenUsageCounter.add(tokenCount, {
185
- ...getCommonAttributes(config),
186
- model,
187
- type,
324
+ ...baseMetricDefinition.getCommonAttributes(config),
325
+ ...attributes,
188
326
  });
189
327
  }
190
- export function recordApiResponseMetrics(config, model, durationMs, statusCode) {
328
+ export function recordApiResponseMetrics(config, durationMs, attributes) {
191
329
  if (!apiRequestCounter ||
192
330
  !apiRequestLatencyHistogram ||
193
331
  !isMetricsInitialized)
194
332
  return;
195
333
  const metricAttributes = {
196
- ...getCommonAttributes(config),
197
- model,
198
- status_code: statusCode ?? 'ok',
334
+ ...baseMetricDefinition.getCommonAttributes(config),
335
+ model: attributes.model,
336
+ status_code: attributes.status_code ?? 'ok',
199
337
  };
200
338
  apiRequestCounter.add(1, metricAttributes);
201
339
  apiRequestLatencyHistogram.record(durationMs, {
202
- ...getCommonAttributes(config),
203
- model,
340
+ ...baseMetricDefinition.getCommonAttributes(config),
341
+ model: attributes.model,
204
342
  });
205
343
  }
206
- export function recordApiErrorMetrics(config, model, durationMs, statusCode, errorType) {
344
+ export function recordApiErrorMetrics(config, durationMs, attributes) {
207
345
  if (!apiRequestCounter ||
208
346
  !apiRequestLatencyHistogram ||
209
347
  !isMetricsInitialized)
210
348
  return;
211
349
  const metricAttributes = {
212
- ...getCommonAttributes(config),
213
- model,
214
- status_code: statusCode ?? 'error',
215
- error_type: errorType ?? 'unknown',
350
+ ...baseMetricDefinition.getCommonAttributes(config),
351
+ model: attributes.model,
352
+ status_code: attributes.status_code ?? 'error',
353
+ error_type: attributes.error_type ?? 'unknown',
216
354
  };
217
355
  apiRequestCounter.add(1, metricAttributes);
218
356
  apiRequestLatencyHistogram.record(durationMs, {
219
- ...getCommonAttributes(config),
220
- model,
357
+ ...baseMetricDefinition.getCommonAttributes(config),
358
+ model: attributes.model,
221
359
  });
222
360
  }
223
- export function recordFileOperationMetric(config, operation, lines, mimetype, extension, programming_language) {
361
+ export function recordFileOperationMetric(config, attributes) {
224
362
  if (!fileOperationCounter || !isMetricsInitialized)
225
363
  return;
226
- const attributes = {
227
- ...getCommonAttributes(config),
228
- operation,
229
- };
230
- if (lines !== undefined)
231
- attributes['lines'] = lines;
232
- if (mimetype !== undefined)
233
- attributes['mimetype'] = mimetype;
234
- if (extension !== undefined)
235
- attributes['extension'] = extension;
236
- if (programming_language !== undefined) {
237
- attributes['programming_language'] = programming_language;
238
- }
239
- fileOperationCounter.add(1, attributes);
364
+ fileOperationCounter.add(1, {
365
+ ...baseMetricDefinition.getCommonAttributes(config),
366
+ ...attributes,
367
+ });
240
368
  }
241
369
  // --- New Metric Recording Functions ---
242
370
  /**
@@ -245,7 +373,7 @@ export function recordFileOperationMetric(config, operation, lines, mimetype, ex
245
373
  export function recordInvalidChunk(config) {
246
374
  if (!invalidChunkCounter || !isMetricsInitialized)
247
375
  return;
248
- invalidChunkCounter.add(1, getCommonAttributes(config));
376
+ invalidChunkCounter.add(1, baseMetricDefinition.getCommonAttributes(config));
249
377
  }
250
378
  /**
251
379
  * Records a metric for when a retry is triggered due to a content error.
@@ -253,7 +381,7 @@ export function recordInvalidChunk(config) {
253
381
  export function recordContentRetry(config) {
254
382
  if (!contentRetryCounter || !isMetricsInitialized)
255
383
  return;
256
- contentRetryCounter.add(1, getCommonAttributes(config));
384
+ contentRetryCounter.add(1, baseMetricDefinition.getCommonAttributes(config));
257
385
  }
258
386
  /**
259
387
  * Records a metric for when all content error retries have failed for a request.
@@ -261,13 +389,13 @@ export function recordContentRetry(config) {
261
389
  export function recordContentRetryFailure(config) {
262
390
  if (!contentRetryFailureCounter || !isMetricsInitialized)
263
391
  return;
264
- contentRetryFailureCounter.add(1, getCommonAttributes(config));
392
+ contentRetryFailureCounter.add(1, baseMetricDefinition.getCommonAttributes(config));
265
393
  }
266
394
  export function recordModelSlashCommand(config, event) {
267
395
  if (!modelSlashCommandCallCounter || !isMetricsInitialized)
268
396
  return;
269
397
  modelSlashCommandCallCounter.add(1, {
270
- ...getCommonAttributes(config),
398
+ ...baseMetricDefinition.getCommonAttributes(config),
271
399
  'slash_command.model.model_name': event.model_name,
272
400
  });
273
401
  }
@@ -277,13 +405,13 @@ export function recordModelRoutingMetrics(config, event) {
277
405
  !isMetricsInitialized)
278
406
  return;
279
407
  modelRoutingLatencyHistogram.record(event.routing_latency_ms, {
280
- ...getCommonAttributes(config),
408
+ ...baseMetricDefinition.getCommonAttributes(config),
281
409
  'routing.decision_model': event.decision_model,
282
410
  'routing.decision_source': event.decision_source,
283
411
  });
284
412
  if (event.failed) {
285
413
  modelRoutingFailureCounter.add(1, {
286
- ...getCommonAttributes(config),
414
+ ...baseMetricDefinition.getCommonAttributes(config),
287
415
  'routing.decision_source': event.decision_source,
288
416
  'routing.error_message': event.error_message,
289
417
  });
@@ -300,175 +428,115 @@ export function initializePerformanceMonitoring(config) {
300
428
  isPerformanceMonitoringEnabled = config.getTelemetryEnabled();
301
429
  if (!isPerformanceMonitoringEnabled)
302
430
  return;
303
- // Initialize startup time histogram
304
- startupTimeHistogram = meter.createHistogram(METRIC_STARTUP_TIME, {
305
- description: 'CLI startup time in milliseconds, broken down by initialization phase.',
306
- unit: 'ms',
307
- valueType: ValueType.DOUBLE,
308
- });
309
- // Initialize memory usage histogram (using histogram until ObservableGauge is available)
310
- memoryUsageGauge = meter.createHistogram(METRIC_MEMORY_USAGE, {
311
- description: 'Memory usage in bytes.',
312
- unit: 'bytes',
313
- valueType: ValueType.INT,
314
- });
315
- // Initialize CPU usage histogram
316
- cpuUsageGauge = meter.createHistogram(METRIC_CPU_USAGE, {
317
- description: 'CPU usage percentage.',
318
- unit: 'percent',
319
- valueType: ValueType.DOUBLE,
320
- });
321
- // Initialize tool queue depth histogram
322
- toolQueueDepthGauge = meter.createHistogram(METRIC_TOOL_QUEUE_DEPTH, {
323
- description: 'Number of tools in execution queue.',
324
- valueType: ValueType.INT,
325
- });
326
- // Initialize performance breakdowns
327
- toolExecutionBreakdownHistogram = meter.createHistogram(METRIC_TOOL_EXECUTION_BREAKDOWN, {
328
- description: 'Tool execution time breakdown by phase in milliseconds.',
329
- unit: 'ms',
330
- valueType: ValueType.INT,
331
- });
332
- tokenEfficiencyHistogram = meter.createHistogram(METRIC_TOKEN_EFFICIENCY, {
333
- description: 'Token efficiency metrics (tokens per operation, cache hit rate, etc.).',
334
- valueType: ValueType.DOUBLE,
335
- });
336
- apiRequestBreakdownHistogram = meter.createHistogram(METRIC_API_REQUEST_BREAKDOWN, {
337
- description: 'API request time breakdown by phase in milliseconds.',
338
- unit: 'ms',
339
- valueType: ValueType.INT,
340
- });
341
- // Initialize performance score and regression detection
342
- performanceScoreGauge = meter.createHistogram(METRIC_PERFORMANCE_SCORE, {
343
- description: 'Composite performance score (0-100).',
344
- unit: 'score',
345
- valueType: ValueType.DOUBLE,
346
- });
347
- regressionDetectionCounter = meter.createCounter(METRIC_REGRESSION_DETECTION, {
348
- description: 'Performance regression detection events.',
349
- valueType: ValueType.INT,
350
- });
351
- regressionPercentageChangeHistogram = meter.createHistogram(METRIC_REGRESSION_PERCENTAGE_CHANGE, {
352
- description: 'Percentage change compared to baseline for detected regressions.',
353
- unit: 'percent',
354
- valueType: ValueType.DOUBLE,
431
+ Object.entries(PERFORMANCE_COUNTER_DEFINITIONS).forEach(([name, { description, valueType, assign }]) => {
432
+ assign(meter.createCounter(name, { description, valueType }));
355
433
  });
356
- baselineComparisonHistogram = meter.createHistogram(METRIC_BASELINE_COMPARISON, {
357
- description: 'Performance comparison to established baseline (percentage change).',
358
- unit: 'percent',
359
- valueType: ValueType.DOUBLE,
434
+ Object.entries(PERFORMANCE_HISTOGRAM_DEFINITIONS).forEach(([name, { description, unit, valueType, assign }]) => {
435
+ assign(meter.createHistogram(name, { description, unit, valueType }));
360
436
  });
361
437
  }
362
- export function recordStartupPerformance(config, phase, durationMs, details) {
438
+ export function recordStartupPerformance(config, durationMs, attributes) {
363
439
  if (!startupTimeHistogram || !isPerformanceMonitoringEnabled)
364
440
  return;
365
- const attributes = {
366
- ...getCommonAttributes(config),
367
- phase,
368
- ...details,
441
+ const metricAttributes = {
442
+ ...baseMetricDefinition.getCommonAttributes(config),
443
+ phase: attributes.phase,
444
+ ...attributes.details,
369
445
  };
370
- startupTimeHistogram.record(durationMs, attributes);
446
+ startupTimeHistogram.record(durationMs, metricAttributes);
371
447
  }
372
- export function recordMemoryUsage(config, memoryType, bytes, component) {
448
+ export function recordMemoryUsage(config, bytes, attributes) {
373
449
  if (!memoryUsageGauge || !isPerformanceMonitoringEnabled)
374
450
  return;
375
- const attributes = {
376
- ...getCommonAttributes(config),
377
- memory_type: memoryType,
378
- component,
451
+ const metricAttributes = {
452
+ ...baseMetricDefinition.getCommonAttributes(config),
453
+ ...attributes,
379
454
  };
380
- memoryUsageGauge.record(bytes, attributes);
455
+ memoryUsageGauge.record(bytes, metricAttributes);
381
456
  }
382
- export function recordCpuUsage(config, percentage, component) {
457
+ export function recordCpuUsage(config, percentage, attributes) {
383
458
  if (!cpuUsageGauge || !isPerformanceMonitoringEnabled)
384
459
  return;
385
- const attributes = {
386
- ...getCommonAttributes(config),
387
- component,
460
+ const metricAttributes = {
461
+ ...baseMetricDefinition.getCommonAttributes(config),
462
+ ...attributes,
388
463
  };
389
- cpuUsageGauge.record(percentage, attributes);
464
+ cpuUsageGauge.record(percentage, metricAttributes);
390
465
  }
391
466
  export function recordToolQueueDepth(config, queueDepth) {
392
467
  if (!toolQueueDepthGauge || !isPerformanceMonitoringEnabled)
393
468
  return;
394
469
  const attributes = {
395
- ...getCommonAttributes(config),
470
+ ...baseMetricDefinition.getCommonAttributes(config),
396
471
  };
397
472
  toolQueueDepthGauge.record(queueDepth, attributes);
398
473
  }
399
- export function recordToolExecutionBreakdown(config, functionName, phase, durationMs) {
474
+ export function recordToolExecutionBreakdown(config, durationMs, attributes) {
400
475
  if (!toolExecutionBreakdownHistogram || !isPerformanceMonitoringEnabled)
401
476
  return;
402
- const attributes = {
403
- ...getCommonAttributes(config),
404
- function_name: functionName,
405
- phase,
477
+ const metricAttributes = {
478
+ ...baseMetricDefinition.getCommonAttributes(config),
479
+ ...attributes,
406
480
  };
407
- toolExecutionBreakdownHistogram.record(durationMs, attributes);
481
+ toolExecutionBreakdownHistogram.record(durationMs, metricAttributes);
408
482
  }
409
- export function recordTokenEfficiency(config, model, metric, value, context) {
483
+ export function recordTokenEfficiency(config, value, attributes) {
410
484
  if (!tokenEfficiencyHistogram || !isPerformanceMonitoringEnabled)
411
485
  return;
412
- const attributes = {
413
- ...getCommonAttributes(config),
414
- model,
415
- metric,
416
- context,
486
+ const metricAttributes = {
487
+ ...baseMetricDefinition.getCommonAttributes(config),
488
+ ...attributes,
417
489
  };
418
- tokenEfficiencyHistogram.record(value, attributes);
490
+ tokenEfficiencyHistogram.record(value, metricAttributes);
419
491
  }
420
- export function recordApiRequestBreakdown(config, model, phase, durationMs) {
492
+ export function recordApiRequestBreakdown(config, durationMs, attributes) {
421
493
  if (!apiRequestBreakdownHistogram || !isPerformanceMonitoringEnabled)
422
494
  return;
423
- const attributes = {
424
- ...getCommonAttributes(config),
425
- model,
426
- phase,
495
+ const metricAttributes = {
496
+ ...baseMetricDefinition.getCommonAttributes(config),
497
+ ...attributes,
427
498
  };
428
- apiRequestBreakdownHistogram.record(durationMs, attributes);
499
+ apiRequestBreakdownHistogram.record(durationMs, metricAttributes);
429
500
  }
430
- export function recordPerformanceScore(config, score, category, baseline) {
501
+ export function recordPerformanceScore(config, score, attributes) {
431
502
  if (!performanceScoreGauge || !isPerformanceMonitoringEnabled)
432
503
  return;
433
- const attributes = {
434
- ...getCommonAttributes(config),
435
- category,
436
- baseline,
504
+ const metricAttributes = {
505
+ ...baseMetricDefinition.getCommonAttributes(config),
506
+ ...attributes,
437
507
  };
438
- performanceScoreGauge.record(score, attributes);
508
+ performanceScoreGauge.record(score, metricAttributes);
439
509
  }
440
- export function recordPerformanceRegression(config, metric, currentValue, baselineValue, severity) {
510
+ export function recordPerformanceRegression(config, attributes) {
441
511
  if (!regressionDetectionCounter || !isPerformanceMonitoringEnabled)
442
512
  return;
443
- const attributes = {
444
- ...getCommonAttributes(config),
445
- metric,
446
- severity,
447
- current_value: currentValue,
448
- baseline_value: baselineValue,
513
+ const metricAttributes = {
514
+ ...baseMetricDefinition.getCommonAttributes(config),
515
+ ...attributes,
449
516
  };
450
- regressionDetectionCounter.add(1, attributes);
451
- if (baselineValue !== 0 && regressionPercentageChangeHistogram) {
452
- const percentageChange = ((currentValue - baselineValue) / baselineValue) * 100;
453
- regressionPercentageChangeHistogram.record(percentageChange, attributes);
517
+ regressionDetectionCounter.add(1, metricAttributes);
518
+ if (attributes.baseline_value !== 0 && regressionPercentageChangeHistogram) {
519
+ const percentageChange = ((attributes.current_value - attributes.baseline_value) /
520
+ attributes.baseline_value) *
521
+ 100;
522
+ regressionPercentageChangeHistogram.record(percentageChange, metricAttributes);
454
523
  }
455
524
  }
456
- export function recordBaselineComparison(config, metric, currentValue, baselineValue, category) {
525
+ export function recordBaselineComparison(config, attributes) {
457
526
  if (!baselineComparisonHistogram || !isPerformanceMonitoringEnabled)
458
527
  return;
459
- if (baselineValue === 0) {
528
+ if (attributes.baseline_value === 0) {
460
529
  diag.warn('Baseline value is zero, skipping comparison.');
461
530
  return;
462
531
  }
463
- const percentageChange = ((currentValue - baselineValue) / baselineValue) * 100;
464
- const attributes = {
465
- ...getCommonAttributes(config),
466
- metric,
467
- category,
468
- current_value: currentValue,
469
- baseline_value: baselineValue,
532
+ const percentageChange = ((attributes.current_value - attributes.baseline_value) /
533
+ attributes.baseline_value) *
534
+ 100;
535
+ const metricAttributes = {
536
+ ...baseMetricDefinition.getCommonAttributes(config),
537
+ ...attributes,
470
538
  };
471
- baselineComparisonHistogram.record(percentageChange, attributes);
539
+ baselineComparisonHistogram.record(percentageChange, metricAttributes);
472
540
  }
473
541
  // Utility function to check if performance monitoring is enabled
474
542
  export function isPerformanceMonitoringActive() {