@machina.ai/cell-cli-core 1.6.1-rc1 → 1.8.2-rc1

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 (259) hide show
  1. package/dist/index.d.ts +4 -3
  2. package/dist/index.js +4 -3
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +1 -1
  5. package/dist/src/agents/codebase-investigator.d.ts +11 -0
  6. package/dist/src/agents/codebase-investigator.js +73 -0
  7. package/dist/src/agents/codebase-investigator.js.map +1 -0
  8. package/dist/src/agents/executor.d.ts +88 -0
  9. package/dist/src/agents/executor.js +417 -0
  10. package/dist/src/agents/executor.js.map +1 -0
  11. package/dist/src/agents/executor.test.d.ts +6 -0
  12. package/dist/src/agents/executor.test.js +419 -0
  13. package/dist/src/agents/executor.test.js.map +1 -0
  14. package/dist/src/agents/invocation.d.ts +43 -0
  15. package/dist/src/agents/invocation.js +100 -0
  16. package/dist/src/agents/invocation.js.map +1 -0
  17. package/dist/src/agents/invocation.test.d.ts +6 -0
  18. package/dist/src/agents/invocation.test.js +206 -0
  19. package/dist/src/agents/invocation.test.js.map +1 -0
  20. package/dist/src/agents/registry.d.ts +35 -0
  21. package/dist/src/agents/registry.js +58 -0
  22. package/dist/src/agents/registry.js.map +1 -0
  23. package/dist/src/agents/registry.test.d.ts +6 -0
  24. package/dist/src/agents/registry.test.js +146 -0
  25. package/dist/src/agents/registry.test.js.map +1 -0
  26. package/dist/src/agents/schema-utils.d.ts +39 -0
  27. package/dist/src/agents/schema-utils.js +57 -0
  28. package/dist/src/agents/schema-utils.js.map +1 -0
  29. package/dist/src/agents/schema-utils.test.d.ts +6 -0
  30. package/dist/src/agents/schema-utils.test.js +144 -0
  31. package/dist/src/agents/schema-utils.test.js.map +1 -0
  32. package/dist/src/agents/subagent-tool-wrapper.d.ts +36 -0
  33. package/dist/src/agents/subagent-tool-wrapper.js +47 -0
  34. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -0
  35. package/dist/src/agents/subagent-tool-wrapper.test.d.ts +6 -0
  36. package/dist/src/agents/subagent-tool-wrapper.test.js +105 -0
  37. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -0
  38. package/dist/src/agents/types.d.ts +116 -0
  39. package/dist/src/agents/types.js +17 -0
  40. package/dist/src/agents/types.js.map +1 -0
  41. package/dist/src/agents/utils.d.ts +15 -0
  42. package/dist/src/agents/utils.js +29 -0
  43. package/dist/src/agents/utils.js.map +1 -0
  44. package/dist/src/agents/utils.test.d.ts +6 -0
  45. package/dist/src/agents/utils.test.js +87 -0
  46. package/dist/src/agents/utils.test.js.map +1 -0
  47. package/dist/src/config/config.d.ts +15 -8
  48. package/dist/src/config/config.js +43 -14
  49. package/dist/src/config/config.js.map +1 -1
  50. package/dist/src/config/constants.d.ts +11 -0
  51. package/dist/src/config/constants.js +16 -0
  52. package/dist/src/config/constants.js.map +1 -0
  53. package/dist/src/core/baseLlmClient.d.ts +4 -0
  54. package/dist/src/core/baseLlmClient.js +24 -23
  55. package/dist/src/core/baseLlmClient.js.map +1 -1
  56. package/dist/src/core/baseLlmClient.test.js +76 -13
  57. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  58. package/dist/src/core/client.d.ts +3 -2
  59. package/dist/src/core/client.js +37 -48
  60. package/dist/src/core/client.js.map +1 -1
  61. package/dist/src/core/client.test.js +277 -119
  62. package/dist/src/core/client.test.js.map +1 -1
  63. package/dist/src/core/coreToolScheduler.test.js +33 -23
  64. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  65. package/dist/src/core/geminiChat.d.ts +4 -3
  66. package/dist/src/core/geminiChat.js +55 -61
  67. package/dist/src/core/geminiChat.js.map +1 -1
  68. package/dist/src/core/geminiChat.test.js +241 -29
  69. package/dist/src/core/geminiChat.test.js.map +1 -1
  70. package/dist/src/core/logger.test.js +16 -16
  71. package/dist/src/core/logger.test.js.map +1 -1
  72. package/dist/src/core/nonInteractiveToolExecutor.test.js +11 -11
  73. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  74. package/dist/src/core/prompts.js +3 -2
  75. package/dist/src/core/prompts.js.map +1 -1
  76. package/dist/src/core/turn.d.ts +1 -4
  77. package/dist/src/core/turn.js +2 -12
  78. package/dist/src/core/turn.js.map +1 -1
  79. package/dist/src/generated/git-commit.d.ts +2 -2
  80. package/dist/src/generated/git-commit.js +2 -2
  81. package/dist/src/ide/detect-ide.d.ts +45 -14
  82. package/dist/src/ide/detect-ide.js +32 -69
  83. package/dist/src/ide/detect-ide.js.map +1 -1
  84. package/dist/src/ide/detect-ide.test.js +29 -46
  85. package/dist/src/ide/detect-ide.test.js.map +1 -1
  86. package/dist/src/ide/ide-client.d.ts +4 -4
  87. package/dist/src/ide/ide-client.js +30 -29
  88. package/dist/src/ide/ide-client.js.map +1 -1
  89. package/dist/src/ide/ide-client.test.js +8 -21
  90. package/dist/src/ide/ide-client.test.js.map +1 -1
  91. package/dist/src/ide/ide-installer.d.ts +2 -2
  92. package/dist/src/ide/ide-installer.js +7 -9
  93. package/dist/src/ide/ide-installer.js.map +1 -1
  94. package/dist/src/ide/ide-installer.test.js +20 -13
  95. package/dist/src/ide/ide-installer.test.js.map +1 -1
  96. package/dist/src/index.d.ts +5 -2
  97. package/dist/src/index.js +5 -2
  98. package/dist/src/index.js.map +1 -1
  99. package/dist/src/mcp/oauth-provider.d.ts +4 -1
  100. package/dist/src/mcp/oauth-provider.js +31 -25
  101. package/dist/src/mcp/oauth-provider.js.map +1 -1
  102. package/dist/src/mcp/sa-impersonation-provider.d.ts +33 -0
  103. package/dist/src/mcp/sa-impersonation-provider.js +130 -0
  104. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -0
  105. package/dist/src/mcp/sa-impersonation-provider.test.d.ts +6 -0
  106. package/dist/src/mcp/sa-impersonation-provider.test.js +117 -0
  107. package/dist/src/mcp/sa-impersonation-provider.test.js.map +1 -0
  108. package/dist/src/policy/policy-engine.js +11 -2
  109. package/dist/src/policy/policy-engine.js.map +1 -1
  110. package/dist/src/policy/policy-engine.test.js +45 -0
  111. package/dist/src/policy/policy-engine.test.js.map +1 -1
  112. package/dist/src/routing/strategies/compositeStrategy.js +4 -3
  113. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
  114. package/dist/src/services/chatRecordingService.d.ts +1 -1
  115. package/dist/src/services/chatRecordingService.js +1 -1
  116. package/dist/src/services/chatRecordingService.js.map +1 -1
  117. package/dist/src/services/fileSystemService.d.ts +9 -0
  118. package/dist/src/services/fileSystemService.js +11 -0
  119. package/dist/src/services/fileSystemService.js.map +1 -1
  120. package/dist/src/services/shellExecutionService.d.ts +2 -0
  121. package/dist/src/services/shellExecutionService.js +48 -7
  122. package/dist/src/services/shellExecutionService.js.map +1 -1
  123. package/dist/src/services/shellExecutionService.test.js +13 -4
  124. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  125. package/dist/src/telemetry/activity-detector.d.ts +41 -0
  126. package/dist/src/telemetry/activity-detector.js +61 -0
  127. package/dist/src/telemetry/activity-detector.js.map +1 -0
  128. package/dist/src/telemetry/activity-detector.test.d.ts +6 -0
  129. package/dist/src/telemetry/activity-detector.test.js +136 -0
  130. package/dist/src/telemetry/activity-detector.test.js.map +1 -0
  131. package/dist/src/telemetry/activity-types.d.ts +19 -0
  132. package/dist/src/telemetry/activity-types.js +21 -0
  133. package/dist/src/telemetry/activity-types.js.map +1 -0
  134. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +6 -2
  135. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +155 -102
  136. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  137. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +1 -0
  138. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +178 -33
  139. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  140. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +108 -100
  141. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +116 -100
  142. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  143. package/dist/src/telemetry/config.d.ts +31 -0
  144. package/dist/src/telemetry/config.js +74 -0
  145. package/dist/src/telemetry/config.js.map +1 -0
  146. package/dist/src/telemetry/config.test.d.ts +6 -0
  147. package/dist/src/telemetry/config.test.js +124 -0
  148. package/dist/src/telemetry/config.test.js.map +1 -0
  149. package/dist/src/telemetry/constants.d.ts +6 -12
  150. package/dist/src/telemetry/constants.js +7 -12
  151. package/dist/src/telemetry/constants.js.map +1 -1
  152. package/dist/src/telemetry/index.d.ts +5 -1
  153. package/dist/src/telemetry/index.js +10 -0
  154. package/dist/src/telemetry/index.js.map +1 -1
  155. package/dist/src/telemetry/loggers.d.ts +3 -1
  156. package/dist/src/telemetry/loggers.js +78 -11
  157. package/dist/src/telemetry/loggers.js.map +1 -1
  158. package/dist/src/telemetry/loggers.test.circular.js +3 -3
  159. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  160. package/dist/src/telemetry/loggers.test.js +126 -11
  161. package/dist/src/telemetry/loggers.test.js.map +1 -1
  162. package/dist/src/telemetry/metrics.d.ts +309 -11
  163. package/dist/src/telemetry/metrics.js +424 -110
  164. package/dist/src/telemetry/metrics.js.map +1 -1
  165. package/dist/src/telemetry/metrics.test.js +538 -15
  166. package/dist/src/telemetry/metrics.test.js.map +1 -1
  167. package/dist/src/telemetry/sdk.js +1 -1
  168. package/dist/src/telemetry/sdk.js.map +1 -1
  169. package/dist/src/telemetry/sdk.test.js +13 -0
  170. package/dist/src/telemetry/sdk.test.js.map +1 -1
  171. package/dist/src/telemetry/types.d.ts +19 -3
  172. package/dist/src/telemetry/types.js +37 -6
  173. package/dist/src/telemetry/types.js.map +1 -1
  174. package/dist/src/telemetry/uiTelemetry.d.ts +1 -1
  175. package/dist/src/telemetry/uiTelemetry.js +2 -3
  176. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  177. package/dist/src/telemetry/uiTelemetry.test.js +13 -13
  178. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  179. package/dist/src/test-utils/mock-tool.d.ts +28 -3
  180. package/dist/src/test-utils/mock-tool.js +71 -1
  181. package/dist/src/test-utils/mock-tool.js.map +1 -1
  182. package/dist/src/tools/glob.js +2 -1
  183. package/dist/src/tools/glob.js.map +1 -1
  184. package/dist/src/tools/ls.js +1 -1
  185. package/dist/src/tools/ls.js.map +1 -1
  186. package/dist/src/tools/mcp-client.d.ts +2 -12
  187. package/dist/src/tools/mcp-client.js +22 -65
  188. package/dist/src/tools/mcp-client.js.map +1 -1
  189. package/dist/src/tools/mcp-client.test.js +9 -154
  190. package/dist/src/tools/mcp-client.test.js.map +1 -1
  191. package/dist/src/tools/message-bus-integration.test.d.ts +6 -0
  192. package/dist/src/tools/message-bus-integration.test.js +183 -0
  193. package/dist/src/tools/message-bus-integration.test.js.map +1 -0
  194. package/dist/src/tools/shell.js +5 -2
  195. package/dist/src/tools/shell.js.map +1 -1
  196. package/dist/src/tools/smart-edit.d.ts +19 -0
  197. package/dist/src/tools/smart-edit.js +105 -3
  198. package/dist/src/tools/smart-edit.js.map +1 -1
  199. package/dist/src/tools/smart-edit.test.js +83 -5
  200. package/dist/src/tools/smart-edit.test.js.map +1 -1
  201. package/dist/src/tools/tool-error.d.ts +1 -0
  202. package/dist/src/tools/tool-error.js +1 -0
  203. package/dist/src/tools/tool-error.js.map +1 -1
  204. package/dist/src/tools/tool-registry.test.js +10 -10
  205. package/dist/src/tools/tool-registry.test.js.map +1 -1
  206. package/dist/src/tools/tools.d.ts +11 -3
  207. package/dist/src/tools/tools.js +94 -3
  208. package/dist/src/tools/tools.js.map +1 -1
  209. package/dist/src/tools/write-todos.d.ts +25 -0
  210. package/dist/src/tools/write-todos.js +150 -0
  211. package/dist/src/tools/write-todos.js.map +1 -0
  212. package/dist/src/tools/write-todos.test.d.ts +6 -0
  213. package/dist/src/tools/write-todos.test.js +89 -0
  214. package/dist/src/tools/write-todos.test.js.map +1 -0
  215. package/dist/src/utils/bfsFileSearch.d.ts +1 -1
  216. package/dist/src/utils/flashFallback.test.js +2 -2
  217. package/dist/src/utils/flashFallback.test.js.map +1 -1
  218. package/dist/src/utils/getFolderStructure.d.ts +1 -1
  219. package/dist/src/utils/getFolderStructure.js +1 -1
  220. package/dist/src/utils/getFolderStructure.js.map +1 -1
  221. package/dist/src/utils/llm-edit-fixer.js +11 -1
  222. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  223. package/dist/src/utils/llm-edit-fixer.test.js +81 -0
  224. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  225. package/dist/src/utils/memoryDiscovery.d.ts +1 -1
  226. package/dist/src/utils/memoryDiscovery.js +1 -1
  227. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  228. package/dist/src/utils/memoryImportProcessor.js +13 -20
  229. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  230. package/dist/src/utils/memoryImportProcessor.test.js +14 -0
  231. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  232. package/dist/src/utils/retry.d.ts +3 -1
  233. package/dist/src/utils/retry.js +20 -5
  234. package/dist/src/utils/retry.js.map +1 -1
  235. package/dist/src/utils/retry.test.js +31 -2
  236. package/dist/src/utils/retry.test.js.map +1 -1
  237. package/dist/src/utils/schemaValidator.js +11 -1
  238. package/dist/src/utils/schemaValidator.js.map +1 -1
  239. package/dist/src/utils/schemaValidator.test.d.ts +6 -0
  240. package/dist/src/utils/schemaValidator.test.js +113 -0
  241. package/dist/src/utils/schemaValidator.test.js.map +1 -0
  242. package/dist/src/utils/shell-utils.js +5 -1
  243. package/dist/src/utils/shell-utils.js.map +1 -1
  244. package/dist/src/utils/shell-utils.test.js +5 -0
  245. package/dist/src/utils/shell-utils.test.js.map +1 -1
  246. package/dist/src/utils/terminalSerializer.d.ts +1 -4
  247. package/dist/src/utils/terminalSerializer.js +3 -3
  248. package/dist/src/utils/terminalSerializer.js.map +1 -1
  249. package/dist/src/utils/thoughtUtils.d.ts +21 -0
  250. package/dist/src/utils/thoughtUtils.js +39 -0
  251. package/dist/src/utils/thoughtUtils.js.map +1 -0
  252. package/dist/src/utils/thoughtUtils.test.d.ts +6 -0
  253. package/dist/src/utils/thoughtUtils.test.js +78 -0
  254. package/dist/src/utils/thoughtUtils.test.js.map +1 -0
  255. package/dist/tsconfig.tsbuildinfo +1 -1
  256. package/package.json +2 -2
  257. package/dist/src/test-utils/tools.d.ts +0 -45
  258. package/dist/src/test-utils/tools.js +0 -105
  259. package/dist/src/test-utils/tools.js.map +0 -1
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { describe, it, expect, vi, beforeEach } from 'vitest';
7
- import { FileOperation } from './metrics.js';
7
+ import { FileOperation, MemoryMetricType, ToolExecutionPhase, ApiRequestPhase, } from './metrics.js';
8
8
  import { makeFakeConfig } from '../test-utils/config.js';
