@google/gemini-cli-core 0.9.0-preview.1 → 0.10.0-nightly.20251009.ae02236c
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.
- package/README.md +87 -40
- package/dist/src/agents/executor.js +19 -8
- package/dist/src/agents/executor.js.map +1 -1
- package/dist/src/agents/executor.test.js +64 -1
- package/dist/src/agents/executor.test.js.map +1 -1
- package/dist/src/code_assist/setup.js +4 -2
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/config/config.d.ts +10 -0
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/core/client.d.ts +1 -0
- package/dist/src/core/client.js +23 -6
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +76 -0
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.js +3 -1
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/prompts.js +8 -8
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/turn.d.ts +10 -2
- package/dist/src/core/turn.js +1 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +11 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-installer.js +1 -1
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +13 -1
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +8 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +53 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +81 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +7 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +16 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +3 -0
- package/dist/src/telemetry/constants.js +4 -0
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +4 -2
- package/dist/src/telemetry/index.js +3 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +4 -1
- package/dist/src/telemetry/loggers.js +52 -3
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +83 -3
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/memory-monitor.d.ts +149 -0
- package/dist/src/telemetry/memory-monitor.js +335 -0
- package/dist/src/telemetry/memory-monitor.js.map +1 -0
- package/dist/src/telemetry/memory-monitor.test.d.ts +6 -0
- package/dist/src/telemetry/memory-monitor.test.js +472 -0
- package/dist/src/telemetry/memory-monitor.test.js.map +1 -0
- package/dist/src/telemetry/metrics.d.ts +29 -1
- package/dist/src/telemetry/metrics.js +48 -0
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +39 -1
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +25 -1
- package/dist/src/telemetry/types.js +40 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/smart-edit.d.ts +0 -19
- package/dist/src/tools/smart-edit.js +39 -51
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +60 -82
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +2 -0
- package/dist/src/tools/tool-names.js +2 -0
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/web-fetch.js +3 -0
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +44 -0
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/write-file.js +2 -1
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +1 -1
- package/dist/src/tools/write-todos.js +4 -3
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/utils/editCorrector.js +2 -2
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editor.js +1 -0
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +1 -0
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/formatters.d.ts +1 -0
- package/dist/src/utils/formatters.js +2 -1
- package/dist/src/utils/formatters.js.map +1 -1
- package/dist/src/utils/formatters.test.d.ts +6 -0
- package/dist/src/utils/formatters.test.js +26 -0
- package/dist/src/utils/formatters.test.js.map +1 -0
- package/dist/src/utils/llm-edit-fixer.js +3 -3
- package/dist/src/utils/pathCorrector.d.ts +25 -0
- package/dist/src/utils/pathCorrector.js +33 -0
- package/dist/src/utils/pathCorrector.js.map +1 -0
- package/dist/src/utils/pathCorrector.test.d.ts +6 -0
- package/dist/src/utils/pathCorrector.test.js +83 -0
- package/dist/src/utils/pathCorrector.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.9.0-preview.0.tgz +0 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
+
import v8 from 'node:v8';
|
|
8
|
+
import process from 'node:process';
|
|
9
|
+
import { MemoryMonitor, initializeMemoryMonitor, getMemoryMonitor, recordCurrentMemoryUsage, startGlobalMemoryMonitoring, stopGlobalMemoryMonitoring, _resetGlobalMemoryMonitorForTests, } from './memory-monitor.js';
|
|
10
|
+
import { recordMemoryUsage, isPerformanceMonitoringActive } from './metrics.js';
|
|
11
|
+
import { HighWaterMarkTracker } from './high-water-mark-tracker.js';
|
|
12
|
+
import { RateLimiter } from './rate-limiter.js';
|
|
13
|
+
// Mock dependencies
|
|
14
|
+
vi.mock('./metrics.js', () => ({
|
|
15
|
+
recordMemoryUsage: vi.fn(),
|
|
16
|
+
isPerformanceMonitoringActive: vi.fn(),
|
|
17
|
+
MemoryMetricType: {
|
|
18
|
+
HEAP_USED: 'heap_used',
|
|
19
|
+
HEAP_TOTAL: 'heap_total',
|
|
20
|
+
EXTERNAL: 'external',
|
|
21
|
+
RSS: 'rss',
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
// Mock Node.js modules
|
|
25
|
+
vi.mock('node:v8', () => ({
|
|
26
|
+
default: {
|
|
27
|
+
getHeapStatistics: vi.fn(),
|
|
28
|
+
getHeapSpaceStatistics: vi.fn(),
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
vi.mock('node:process', () => ({
|
|
32
|
+
default: {
|
|
33
|
+
memoryUsage: vi.fn(),
|
|
34
|
+
cpuUsage: vi.fn(),
|
|
35
|
+
uptime: vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
const mockRecordMemoryUsage = vi.mocked(recordMemoryUsage);
|
|
39
|
+
const mockIsPerformanceMonitoringActive = vi.mocked(isPerformanceMonitoringActive);
|
|
40
|
+
const mockV8GetHeapStatistics = vi.mocked(v8.getHeapStatistics);
|
|
41
|
+
const mockV8GetHeapSpaceStatistics = vi.mocked(v8.getHeapSpaceStatistics);
|
|
42
|
+
const mockProcessMemoryUsage = vi.mocked(process.memoryUsage);
|
|
43
|
+
const mockProcessCpuUsage = vi.mocked(process.cpuUsage);
|
|
44
|
+
const mockProcessUptime = vi.mocked(process.uptime);
|
|
45
|
+
// Mock config object
|
|
46
|
+
const mockConfig = {
|
|
47
|
+
getSessionId: () => 'test-session-id',
|
|
48
|
+
getTelemetryEnabled: () => true,
|
|
49
|
+
};
|
|
50
|
+
// Test data
|
|
51
|
+
const mockMemoryUsage = {
|
|
52
|
+
heapUsed: 15728640, // ~15MB
|
|
53
|
+
heapTotal: 31457280, // ~30MB
|
|
54
|
+
external: 2097152, // ~2MB
|
|
55
|
+
rss: 41943040, // ~40MB
|
|
56
|
+
arrayBuffers: 1048576, // ~1MB
|
|
57
|
+
};
|
|
58
|
+
const mockHeapStatistics = {
|
|
59
|
+
heap_size_limit: 536870912, // ~512MB
|
|
60
|
+
total_heap_size: 31457280,
|
|
61
|
+
total_heap_size_executable: 4194304, // ~4MB
|
|
62
|
+
total_physical_size: 31457280,
|
|
63
|
+
total_available_size: 1000000000, // ~1GB
|
|
64
|
+
used_heap_size: 15728640,
|
|
65
|
+
malloced_memory: 8192,
|
|
66
|
+
peak_malloced_memory: 16384,
|
|
67
|
+
does_zap_garbage: 0,
|
|
68
|
+
number_of_native_contexts: 1,
|
|
69
|
+
number_of_detached_contexts: 0,
|
|
70
|
+
total_global_handles_size: 8192,
|
|
71
|
+
used_global_handles_size: 4096,
|
|
72
|
+
external_memory: 2097152,
|
|
73
|
+
};
|
|
74
|
+
const mockHeapSpaceStatistics = [
|
|
75
|
+
{
|
|
76
|
+
space_name: 'new_space',
|
|
77
|
+
space_size: 8388608,
|
|
78
|
+
space_used_size: 4194304,
|
|
79
|
+
space_available_size: 4194304,
|
|
80
|
+
physical_space_size: 8388608,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
space_name: 'old_space',
|
|
84
|
+
space_size: 16777216,
|
|
85
|
+
space_used_size: 8388608,
|
|
86
|
+
space_available_size: 8388608,
|
|
87
|
+
physical_space_size: 16777216,
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
const mockCpuUsage = {
|
|
91
|
+
user: 1000000, // 1 second
|
|
92
|
+
system: 500000, // 0.5 seconds
|
|
93
|
+
};
|
|
94
|
+
describe('MemoryMonitor', () => {
|
|
95
|
+
beforeEach(() => {
|
|
96
|
+
vi.useFakeTimers();
|
|
97
|
+
vi.setSystemTime(new Date('2025-01-01T00:00:00.000Z'));
|
|
98
|
+
// Setup default mocks
|
|
99
|
+
mockIsPerformanceMonitoringActive.mockReturnValue(true);
|
|
100
|
+
mockProcessMemoryUsage.mockReturnValue(mockMemoryUsage);
|
|
101
|
+
mockV8GetHeapStatistics.mockReturnValue(mockHeapStatistics);
|
|
102
|
+
mockV8GetHeapSpaceStatistics.mockReturnValue(mockHeapSpaceStatistics);
|
|
103
|
+
mockProcessCpuUsage.mockReturnValue(mockCpuUsage);
|
|
104
|
+
mockProcessUptime.mockReturnValue(123.456);
|
|
105
|
+
});
|
|
106
|
+
afterEach(() => {
|
|
107
|
+
vi.restoreAllMocks();
|
|
108
|
+
vi.useRealTimers();
|
|
109
|
+
_resetGlobalMemoryMonitorForTests();
|
|
110
|
+
});
|
|
111
|
+
describe('MemoryMonitor Class', () => {
|
|
112
|
+
describe('constructor', () => {
|
|
113
|
+
it('should create a new MemoryMonitor instance without config to avoid multi-session attribution', () => {
|
|
114
|
+
const monitor = new MemoryMonitor();
|
|
115
|
+
expect(monitor).toBeInstanceOf(MemoryMonitor);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('takeSnapshot', () => {
|
|
119
|
+
it('should take a memory snapshot and record metrics when performance monitoring is active', () => {
|
|
120
|
+
const monitor = new MemoryMonitor();
|
|
121
|
+
const snapshot = monitor.takeSnapshot('test_context', mockConfig);
|
|
122
|
+
expect(snapshot).toEqual({
|
|
123
|
+
timestamp: Date.now(),
|
|
124
|
+
heapUsed: mockMemoryUsage.heapUsed,
|
|
125
|
+
heapTotal: mockMemoryUsage.heapTotal,
|
|
126
|
+
external: mockMemoryUsage.external,
|
|
127
|
+
rss: mockMemoryUsage.rss,
|
|
128
|
+
arrayBuffers: mockMemoryUsage.arrayBuffers,
|
|
129
|
+
heapSizeLimit: mockHeapStatistics.heap_size_limit,
|
|
130
|
+
});
|
|
131
|
+
// Verify metrics were recorded
|
|
132
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
133
|
+
memory_type: 'heap_used',
|
|
134
|
+
component: 'test_context',
|
|
135
|
+
});
|
|
136
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapTotal, {
|
|
137
|
+
memory_type: 'heap_total',
|
|
138
|
+
component: 'test_context',
|
|
139
|
+
});
|
|
140
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.external, {
|
|
141
|
+
memory_type: 'external',
|
|
142
|
+
component: 'test_context',
|
|
143
|
+
});
|
|
144
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.rss, {
|
|
145
|
+
memory_type: 'rss',
|
|
146
|
+
component: 'test_context',
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
it('should not record metrics when performance monitoring is inactive', () => {
|
|
150
|
+
mockIsPerformanceMonitoringActive.mockReturnValue(false);
|
|
151
|
+
const monitor = new MemoryMonitor();
|
|
152
|
+
const snapshot = monitor.takeSnapshot('test_context', mockConfig);
|
|
153
|
+
expect(snapshot).toEqual({
|
|
154
|
+
timestamp: Date.now(),
|
|
155
|
+
heapUsed: mockMemoryUsage.heapUsed,
|
|
156
|
+
heapTotal: mockMemoryUsage.heapTotal,
|
|
157
|
+
external: mockMemoryUsage.external,
|
|
158
|
+
rss: mockMemoryUsage.rss,
|
|
159
|
+
arrayBuffers: mockMemoryUsage.arrayBuffers,
|
|
160
|
+
heapSizeLimit: mockHeapStatistics.heap_size_limit,
|
|
161
|
+
});
|
|
162
|
+
// Verify no metrics were recorded
|
|
163
|
+
expect(mockRecordMemoryUsage).not.toHaveBeenCalled();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('getCurrentMemoryUsage', () => {
|
|
167
|
+
it('should return current memory usage without recording metrics', () => {
|
|
168
|
+
const monitor = new MemoryMonitor();
|
|
169
|
+
const usage = monitor.getCurrentMemoryUsage();
|
|
170
|
+
expect(usage).toEqual({
|
|
171
|
+
timestamp: Date.now(),
|
|
172
|
+
heapUsed: mockMemoryUsage.heapUsed,
|
|
173
|
+
heapTotal: mockMemoryUsage.heapTotal,
|
|
174
|
+
external: mockMemoryUsage.external,
|
|
175
|
+
rss: mockMemoryUsage.rss,
|
|
176
|
+
arrayBuffers: mockMemoryUsage.arrayBuffers,
|
|
177
|
+
heapSizeLimit: mockHeapStatistics.heap_size_limit,
|
|
178
|
+
});
|
|
179
|
+
// Verify no metrics were recorded
|
|
180
|
+
expect(mockRecordMemoryUsage).not.toHaveBeenCalled();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
describe('start and stop', () => {
|
|
184
|
+
it('should start and stop memory monitoring with proper lifecycle', () => {
|
|
185
|
+
const monitor = new MemoryMonitor();
|
|
186
|
+
const intervalMs = 1000;
|
|
187
|
+
// Start monitoring
|
|
188
|
+
monitor.start(mockConfig, intervalMs);
|
|
189
|
+
// Verify initial snapshot was taken
|
|
190
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
191
|
+
memory_type: 'heap_used',
|
|
192
|
+
component: 'monitoring_start',
|
|
193
|
+
});
|
|
194
|
+
// Fast-forward time to trigger periodic snapshot
|
|
195
|
+
vi.advanceTimersByTime(intervalMs);
|
|
196
|
+
// Verify monitoring_start snapshot was taken (multiple metrics)
|
|
197
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
|
|
198
|
+
memory_type: 'heap_used',
|
|
199
|
+
component: 'monitoring_start',
|
|
200
|
+
});
|
|
201
|
+
// Stop monitoring
|
|
202
|
+
monitor.stop(mockConfig);
|
|
203
|
+
// Verify final snapshot was taken
|
|
204
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
205
|
+
memory_type: 'heap_used',
|
|
206
|
+
component: 'monitoring_stop',
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
it('should not start monitoring when performance monitoring is inactive', () => {
|
|
210
|
+
mockIsPerformanceMonitoringActive.mockReturnValue(false);
|
|
211
|
+
const monitor = new MemoryMonitor();
|
|
212
|
+
monitor.start(mockConfig, 1000);
|
|
213
|
+
// Verify no snapshots were taken
|
|
214
|
+
expect(mockRecordMemoryUsage).not.toHaveBeenCalled();
|
|
215
|
+
});
|
|
216
|
+
it('should not start monitoring when already running', () => {
|
|
217
|
+
const monitor = new MemoryMonitor();
|
|
218
|
+
// Start monitoring twice
|
|
219
|
+
monitor.start(mockConfig, 1000);
|
|
220
|
+
const initialCallCount = mockRecordMemoryUsage.mock.calls.length;
|
|
221
|
+
monitor.start(mockConfig, 1000);
|
|
222
|
+
// Verify no additional snapshots were taken
|
|
223
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledTimes(initialCallCount);
|
|
224
|
+
});
|
|
225
|
+
it('should handle stop when not running', () => {
|
|
226
|
+
const monitor = new MemoryMonitor();
|
|
227
|
+
// Should not throw error
|
|
228
|
+
expect(() => monitor.stop(mockConfig)).not.toThrow();
|
|
229
|
+
});
|
|
230
|
+
it('should stop without taking final snapshot when no config provided', () => {
|
|
231
|
+
const monitor = new MemoryMonitor();
|
|
232
|
+
monitor.start(mockConfig, 1000);
|
|
233
|
+
const callsBeforeStop = mockRecordMemoryUsage.mock.calls.length;
|
|
234
|
+
monitor.stop(); // No config provided
|
|
235
|
+
// Verify no final snapshot was taken
|
|
236
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledTimes(callsBeforeStop);
|
|
237
|
+
});
|
|
238
|
+
it('should periodically cleanup tracker state to prevent growth', () => {
|
|
239
|
+
const trackerCleanupSpy = vi.spyOn(HighWaterMarkTracker.prototype, 'cleanup');
|
|
240
|
+
const rateLimiterCleanupSpy = vi.spyOn(RateLimiter.prototype, 'cleanup');
|
|
241
|
+
const monitor = new MemoryMonitor();
|
|
242
|
+
monitor.start(mockConfig, 1000);
|
|
243
|
+
trackerCleanupSpy.mockClear();
|
|
244
|
+
rateLimiterCleanupSpy.mockClear();
|
|
245
|
+
// Advance timers beyond the cleanup interval (15 minutes) to trigger cleanup
|
|
246
|
+
vi.advanceTimersByTime(16 * 60 * 1000);
|
|
247
|
+
expect(trackerCleanupSpy).toHaveBeenCalled();
|
|
248
|
+
expect(rateLimiterCleanupSpy).toHaveBeenCalled();
|
|
249
|
+
monitor.stop(mockConfig);
|
|
250
|
+
trackerCleanupSpy.mockRestore();
|
|
251
|
+
rateLimiterCleanupSpy.mockRestore();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe('getMemoryGrowth', () => {
|
|
255
|
+
it('should calculate memory growth between snapshots', () => {
|
|
256
|
+
const monitor = new MemoryMonitor();
|
|
257
|
+
// Take initial snapshot
|
|
258
|
+
monitor.takeSnapshot('initial', mockConfig);
|
|
259
|
+
// Change memory usage
|
|
260
|
+
const newMemoryUsage = {
|
|
261
|
+
...mockMemoryUsage,
|
|
262
|
+
heapUsed: mockMemoryUsage.heapUsed + 1048576, // +1MB
|
|
263
|
+
rss: mockMemoryUsage.rss + 2097152, // +2MB
|
|
264
|
+
};
|
|
265
|
+
mockProcessMemoryUsage.mockReturnValue(newMemoryUsage);
|
|
266
|
+
const growth = monitor.getMemoryGrowth();
|
|
267
|
+
expect(growth).toEqual({
|
|
268
|
+
heapUsed: 1048576,
|
|
269
|
+
heapTotal: 0,
|
|
270
|
+
external: 0,
|
|
271
|
+
rss: 2097152,
|
|
272
|
+
arrayBuffers: 0,
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
it('should return null when no previous snapshot exists', () => {
|
|
276
|
+
const monitor = new MemoryMonitor();
|
|
277
|
+
const growth = monitor.getMemoryGrowth();
|
|
278
|
+
expect(growth).toBeNull();
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
describe('checkMemoryThreshold', () => {
|
|
282
|
+
it('should return true when memory usage exceeds threshold', () => {
|
|
283
|
+
const monitor = new MemoryMonitor();
|
|
284
|
+
const thresholdMB = 10; // 10MB threshold
|
|
285
|
+
const exceeds = monitor.checkMemoryThreshold(thresholdMB);
|
|
286
|
+
expect(exceeds).toBe(true); // heapUsed is ~15MB
|
|
287
|
+
});
|
|
288
|
+
it('should return false when memory usage is below threshold', () => {
|
|
289
|
+
const monitor = new MemoryMonitor();
|
|
290
|
+
const thresholdMB = 20; // 20MB threshold
|
|
291
|
+
const exceeds = monitor.checkMemoryThreshold(thresholdMB);
|
|
292
|
+
expect(exceeds).toBe(false); // heapUsed is ~15MB
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
describe('getMemoryUsageSummary', () => {
|
|
296
|
+
it('should return memory usage summary in MB with proper rounding', () => {
|
|
297
|
+
const monitor = new MemoryMonitor();
|
|
298
|
+
const summary = monitor.getMemoryUsageSummary();
|
|
299
|
+
expect(summary).toEqual({
|
|
300
|
+
heapUsedMB: 15.0, // 15728640 bytes = 15MB
|
|
301
|
+
heapTotalMB: 30.0, // 31457280 bytes = 30MB
|
|
302
|
+
externalMB: 2.0, // 2097152 bytes = 2MB
|
|
303
|
+
rssMB: 40.0, // 41943040 bytes = 40MB
|
|
304
|
+
heapSizeLimitMB: 512.0, // 536870912 bytes = 512MB
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
describe('getHeapStatistics', () => {
|
|
309
|
+
it('should return V8 heap statistics', () => {
|
|
310
|
+
const monitor = new MemoryMonitor();
|
|
311
|
+
const stats = monitor.getHeapStatistics();
|
|
312
|
+
expect(stats).toBe(mockHeapStatistics);
|
|
313
|
+
expect(mockV8GetHeapStatistics).toHaveBeenCalled();
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
describe('getHeapSpaceStatistics', () => {
|
|
317
|
+
it('should return V8 heap space statistics', () => {
|
|
318
|
+
const monitor = new MemoryMonitor();
|
|
319
|
+
const stats = monitor.getHeapSpaceStatistics();
|
|
320
|
+
expect(stats).toBe(mockHeapSpaceStatistics);
|
|
321
|
+
expect(mockV8GetHeapSpaceStatistics).toHaveBeenCalled();
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
describe('getProcessMetrics', () => {
|
|
325
|
+
it('should return process CPU and memory metrics', () => {
|
|
326
|
+
const monitor = new MemoryMonitor();
|
|
327
|
+
const metrics = monitor.getProcessMetrics();
|
|
328
|
+
expect(metrics).toEqual({
|
|
329
|
+
cpuUsage: mockCpuUsage,
|
|
330
|
+
memoryUsage: mockMemoryUsage,
|
|
331
|
+
uptime: 123.456,
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
describe('recordComponentMemoryUsage', () => {
|
|
336
|
+
it('should record memory usage for specific component', () => {
|
|
337
|
+
const monitor = new MemoryMonitor();
|
|
338
|
+
const snapshot = monitor.recordComponentMemoryUsage(mockConfig, 'test_component');
|
|
339
|
+
expect(snapshot).toEqual({
|
|
340
|
+
timestamp: Date.now(),
|
|
341
|
+
heapUsed: mockMemoryUsage.heapUsed,
|
|
342
|
+
heapTotal: mockMemoryUsage.heapTotal,
|
|
343
|
+
external: mockMemoryUsage.external,
|
|
344
|
+
rss: mockMemoryUsage.rss,
|
|
345
|
+
arrayBuffers: mockMemoryUsage.arrayBuffers,
|
|
346
|
+
heapSizeLimit: mockHeapStatistics.heap_size_limit,
|
|
347
|
+
});
|
|
348
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
349
|
+
memory_type: 'heap_used',
|
|
350
|
+
component: 'test_component',
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
it('should record memory usage for component with operation', () => {
|
|
354
|
+
const monitor = new MemoryMonitor();
|
|
355
|
+
monitor.recordComponentMemoryUsage(mockConfig, 'test_component', 'test_operation');
|
|
356
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
357
|
+
memory_type: 'heap_used',
|
|
358
|
+
component: 'test_component_test_operation',
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
describe('destroy', () => {
|
|
363
|
+
it('should stop monitoring and cleanup resources', () => {
|
|
364
|
+
const monitor = new MemoryMonitor();
|
|
365
|
+
monitor.start(mockConfig, 1000);
|
|
366
|
+
monitor.destroy();
|
|
367
|
+
// Fast-forward time to ensure no more periodic snapshots
|
|
368
|
+
const callsBeforeDestroy = mockRecordMemoryUsage.mock.calls.length;
|
|
369
|
+
vi.advanceTimersByTime(2000);
|
|
370
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledTimes(callsBeforeDestroy);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
describe('Global Memory Monitor Functions', () => {
|
|
375
|
+
describe('initializeMemoryMonitor', () => {
|
|
376
|
+
it('should create singleton instance', () => {
|
|
377
|
+
const monitor1 = initializeMemoryMonitor();
|
|
378
|
+
const monitor2 = initializeMemoryMonitor();
|
|
379
|
+
expect(monitor1).toBe(monitor2);
|
|
380
|
+
expect(monitor1).toBeInstanceOf(MemoryMonitor);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
describe('getMemoryMonitor', () => {
|
|
384
|
+
it('should return null when not initialized', () => {
|
|
385
|
+
_resetGlobalMemoryMonitorForTests();
|
|
386
|
+
expect(getMemoryMonitor()).toBeNull();
|
|
387
|
+
});
|
|
388
|
+
it('should return initialized monitor', () => {
|
|
389
|
+
const initialized = initializeMemoryMonitor();
|
|
390
|
+
const retrieved = getMemoryMonitor();
|
|
391
|
+
expect(retrieved).toBe(initialized);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
describe('recordCurrentMemoryUsage', () => {
|
|
395
|
+
it('should initialize monitor and take snapshot', () => {
|
|
396
|
+
const snapshot = recordCurrentMemoryUsage(mockConfig, 'test_context');
|
|
397
|
+
expect(snapshot).toEqual({
|
|
398
|
+
timestamp: Date.now(),
|
|
399
|
+
heapUsed: mockMemoryUsage.heapUsed,
|
|
400
|
+
heapTotal: mockMemoryUsage.heapTotal,
|
|
401
|
+
external: mockMemoryUsage.external,
|
|
402
|
+
rss: mockMemoryUsage.rss,
|
|
403
|
+
arrayBuffers: mockMemoryUsage.arrayBuffers,
|
|
404
|
+
heapSizeLimit: mockHeapStatistics.heap_size_limit,
|
|
405
|
+
});
|
|
406
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
407
|
+
memory_type: 'heap_used',
|
|
408
|
+
component: 'test_context',
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
describe('startGlobalMemoryMonitoring', () => {
|
|
413
|
+
it('should initialize and start global monitoring', () => {
|
|
414
|
+
startGlobalMemoryMonitoring(mockConfig, 1000);
|
|
415
|
+
// Verify initial snapshot
|
|
416
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
417
|
+
memory_type: 'heap_used',
|
|
418
|
+
component: 'monitoring_start',
|
|
419
|
+
});
|
|
420
|
+
// Fast-forward and verify monitoring snapshot
|
|
421
|
+
vi.advanceTimersByTime(1000);
|
|
422
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
|
|
423
|
+
memory_type: 'heap_used',
|
|
424
|
+
component: 'monitoring_start',
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
describe('stopGlobalMemoryMonitoring', () => {
|
|
429
|
+
it('should stop global monitoring when monitor exists', () => {
|
|
430
|
+
startGlobalMemoryMonitoring(mockConfig, 1000);
|
|
431
|
+
stopGlobalMemoryMonitoring(mockConfig);
|
|
432
|
+
// Verify final snapshot
|
|
433
|
+
expect(mockRecordMemoryUsage).toHaveBeenCalledWith(mockConfig, mockMemoryUsage.heapUsed, {
|
|
434
|
+
memory_type: 'heap_used',
|
|
435
|
+
component: 'monitoring_stop',
|
|
436
|
+
});
|
|
437
|
+
// Verify no more periodic snapshots
|
|
438
|
+
const callsAfterStop = mockRecordMemoryUsage.mock.calls.length;
|
|
439
|
+
vi.advanceTimersByTime(2000);
|
|
440
|
+
expect(mockRecordMemoryUsage.mock.calls.length).toBe(callsAfterStop);
|
|
441
|
+
});
|
|
442
|
+
it('should handle stop when no global monitor exists', () => {
|
|
443
|
+
expect(() => stopGlobalMemoryMonitoring(mockConfig)).not.toThrow();
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
describe('Error Scenarios', () => {
|
|
448
|
+
it('should handle process.memoryUsage() errors gracefully', () => {
|
|
449
|
+
mockProcessMemoryUsage.mockImplementation(() => {
|
|
450
|
+
throw new Error('Memory access error');
|
|
451
|
+
});
|
|
452
|
+
const monitor = new MemoryMonitor();
|
|
453
|
+
expect(() => monitor.getCurrentMemoryUsage()).toThrow('Memory access error');
|
|
454
|
+
});
|
|
455
|
+
it('should handle v8.getHeapStatistics() errors gracefully', () => {
|
|
456
|
+
mockV8GetHeapStatistics.mockImplementation(() => {
|
|
457
|
+
throw new Error('Heap statistics error');
|
|
458
|
+
});
|
|
459
|
+
const monitor = new MemoryMonitor();
|
|
460
|
+
expect(() => monitor.getCurrentMemoryUsage()).toThrow('Heap statistics error');
|
|
461
|
+
});
|
|
462
|
+
it('should handle metric recording errors gracefully', () => {
|
|
463
|
+
mockRecordMemoryUsage.mockImplementation(() => {
|
|
464
|
+
throw new Error('Metric recording error');
|
|
465
|
+
});
|
|
466
|
+
const monitor = new MemoryMonitor();
|
|
467
|
+
// Should propagate error if metric recording fails
|
|
468
|
+
expect(() => monitor.takeSnapshot('test', mockConfig)).toThrow('Metric recording error');
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
//# sourceMappingURL=memory-monitor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-monitor.test.js","sourceRoot":"","sources":["../../../src/telemetry/memory-monitor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import type { Attributes, Meter, Counter, Histogram } from '@opentelemetry/api';
|
|
|
7
7
|
import { ValueType } from '@opentelemetry/api';
|
|
8
8
|
import { EVENT_CHAT_COMPRESSION } from './constants.js';
|
|
9
9
|
import type { Config } from '../config/config.js';
|
|
10
|
-
import type { ModelRoutingEvent, ModelSlashCommandEvent } from './types.js';
|
|
10
|
+
import type { ModelRoutingEvent, ModelSlashCommandEvent, AgentFinishEvent } from './types.js';
|
|
11
11
|
declare const TOOL_CALL_COUNT = "gemini_cli.tool.call.count";
|
|
12
12
|
declare const API_REQUEST_COUNT = "gemini_cli.api.request.count";
|
|
13
13
|
declare const TOKEN_USAGE = "gemini_cli.token.usage";
|
|
@@ -116,6 +116,15 @@ declare const COUNTER_DEFINITIONS: {
|
|
|
116
116
|
tokens_after: number;
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
|
+
readonly "gemini_cli.agent.run.count": {
|
|
120
|
+
readonly description: "Counts agent runs, tagged by name and termination reason.";
|
|
121
|
+
readonly valueType: ValueType.INT;
|
|
122
|
+
readonly assign: (c: Counter) => Counter<Attributes>;
|
|
123
|
+
readonly attributes: {
|
|
124
|
+
agent_name: string;
|
|
125
|
+
terminate_reason: string;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
119
128
|
};
|
|
120
129
|
declare const HISTOGRAM_DEFINITIONS: {
|
|
121
130
|
readonly "gemini_cli.tool.call.latency": {
|
|
@@ -146,6 +155,24 @@ declare const HISTOGRAM_DEFINITIONS: {
|
|
|
146
155
|
"routing.decision_source": string;
|
|
147
156
|
};
|
|
148
157
|
};
|
|
158
|
+
readonly "gemini_cli.agent.duration": {
|
|
159
|
+
readonly description: "Duration of agent runs in milliseconds.";
|
|
160
|
+
readonly unit: "ms";
|
|
161
|
+
readonly valueType: ValueType.INT;
|
|
162
|
+
readonly assign: (h: Histogram) => Histogram<Attributes>;
|
|
163
|
+
readonly attributes: {
|
|
164
|
+
agent_name: string;
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
readonly "gemini_cli.agent.turns": {
|
|
168
|
+
readonly description: "Number of turns taken by agents.";
|
|
169
|
+
readonly unit: "turns";
|
|
170
|
+
readonly valueType: ValueType.INT;
|
|
171
|
+
readonly assign: (h: Histogram) => Histogram<Attributes>;
|
|
172
|
+
readonly attributes: {
|
|
173
|
+
agent_name: string;
|
|
174
|
+
};
|
|
175
|
+
};
|
|
149
176
|
readonly "gen_ai.client.token.usage": {
|
|
150
177
|
readonly description: "Number of input and output tokens used.";
|
|
151
178
|
readonly unit: "token";
|
|
@@ -363,6 +390,7 @@ export declare function recordContentRetry(config: Config): void;
|
|
|
363
390
|
export declare function recordContentRetryFailure(config: Config): void;
|
|
364
391
|
export declare function recordModelSlashCommand(config: Config, event: ModelSlashCommandEvent): void;
|
|
365
392
|
export declare function recordModelRoutingMetrics(config: Config, event: ModelRoutingEvent): void;
|
|
393
|
+
export declare function recordAgentRunMetrics(config: Config, event: AgentFinishEvent): void;
|
|
366
394
|
export declare function recordGenAiClientTokenUsage(config: Config, tokenCount: number, attributes: MetricDefinitions[typeof GEN_AI_CLIENT_TOKEN_USAGE]['attributes']): void;
|
|
367
395
|
export declare function recordGenAiClientOperationDuration(config: Config, durationSeconds: number, attributes: MetricDefinitions[typeof GEN_AI_CLIENT_OPERATION_DURATION]['attributes']): void;
|
|
368
396
|
export declare function getConventionAttributes(event: {
|
|
@@ -19,6 +19,10 @@ const CONTENT_RETRY_FAILURE_COUNT = 'gemini_cli.chat.content_retry_failure.count
|
|
|
19
19
|
const MODEL_ROUTING_LATENCY = 'gemini_cli.model_routing.latency';
|
|
20
20
|
const MODEL_ROUTING_FAILURE_COUNT = 'gemini_cli.model_routing.failure.count';
|
|
21
21
|
const MODEL_SLASH_COMMAND_CALL_COUNT = 'gemini_cli.slash_command.model.call_count';
|
|
22
|
+
// Agent Metrics
|
|
23
|
+
const AGENT_RUN_COUNT = 'gemini_cli.agent.run.count';
|
|
24
|
+
const AGENT_DURATION_MS = 'gemini_cli.agent.duration';
|
|
25
|
+
const AGENT_TURNS = 'gemini_cli.agent.turns';
|
|
22
26
|
// OpenTelemetry GenAI Semantic Convention Metrics
|
|
23
27
|
const GEN_AI_CLIENT_TOKEN_USAGE = 'gen_ai.client.token.usage';
|
|
24
28
|
const GEN_AI_CLIENT_OPERATION_DURATION = 'gen_ai.client.operation.duration';
|
|
@@ -106,6 +110,12 @@ const COUNTER_DEFINITIONS = {
|
|
|
106
110
|
assign: (c) => (chatCompressionCounter = c),
|
|
107
111
|
attributes: {},
|
|
108
112
|
},
|
|
113
|
+
[AGENT_RUN_COUNT]: {
|
|
114
|
+
description: 'Counts agent runs, tagged by name and termination reason.',
|
|
115
|
+
valueType: ValueType.INT,
|
|
116
|
+
assign: (c) => (agentRunCounter = c),
|
|
117
|
+
attributes: {},
|
|
118
|
+
},
|
|
109
119
|
};
|
|
110
120
|
const HISTOGRAM_DEFINITIONS = {
|
|
111
121
|
[TOOL_CALL_LATENCY]: {
|
|
@@ -129,6 +139,20 @@ const HISTOGRAM_DEFINITIONS = {
|
|
|
129
139
|
assign: (h) => (modelRoutingLatencyHistogram = h),
|
|
130
140
|
attributes: {},
|
|
131
141
|
},
|
|
142
|
+
[AGENT_DURATION_MS]: {
|
|
143
|
+
description: 'Duration of agent runs in milliseconds.',
|
|
144
|
+
unit: 'ms',
|
|
145
|
+
valueType: ValueType.INT,
|
|
146
|
+
assign: (h) => (agentDurationHistogram = h),
|
|
147
|
+
attributes: {},
|
|
148
|
+
},
|
|
149
|
+
[AGENT_TURNS]: {
|
|
150
|
+
description: 'Number of turns taken by agents.',
|
|
151
|
+
unit: 'turns',
|
|
152
|
+
valueType: ValueType.INT,
|
|
153
|
+
assign: (h) => (agentTurnsHistogram = h),
|
|
154
|
+
attributes: {},
|
|
155
|
+
},
|
|
132
156
|
[GEN_AI_CLIENT_TOKEN_USAGE]: {
|
|
133
157
|
description: 'Number of input and output tokens used.',
|
|
134
158
|
unit: 'token',
|
|
@@ -289,6 +313,9 @@ let contentRetryFailureCounter;
|
|
|
289
313
|
let modelRoutingLatencyHistogram;
|
|
290
314
|
let modelRoutingFailureCounter;
|
|
291
315
|
let modelSlashCommandCallCounter;
|
|
316
|
+
let agentRunCounter;
|
|
317
|
+
let agentDurationHistogram;
|
|
318
|
+
let agentTurnsHistogram;
|
|
292
319
|
// OpenTelemetry GenAI Semantic Convention Metrics
|
|
293
320
|
let genAiClientTokenUsageHistogram;
|
|
294
321
|
let genAiClientOperationDurationHistogram;
|
|
@@ -452,6 +479,27 @@ export function recordModelRoutingMetrics(config, event) {
|
|
|
452
479
|
});
|
|
453
480
|
}
|
|
454
481
|
}
|
|
482
|
+
export function recordAgentRunMetrics(config, event) {
|
|
483
|
+
if (!agentRunCounter ||
|
|
484
|
+
!agentDurationHistogram ||
|
|
485
|
+
!agentTurnsHistogram ||
|
|
486
|
+
!isMetricsInitialized)
|
|
487
|
+
return;
|
|
488
|
+
const commonAttributes = baseMetricDefinition.getCommonAttributes(config);
|
|
489
|
+
agentRunCounter.add(1, {
|
|
490
|
+
...commonAttributes,
|
|
491
|
+
agent_name: event.agent_name,
|
|
492
|
+
terminate_reason: event.terminate_reason,
|
|
493
|
+
});
|
|
494
|
+
agentDurationHistogram.record(event.duration_ms, {
|
|
495
|
+
...commonAttributes,
|
|
496
|
+
agent_name: event.agent_name,
|
|
497
|
+
});
|
|
498
|
+
agentTurnsHistogram.record(event.turn_count, {
|
|
499
|
+
...commonAttributes,
|
|
500
|
+
agent_name: event.agent_name,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
455
503
|
// OpenTelemetry GenAI Semantic Convention Recording Functions
|
|
456
504
|
export function recordGenAiClientTokenUsage(config, tokenCount, attributes) {
|
|
457
505
|
if (!genAiClientTokenUsageHistogram || !isMetricsInitialized)
|