9
9
  import { ModelRoutingEvent } from './types.js';
10
10
  const mockCounterAddFn = vi.fn();
@@ -28,9 +28,11 @@ function originalOtelMockFactory() {
28
28
  },
29
29
  ValueType: {
30
30
  INT: 1,
31
+ DOUBLE: 2,
31
32
  },
32
33
  diag: {
33
34
  setLogger: vi.fn(),
35
+ warn: vi.fn(),
34
36
  },
35
37
  };
36
38
  }
@@ -41,6 +43,16 @@ describe('Telemetry Metrics', () => {
41
43
  let recordFileOperationMetricModule;
42
44
  let recordChatCompressionMetricsModule;
43
45
  let recordModelRoutingMetricsModule;
46
+ let recordStartupPerformanceModule;
47
+ let recordMemoryUsageModule;
48
+ let recordCpuUsageModule;
49
+ let recordToolQueueDepthModule;
50
+ let recordToolExecutionBreakdownModule;
51
+ let recordTokenEfficiencyModule;
52
+ let recordApiRequestBreakdownModule;
53
+ let recordPerformanceScoreModule;
54
+ let recordPerformanceRegressionModule;
55
+ let recordBaselineComparisonModule;
44
56
  beforeEach(async () => {
45
57
  vi.resetModules();
46
58
  vi.doMock('@opentelemetry/api', () => {
@@ -55,6 +67,18 @@ describe('Telemetry Metrics', () => {
55
67
  recordChatCompressionMetricsModule =
56
68
  metricsJsModule.recordChatCompressionMetrics;
57
69
  recordModelRoutingMetricsModule = metricsJsModule.recordModelRoutingMetrics;
70
+ recordStartupPerformanceModule = metricsJsModule.recordStartupPerformance;
71
+ recordMemoryUsageModule = metricsJsModule.recordMemoryUsage;
72
+ recordCpuUsageModule = metricsJsModule.recordCpuUsage;
73
+ recordToolQueueDepthModule = metricsJsModule.recordToolQueueDepth;
74
+ recordToolExecutionBreakdownModule =
75
+ metricsJsModule.recordToolExecutionBreakdown;
76
+ recordTokenEfficiencyModule = metricsJsModule.recordTokenEfficiency;
77
+ recordApiRequestBreakdownModule = metricsJsModule.recordApiRequestBreakdown;
78
+ recordPerformanceScoreModule = metricsJsModule.recordPerformanceScore;
79
+ recordPerformanceRegressionModule =
80
+ metricsJsModule.recordPerformanceRegression;
81
+ recordBaselineComparisonModule = metricsJsModule.recordBaselineComparison;
58
82
  const otelApiModule = await import('@opentelemetry/api');
59
83
  mockCounterAddFn.mockClear();
60
84
  mockCreateCounterFn.mockClear();
@@ -91,14 +115,21 @@ describe('Telemetry Metrics', () => {
91
115
  describe('recordTokenUsageMetrics', () => {
92
116
  const mockConfig = {
93
117
  getSessionId: () => 'test-session-id',
118
+ getTelemetryEnabled: () => true,
94
119
  };
95
120
  it('should not record metrics if not initialized', () => {
96
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 100, 'input');
121
+ recordTokenUsageMetricsModule(mockConfig, 100, {
122
+ model: 'gemini-pro',
123
+ type: 'input',
124
+ });
97
125
  expect(mockCounterAddFn).not.toHaveBeenCalled();
98
126
  });
99
127
  it('should record token usage with the correct attributes', () => {
100
128
  initializeMetricsModule(mockConfig);
101
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 100, 'input');
129
+ recordTokenUsageMetricsModule(mockConfig, 100, {
130
+ model: 'gemini-pro',
131
+ type: 'input',
132
+ });
102
133
  expect(mockCounterAddFn).toHaveBeenCalledTimes(2);
103
134
  expect(mockCounterAddFn).toHaveBeenNthCalledWith(1, 1, {
104
135
  'session.id': 'test-session-id',
@@ -112,25 +143,37 @@ describe('Telemetry Metrics', () => {
112
143
  it('should record token usage for different types', () => {
113
144
  initializeMetricsModule(mockConfig);
114
145
  mockCounterAddFn.mockClear();
115
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 50, 'output');
146
+ recordTokenUsageMetricsModule(mockConfig, 50, {
147
+ model: 'gemini-pro',
148
+ type: 'output',
149
+ });
116
150
  expect(mockCounterAddFn).toHaveBeenCalledWith(50, {
117
151
  'session.id': 'test-session-id',
118
152
  model: 'gemini-pro',
119
153
  type: 'output',
120
154
  });
121
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 25, 'thought');
155
+ recordTokenUsageMetricsModule(mockConfig, 25, {
156
+ model: 'gemini-pro',
157
+ type: 'thought',
158
+ });
122
159
  expect(mockCounterAddFn).toHaveBeenCalledWith(25, {
123
160
  'session.id': 'test-session-id',
124
161
  model: 'gemini-pro',
125
162
  type: 'thought',
126
163
  });
127
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 75, 'cache');
164
+ recordTokenUsageMetricsModule(mockConfig, 75, {
165
+ model: 'gemini-pro',
166
+ type: 'cache',
167
+ });
128
168
  expect(mockCounterAddFn).toHaveBeenCalledWith(75, {
129
169
  'session.id': 'test-session-id',
130
170
  model: 'gemini-pro',
131
171
  type: 'cache',
132
172
  });
133
- recordTokenUsageMetricsModule(mockConfig, 'gemini-pro', 125, 'tool');
173
+ recordTokenUsageMetricsModule(mockConfig, 125, {
174
+ model: 'gemini-pro',
175
+ type: 'tool',
176
+ });
134
177
  expect(mockCounterAddFn).toHaveBeenCalledWith(125, {
135
178
  'session.id': 'test-session-id',
136
179
  model: 'gemini-pro',
@@ -140,7 +183,10 @@ describe('Telemetry Metrics', () => {
140
183
  it('should handle different models', () => {
141
184
  initializeMetricsModule(mockConfig);
142
185
  mockCounterAddFn.mockClear();
143
- recordTokenUsageMetricsModule(mockConfig, 'gemini-ultra', 200, 'input');
186
+ recordTokenUsageMetricsModule(mockConfig, 200, {
187
+ model: 'gemini-ultra',
188
+ type: 'input',
189
+ });
144
190
  expect(mockCounterAddFn).toHaveBeenCalledWith(200, {
145
191
  'session.id': 'test-session-id',
146
192
  model: 'gemini-ultra',
@@ -151,14 +197,25 @@ describe('Telemetry Metrics', () => {
151
197
  describe('recordFileOperationMetric', () => {
152
198
  const mockConfig = {
153
199
  getSessionId: () => 'test-session-id',
200
+ getTelemetryEnabled: () => true,
154
201
  };
155
202
  it('should not record metrics if not initialized', () => {
156
- recordFileOperationMetricModule(mockConfig, FileOperation.CREATE, 10, 'text/plain', 'txt');
203
+ recordFileOperationMetricModule(mockConfig, {
204
+ operation: FileOperation.CREATE,
205
+ lines: 10,
206
+ mimetype: 'text/plain',
207
+ extension: 'txt',
208
+ });
157
209
  expect(mockCounterAddFn).not.toHaveBeenCalled();
158
210
  });
159
211
  it('should record file creation with all attributes', () => {
160
212
  initializeMetricsModule(mockConfig);
161
- recordFileOperationMetricModule(mockConfig, FileOperation.CREATE, 10, 'text/plain', 'txt');
213
+ recordFileOperationMetricModule(mockConfig, {
214
+ operation: FileOperation.CREATE,
215
+ lines: 10,
216
+ mimetype: 'text/plain',
217
+ extension: 'txt',
218
+ });
162
219
  expect(mockCounterAddFn).toHaveBeenCalledTimes(2);
163
220
  expect(mockCounterAddFn).toHaveBeenNthCalledWith(1, 1, {
164
221
  'session.id': 'test-session-id',
@@ -174,7 +231,9 @@ describe('Telemetry Metrics', () => {
174
231
  it('should record file read with minimal attributes', () => {
175
232
  initializeMetricsModule(mockConfig);
176
233
  mockCounterAddFn.mockClear();
177
- recordFileOperationMetricModule(mockConfig, FileOperation.READ);
234
+ recordFileOperationMetricModule(mockConfig, {
235
+ operation: FileOperation.READ,
236
+ });
178
237
  expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
179
238
  'session.id': 'test-session-id',
180
239
  operation: FileOperation.READ,
@@ -183,7 +242,10 @@ describe('Telemetry Metrics', () => {
183
242
  it('should record file update with some attributes', () => {
184
243
  initializeMetricsModule(mockConfig);
185
244
  mockCounterAddFn.mockClear();
186
- recordFileOperationMetricModule(mockConfig, FileOperation.UPDATE, undefined, 'application/javascript');
245
+ recordFileOperationMetricModule(mockConfig, {
246
+ operation: FileOperation.UPDATE,
247
+ mimetype: 'application/javascript',
248
+ });
187
249
  expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
188
250
  'session.id': 'test-session-id',
189
251
  operation: FileOperation.UPDATE,
@@ -193,7 +255,9 @@ describe('Telemetry Metrics', () => {
193
255
  it('should record file operation without diffStat', () => {
194
256
  initializeMetricsModule(mockConfig);
195
257
  mockCounterAddFn.mockClear();
196
- recordFileOperationMetricModule(mockConfig, FileOperation.UPDATE, undefined, undefined, undefined);
258
+ recordFileOperationMetricModule(mockConfig, {
259
+ operation: FileOperation.UPDATE,
260
+ });
197
261
  expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
198
262
  'session.id': 'test-session-id',
199
263
  operation: FileOperation.UPDATE,
@@ -202,7 +266,12 @@ describe('Telemetry Metrics', () => {
202
266
  it('should record minimal file operation when optional parameters are undefined', () => {
203
267
  initializeMetricsModule(mockConfig);
204
268
  mockCounterAddFn.mockClear();
205
- recordFileOperationMetricModule(mockConfig, FileOperation.UPDATE, 10, 'text/plain', 'txt', undefined);
269
+ recordFileOperationMetricModule(mockConfig, {
270
+ operation: FileOperation.UPDATE,
271
+ lines: 10,
272
+ mimetype: 'text/plain',
273
+ extension: 'txt',
274
+ });
206
275
  expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
207
276
  'session.id': 'test-session-id',
208
277
  operation: FileOperation.UPDATE,
@@ -214,7 +283,9 @@ describe('Telemetry Metrics', () => {
214
283
  it('should not include diffStat attributes when diffStat is not provided', () => {
215
284
  initializeMetricsModule(mockConfig);
216
285
  mockCounterAddFn.mockClear();
217
- recordFileOperationMetricModule(mockConfig, FileOperation.UPDATE, undefined, undefined, undefined);
286
+ recordFileOperationMetricModule(mockConfig, {
287
+ operation: FileOperation.UPDATE,
288
+ });
218
289
  expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
219
290
  'session.id': 'test-session-id',
220
291
  operation: FileOperation.UPDATE,
@@ -224,6 +295,7 @@ describe('Telemetry Metrics', () => {
224
295
  describe('recordModelRoutingMetrics', () => {
225
296
  const mockConfig = {
226
297
  getSessionId: () => 'test-session-id',
298
+ getTelemetryEnabled: () => true,
227
299
  };
228
300
  it('should not record metrics if not initialized', () => {
229
301
  const event = new ModelRoutingEvent('gemini-pro', 'default', 100, 'test-reason', false, undefined);
@@ -260,5 +332,456 @@ describe('Telemetry Metrics', () => {
260
332
  });
261
333
  });
262
334
  });
335
+ describe('Performance Monitoring Metrics', () => {
336
+ const mockConfig = {
337
+ getSessionId: () => 'test-session-id',
338
+ getTelemetryEnabled: () => true,
339
+ };
340
+ describe('recordStartupPerformance', () => {
341
+ it('should not record metrics when performance monitoring is disabled', async () => {
342
+ // Re-import with performance monitoring disabled by mocking the config
343
+ const mockConfigDisabled = {
344
+ getSessionId: () => 'test-session-id',
345
+ getTelemetryEnabled: () => false, // Disable telemetry to disable performance monitoring
346
+ };
347
+ initializeMetricsModule(mockConfigDisabled);
348
+ mockHistogramRecordFn.mockClear();
349
+ recordStartupPerformanceModule(mockConfigDisabled, 100, {
350
+ phase: 'settings_loading',
351
+ details: {
352
+ auth_type: 'gemini',
353
+ },
354
+ });
355
+ expect(mockHistogramRecordFn).not.toHaveBeenCalled();
356
+ });
357
+ it('should record startup performance with phase and details', () => {
358
+ initializeMetricsModule(mockConfig);
359
+ mockHistogramRecordFn.mockClear();
360
+ recordStartupPerformanceModule(mockConfig, 150, {
361
+ phase: 'settings_loading',
362
+ details: {
363
+ auth_type: 'gemini',
364
+ telemetry_enabled: true,
365
+ settings_sources: 2,
366
+ },
367
+ });
368
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(150, {
369
+ 'session.id': 'test-session-id',
370
+ phase: 'settings_loading',
371
+ auth_type: 'gemini',
372
+ telemetry_enabled: true,
373
+ settings_sources: 2,
374
+ });
375
+ });
376
+ it('should record startup performance without details', () => {
377
+ initializeMetricsModule(mockConfig);
378
+ mockHistogramRecordFn.mockClear();
379
+ recordStartupPerformanceModule(mockConfig, 50, { phase: 'cleanup' });
380
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(50, {
381
+ 'session.id': 'test-session-id',
382
+ phase: 'cleanup',
383
+ });
384
+ });
385
+ it('should handle floating-point duration values from performance.now()', () => {
386
+ initializeMetricsModule(mockConfig);
387
+ mockHistogramRecordFn.mockClear();
388
+ // Test with realistic floating-point values that performance.now() would return
389
+ const floatingPointDuration = 123.45678;
390
+ recordStartupPerformanceModule(mockConfig, floatingPointDuration, {
391
+ phase: 'total_startup',
392
+ details: {
393
+ is_tty: true,
394
+ has_question: false,
395
+ },
396
+ });
397
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(floatingPointDuration, {
398
+ 'session.id': 'test-session-id',
399
+ phase: 'total_startup',
400
+ is_tty: true,
401
+ has_question: false,
402
+ });
403
+ });
404
+ });
405
+ describe('recordMemoryUsage', () => {
406
+ it('should record memory usage for different memory types', () => {
407
+ initializeMetricsModule(mockConfig);
408
+ mockHistogramRecordFn.mockClear();
409
+ recordMemoryUsageModule(mockConfig, 15728640, {
410
+ memory_type: MemoryMetricType.HEAP_USED,
411
+ component: 'startup',
412
+ });
413
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(15728640, {
414
+ 'session.id': 'test-session-id',
415
+ memory_type: 'heap_used',
416
+ component: 'startup',
417
+ });
418
+ });
419
+ it('should record memory usage for all memory metric types', () => {
420
+ initializeMetricsModule(mockConfig);
421
+ mockHistogramRecordFn.mockClear();
422
+ recordMemoryUsageModule(mockConfig, 31457280, {
423
+ memory_type: MemoryMetricType.HEAP_TOTAL,
424
+ component: 'api_call',
425
+ });
426
+ recordMemoryUsageModule(mockConfig, 2097152, {
427
+ memory_type: MemoryMetricType.EXTERNAL,
428
+ component: 'tool_execution',
429
+ });
430
+ recordMemoryUsageModule(mockConfig, 41943040, {
431
+ memory_type: MemoryMetricType.RSS,
432
+ component: 'memory_monitor',
433
+ });
434
+ expect(mockHistogramRecordFn).toHaveBeenCalledTimes(3); // One for each call
435
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(1, 31457280, {
436
+ 'session.id': 'test-session-id',
437
+ memory_type: 'heap_total',
438
+ component: 'api_call',
439
+ });
440
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(2, 2097152, {
441
+ 'session.id': 'test-session-id',
442
+ memory_type: 'external',
443
+ component: 'tool_execution',
444
+ });
445
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(3, 41943040, {
446
+ 'session.id': 'test-session-id',
447
+ memory_type: 'rss',
448
+ component: 'memory_monitor',
449
+ });
450
+ });
451
+ it('should record memory usage without component', () => {
452
+ initializeMetricsModule(mockConfig);
453
+ mockHistogramRecordFn.mockClear();
454
+ recordMemoryUsageModule(mockConfig, 15728640, {
455
+ memory_type: MemoryMetricType.HEAP_USED,
456
+ });
457
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(15728640, {
458
+ 'session.id': 'test-session-id',
459
+ memory_type: 'heap_used',
460
+ });
461
+ });
462
+ });
463
+ describe('recordCpuUsage', () => {
464
+ it('should record CPU usage percentage', () => {
465
+ initializeMetricsModule(mockConfig);
466
+ mockHistogramRecordFn.mockClear();
467
+ recordCpuUsageModule(mockConfig, 85.5, {
468
+ component: 'tool_execution',
469
+ });
470
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(85.5, {
471
+ 'session.id': 'test-session-id',
472
+ component: 'tool_execution',
473
+ });
474
+ });
475
+ it('should record CPU usage without component', () => {
476
+ initializeMetricsModule(mockConfig);
477
+ mockHistogramRecordFn.mockClear();
478
+ recordCpuUsageModule(mockConfig, 42.3, {});
479
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(42.3, {
480
+ 'session.id': 'test-session-id',
481
+ });
482
+ });
483
+ });
484
+ describe('recordToolQueueDepth', () => {
485
+ it('should record tool queue depth', () => {
486
+ initializeMetricsModule(mockConfig);
487
+ mockHistogramRecordFn.mockClear();
488
+ recordToolQueueDepthModule(mockConfig, 3);
489
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(3, {
490
+ 'session.id': 'test-session-id',
491
+ });
492
+ });
493
+ it('should record zero queue depth', () => {
494
+ initializeMetricsModule(mockConfig);
495
+ mockHistogramRecordFn.mockClear();
496
+ recordToolQueueDepthModule(mockConfig, 0);
497
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(0, {
498
+ 'session.id': 'test-session-id',
499
+ });
500
+ });
501
+ });
502
+ describe('recordToolExecutionBreakdown', () => {
503
+ it('should record tool execution breakdown for all phases', () => {
504
+ initializeMetricsModule(mockConfig);
505
+ mockHistogramRecordFn.mockClear();
506
+ recordToolExecutionBreakdownModule(mockConfig, 25, {
507
+ function_name: 'Read',
508
+ phase: ToolExecutionPhase.VALIDATION,
509
+ });
510
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(25, {
511
+ 'session.id': 'test-session-id',
512
+ function_name: 'Read',
513
+ phase: 'validation',
514
+ });
515
+ });
516
+ it('should record execution breakdown for different phases', () => {
517
+ initializeMetricsModule(mockConfig);
518
+ mockHistogramRecordFn.mockClear();
519
+ recordToolExecutionBreakdownModule(mockConfig, 50, {
520
+ function_name: 'Bash',
521
+ phase: ToolExecutionPhase.PREPARATION,
522
+ });
523
+ recordToolExecutionBreakdownModule(mockConfig, 1500, {
524
+ function_name: 'Bash',
525
+ phase: ToolExecutionPhase.EXECUTION,
526
+ });
527
+ recordToolExecutionBreakdownModule(mockConfig, 75, {
528
+ function_name: 'Bash',
529
+ phase: ToolExecutionPhase.RESULT_PROCESSING,
530
+ });
531
+ expect(mockHistogramRecordFn).toHaveBeenCalledTimes(3); // One for each call
532
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(1, 50, {
533
+ 'session.id': 'test-session-id',
534
+ function_name: 'Bash',
535
+ phase: 'preparation',
536
+ });
537
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(2, 1500, {
538
+ 'session.id': 'test-session-id',
539
+ function_name: 'Bash',
540
+ phase: 'execution',
541
+ });
542
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(3, 75, {
543
+ 'session.id': 'test-session-id',
544
+ function_name: 'Bash',
545
+ phase: 'result_processing',
546
+ });
547
+ });
548
+ });
549
+ describe('recordTokenEfficiency', () => {
550
+ it('should record token efficiency metrics', () => {
551
+ initializeMetricsModule(mockConfig);
552
+ mockHistogramRecordFn.mockClear();
553
+ recordTokenEfficiencyModule(mockConfig, 0.85, {
554
+ model: 'gemini-pro',
555
+ metric: 'cache_hit_rate',
556
+ context: 'api_request',
557
+ });
558
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(0.85, {
559
+ 'session.id': 'test-session-id',
560
+ model: 'gemini-pro',
561
+ metric: 'cache_hit_rate',
562
+ context: 'api_request',
563
+ });
564
+ });
565
+ it('should record token efficiency without context', () => {
566
+ initializeMetricsModule(mockConfig);
567
+ mockHistogramRecordFn.mockClear();
568
+ recordTokenEfficiencyModule(mockConfig, 125.5, {
569
+ model: 'gemini-pro',
570
+ metric: 'tokens_per_operation',
571
+ });
572
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(125.5, {
573
+ 'session.id': 'test-session-id',
574
+ model: 'gemini-pro',
575
+ metric: 'tokens_per_operation',
576
+ });
577
+ });
578
+ });
579
+ describe('recordApiRequestBreakdown', () => {
580
+ it('should record API request breakdown for all phases', () => {
581
+ initializeMetricsModule(mockConfig);
582
+ mockHistogramRecordFn.mockClear();
583
+ recordApiRequestBreakdownModule(mockConfig, 15, {
584
+ model: 'gemini-pro',
585
+ phase: ApiRequestPhase.REQUEST_PREPARATION,
586
+ });
587
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(15, {
588
+ 'session.id': 'test-session-id',
589
+ model: 'gemini-pro',
590
+ phase: 'request_preparation',
591
+ });
592
+ });
593
+ it('should record API request breakdown for different phases', () => {
594
+ initializeMetricsModule(mockConfig);
595
+ mockHistogramRecordFn.mockClear();
596
+ recordApiRequestBreakdownModule(mockConfig, 250, {
597
+ model: 'gemini-pro',
598
+ phase: ApiRequestPhase.NETWORK_LATENCY,
599
+ });
600
+ recordApiRequestBreakdownModule(mockConfig, 100, {
601
+ model: 'gemini-pro',
602
+ phase: ApiRequestPhase.RESPONSE_PROCESSING,
603
+ });
604
+ recordApiRequestBreakdownModule(mockConfig, 50, {
605
+ model: 'gemini-pro',
606
+ phase: ApiRequestPhase.TOKEN_PROCESSING,
607
+ });
608
+ expect(mockHistogramRecordFn).toHaveBeenCalledTimes(3); // One for each call
609
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(1, 250, {
610
+ 'session.id': 'test-session-id',
611
+ model: 'gemini-pro',
612
+ phase: 'network_latency',
613
+ });
614
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(2, 100, {
615
+ 'session.id': 'test-session-id',
616
+ model: 'gemini-pro',
617
+ phase: 'response_processing',
618
+ });
619
+ expect(mockHistogramRecordFn).toHaveBeenNthCalledWith(3, 50, {
620
+ 'session.id': 'test-session-id',
621
+ model: 'gemini-pro',
622
+ phase: 'token_processing',
623
+ });
624
+ });
625
+ });
626
+ describe('recordPerformanceScore', () => {
627
+ it('should record performance score with category and baseline', () => {
628
+ initializeMetricsModule(mockConfig);
629
+ mockHistogramRecordFn.mockClear();
630
+ recordPerformanceScoreModule(mockConfig, 85.5, {
631
+ category: 'memory_efficiency',
632
+ baseline: 80.0,
633
+ });
634
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(85.5, {
635
+ 'session.id': 'test-session-id',
636
+ category: 'memory_efficiency',
637
+ baseline: 80.0,
638
+ });
639
+ });
640
+ it('should record performance score without baseline', () => {
641
+ initializeMetricsModule(mockConfig);
642
+ mockHistogramRecordFn.mockClear();
643
+ recordPerformanceScoreModule(mockConfig, 92.3, {
644
+ category: 'overall_performance',
645
+ });
646
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(92.3, {
647
+ 'session.id': 'test-session-id',
648
+ category: 'overall_performance',
649
+ });
650
+ });
651
+ });
652
+ describe('recordPerformanceRegression', () => {
653
+ it('should record performance regression with baseline comparison', () => {
654
+ initializeMetricsModule(mockConfig);
655
+ mockCounterAddFn.mockClear();
656
+ mockHistogramRecordFn.mockClear();
657
+ recordPerformanceRegressionModule(mockConfig, {
658
+ metric: 'startup_time',
659
+ current_value: 1200,
660
+ baseline_value: 1000,
661
+ severity: 'medium',
662
+ });
663
+ // Verify regression counter
664
+ expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
665
+ 'session.id': 'test-session-id',
666
+ metric: 'startup_time',
667
+ severity: 'medium',
668
+ current_value: 1200,
669
+ baseline_value: 1000,
670
+ });
671
+ // Verify baseline comparison histogram (20% increase)
672
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(20, {
673
+ 'session.id': 'test-session-id',
674
+ metric: 'startup_time',
675
+ severity: 'medium',
676
+ current_value: 1200,
677
+ baseline_value: 1000,
678
+ });
679
+ });
680
+ it('should handle zero baseline value gracefully', () => {
681
+ initializeMetricsModule(mockConfig);
682
+ mockCounterAddFn.mockClear();
683
+ mockHistogramRecordFn.mockClear();
684
+ recordPerformanceRegressionModule(mockConfig, {
685
+ metric: 'memory_usage',
686
+ current_value: 100,
687
+ baseline_value: 0,
688
+ severity: 'high',
689
+ });
690
+ // Verify regression counter still recorded
691
+ expect(mockCounterAddFn).toHaveBeenCalledWith(1, {
692
+ 'session.id': 'test-session-id',
693
+ metric: 'memory_usage',
694
+ severity: 'high',
695
+ current_value: 100,
696
+ baseline_value: 0,
697
+ });
698
+ // Verify no baseline comparison due to zero baseline
699
+ expect(mockHistogramRecordFn).not.toHaveBeenCalled();
700
+ });
701
+ it('should record different severity levels', () => {
702
+ initializeMetricsModule(mockConfig);
703
+ mockCounterAddFn.mockClear();
704
+ recordPerformanceRegressionModule(mockConfig, {
705
+ metric: 'api_latency',
706
+ current_value: 500,
707
+ baseline_value: 400,
708
+ severity: 'low',
709
+ });
710
+ recordPerformanceRegressionModule(mockConfig, {
711
+ metric: 'cpu_usage',
712
+ current_value: 90,
713
+ baseline_value: 70,
714
+ severity: 'high',
715
+ });
716
+ expect(mockCounterAddFn).toHaveBeenNthCalledWith(1, 1, {
717
+ 'session.id': 'test-session-id',
718
+ metric: 'api_latency',
719
+ severity: 'low',
720
+ current_value: 500,
721
+ baseline_value: 400,
722
+ });
723
+ expect(mockCounterAddFn).toHaveBeenNthCalledWith(2, 1, {
724
+ 'session.id': 'test-session-id',
725
+ metric: 'cpu_usage',
726
+ severity: 'high',
727
+ current_value: 90,
728
+ baseline_value: 70,
729
+ });
730
+ });
731
+ });
732
+ describe('recordBaselineComparison', () => {
733
+ it('should record baseline comparison with percentage change', () => {
734
+ initializeMetricsModule(mockConfig);
735
+ mockHistogramRecordFn.mockClear();
736
+ recordBaselineComparisonModule(mockConfig, {
737
+ metric: 'memory_usage',
738
+ current_value: 120,
739
+ baseline_value: 100,
740
+ category: 'performance_tracking',
741
+ });
742
+ // 20% increase: (120 - 100) / 100 * 100 = 20%
743
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(20, {
744
+ 'session.id': 'test-session-id',
745
+ metric: 'memory_usage',
746
+ category: 'performance_tracking',
747
+ current_value: 120,
748
+ baseline_value: 100,
749
+ });
750
+ });
751
+ it('should handle negative percentage change (improvement)', () => {
752
+ initializeMetricsModule(mockConfig);
753
+ mockHistogramRecordFn.mockClear();
754
+ recordBaselineComparisonModule(mockConfig, {
755
+ metric: 'startup_time',
756
+ current_value: 800,
757
+ baseline_value: 1000,
758
+ category: 'optimization',
759
+ });
760
+ // 20% decrease: (800 - 1000) / 1000 * 100 = -20%
761
+ expect(mockHistogramRecordFn).toHaveBeenCalledWith(-20, {
762
+ 'session.id': 'test-session-id',
763
+ metric: 'startup_time',
764
+ category: 'optimization',
765
+ current_value: 800,
766
+ baseline_value: 1000,
767
+ });
768
+ });
769
+ it('should skip recording when baseline is zero', async () => {
770
+ // Access the actual mocked module
771
+ const mockedModule = (await vi.importMock('@opentelemetry/api'));
772
+ const diagSpy = vi.spyOn(mockedModule.diag, 'warn');
773
+ initializeMetricsModule(mockConfig);
774
+ mockHistogramRecordFn.mockClear();
775
+ recordBaselineComparisonModule(mockConfig, {
776
+ metric: 'new_metric',
777
+ current_value: 50,
778
+ baseline_value: 0,
779
+ category: 'testing',
780
+ });
781
+ expect(diagSpy).toHaveBeenCalledWith('Baseline value is zero, skipping comparison.');
782
+ expect(mockHistogramRecordFn).not.toHaveBeenCalled();
783
+ });
784
+ });
785
+ });
263
786
  });
264
787
  //# sourceMappingURL=metrics.test.js.map