@google/gemini-cli-core 0.21.0-preview.0 → 0.21.0-preview.2
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/dist/google-gemini-cli-core-0.21.0-preview.1.tgz +0 -0
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/ide/ide-client.js +3 -3
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.js +17 -0
- package/dist/src/ide/ide-client.test.js.map +1 -1
- package/dist/src/services/sessionSummaryUtils.d.ts +8 -3
- package/dist/src/services/sessionSummaryUtils.js +106 -38
- package/dist/src/services/sessionSummaryUtils.js.map +1 -1
- package/dist/src/services/sessionSummaryUtils.test.js +83 -244
- package/dist/src/services/sessionSummaryUtils.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
7
|
-
import {
|
|
7
|
+
import { generateSummary, getPreviousSession } from './sessionSummaryUtils.js';
|
|
8
|
+
import * as fs from 'node:fs/promises';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
// Mock fs/promises
|
|
11
|
+
vi.mock('node:fs/promises');
|
|
12
|
+
const mockReaddir = fs.readdir;
|
|
8
13
|
// Mock the SessionSummaryService module
|
|
9
14
|
vi.mock('./sessionSummaryService.js', () => ({
|
|
10
15
|
SessionSummaryService: vi.fn().mockImplementation(() => ({
|
|
@@ -15,31 +20,32 @@ vi.mock('./sessionSummaryService.js', () => ({
|
|
|
15
20
|
vi.mock('../core/baseLlmClient.js', () => ({
|
|
16
21
|
BaseLlmClient: vi.fn(),
|
|
17
22
|
}));
|
|
23
|
+
// Helper to create a session with N user messages
|
|
24
|
+
function createSessionWithUserMessages(count, options = {}) {
|
|
25
|
+
return JSON.stringify({
|
|
26
|
+
sessionId: options.sessionId ?? 'session-id',
|
|
27
|
+
summary: options.summary,
|
|
28
|
+
messages: Array.from({ length: count }, (_, i) => ({
|
|
29
|
+
id: String(i + 1),
|
|
30
|
+
type: 'user',
|
|
31
|
+
content: [{ text: `Message ${i + 1}` }],
|
|
32
|
+
})),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
18
35
|
describe('sessionSummaryUtils', () => {
|
|
19
36
|
let mockConfig;
|
|
20
|
-
let mockChatRecordingService;
|
|
21
|
-
let mockGeminiClient;
|
|
22
37
|
let mockContentGenerator;
|
|
23
38
|
let mockGenerateSummary;
|
|
24
39
|
beforeEach(async () => {
|
|
25
40
|
vi.clearAllMocks();
|
|
26
41
|
// Setup mock content generator
|
|
27
42
|
mockContentGenerator = {};
|
|
28
|
-
// Setup mock chat recording service
|
|
29
|
-
mockChatRecordingService = {
|
|
30
|
-
getConversation: vi.fn(),
|
|
31
|
-
saveSummary: vi.fn(),
|
|
32
|
-
};
|
|
33
|
-
// Setup mock gemini client
|
|
34
|
-
mockGeminiClient = {
|
|
35
|
-
getChatRecordingService: vi
|
|
36
|
-
.fn()
|
|
37
|
-
.mockReturnValue(mockChatRecordingService),
|
|
38
|
-
};
|
|
39
43
|
// Setup mock config
|
|
40
44
|
mockConfig = {
|
|
41
45
|
getContentGenerator: vi.fn().mockReturnValue(mockContentGenerator),
|
|
42
|
-
|
|
46
|
+
storage: {
|
|
47
|
+
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
|
|
48
|
+
},
|
|
43
49
|
};
|
|
44
50
|
// Setup mock generateSummary function
|
|
45
51
|
mockGenerateSummary = vi.fn().mockResolvedValue('Add dark mode to the app');
|
|
@@ -52,246 +58,79 @@ describe('sessionSummaryUtils', () => {
|
|
|
52
58
|
afterEach(() => {
|
|
53
59
|
vi.restoreAllMocks();
|
|
54
60
|
});
|
|
55
|
-
describe('
|
|
56
|
-
it('should
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
startTime: '2025-12-03T00:00:00Z',
|
|
61
|
-
lastUpdated: '2025-12-03T00:10:00Z',
|
|
62
|
-
messages: [
|
|
63
|
-
{
|
|
64
|
-
id: '1',
|
|
65
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
66
|
-
type: 'user',
|
|
67
|
-
content: [{ text: 'How do I add dark mode?' }],
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
id: '2',
|
|
71
|
-
timestamp: '2025-12-03T00:01:00Z',
|
|
72
|
-
type: 'gemini',
|
|
73
|
-
content: [{ text: 'To add dark mode...' }],
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
};
|
|
77
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
78
|
-
await generateAndSaveSummary(mockConfig);
|
|
79
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
80
|
-
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
81
|
-
expect(mockGenerateSummary).toHaveBeenCalledWith({
|
|
82
|
-
messages: mockConversation.messages,
|
|
83
|
-
});
|
|
84
|
-
expect(mockChatRecordingService.saveSummary).toHaveBeenCalledTimes(1);
|
|
85
|
-
expect(mockChatRecordingService.saveSummary).toHaveBeenCalledWith('Add dark mode to the app');
|
|
61
|
+
describe('getPreviousSession', () => {
|
|
62
|
+
it('should return null if chats directory does not exist', async () => {
|
|
63
|
+
vi.mocked(fs.access).mockRejectedValue(new Error('ENOENT'));
|
|
64
|
+
const result = await getPreviousSession(mockConfig);
|
|
65
|
+
expect(result).toBeNull();
|
|
86
66
|
});
|
|
87
|
-
it('should
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
expect(
|
|
92
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
67
|
+
it('should return null if no session files exist', async () => {
|
|
68
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
69
|
+
mockReaddir.mockResolvedValue([]);
|
|
70
|
+
const result = await getPreviousSession(mockConfig);
|
|
71
|
+
expect(result).toBeNull();
|
|
93
72
|
});
|
|
94
|
-
it('should
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
expect(
|
|
73
|
+
it('should return null if most recent session already has summary', async () => {
|
|
74
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
75
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
76
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(5, { summary: 'Existing summary' }));
|
|
77
|
+
const result = await getPreviousSession(mockConfig);
|
|
78
|
+
expect(result).toBeNull();
|
|
100
79
|
});
|
|
101
|
-
it('should
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
summary: 'Existing summary',
|
|
108
|
-
messages: [
|
|
109
|
-
{
|
|
110
|
-
id: '1',
|
|
111
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
112
|
-
type: 'user',
|
|
113
|
-
content: [{ text: 'Hello' }],
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
};
|
|
117
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
118
|
-
await generateAndSaveSummary(mockConfig);
|
|
119
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
120
|
-
expect(mockGenerateSummary).not.toHaveBeenCalled();
|
|
121
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
80
|
+
it('should return null if most recent session has 1 or fewer user messages', async () => {
|
|
81
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
82
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
83
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(1));
|
|
84
|
+
const result = await getPreviousSession(mockConfig);
|
|
85
|
+
expect(result).toBeNull();
|
|
122
86
|
});
|
|
123
|
-
it('should
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
messages: [],
|
|
130
|
-
};
|
|
131
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
132
|
-
await generateAndSaveSummary(mockConfig);
|
|
133
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
134
|
-
expect(mockGenerateSummary).not.toHaveBeenCalled();
|
|
135
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
87
|
+
it('should return path if most recent session has more than 1 user message and no summary', async () => {
|
|
88
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
89
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
90
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(2));
|
|
91
|
+
const result = await getPreviousSession(mockConfig);
|
|
92
|
+
expect(result).toBe(path.join('/tmp/project', 'chats', 'session-2024-01-01T10-00-abc12345.json'));
|
|
136
93
|
});
|
|
137
|
-
it('should
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
147
|
-
type: 'user',
|
|
148
|
-
content: [{ text: 'Hello' }],
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
};
|
|
152
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
153
|
-
mockGenerateSummary.mockResolvedValue(null);
|
|
154
|
-
await generateAndSaveSummary(mockConfig);
|
|
155
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
156
|
-
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
157
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
94
|
+
it('should select most recently created session by filename', async () => {
|
|
95
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
96
|
+
mockReaddir.mockResolvedValue([
|
|
97
|
+
'session-2024-01-01T10-00-older000.json',
|
|
98
|
+
'session-2024-01-02T10-00-newer000.json',
|
|
99
|
+
]);
|
|
100
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(2));
|
|
101
|
+
const result = await getPreviousSession(mockConfig);
|
|
102
|
+
expect(result).toBe(path.join('/tmp/project', 'chats', 'session-2024-01-02T10-00-newer000.json'));
|
|
158
103
|
});
|
|
159
|
-
it('should
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
messages: [
|
|
166
|
-
{
|
|
167
|
-
id: '1',
|
|
168
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
169
|
-
type: 'user',
|
|
170
|
-
content: [{ text: 'Hello' }],
|
|
171
|
-
},
|
|
172
|
-
],
|
|
173
|
-
};
|
|
174
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
175
|
-
mockGenerateSummary.mockRejectedValue(new Error('API Error'));
|
|
176
|
-
// Should not throw
|
|
177
|
-
await expect(generateAndSaveSummary(mockConfig)).resolves.not.toThrow();
|
|
178
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
179
|
-
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
180
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
104
|
+
it('should return null if most recent session file is corrupted', async () => {
|
|
105
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
106
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
107
|
+
vi.mocked(fs.readFile).mockResolvedValue('invalid json');
|
|
108
|
+
const result = await getPreviousSession(mockConfig);
|
|
109
|
+
expect(result).toBeNull();
|
|
181
110
|
});
|
|
182
111
|
});
|
|
183
|
-
describe('
|
|
184
|
-
it('should
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
projectHash: 'test-hash',
|
|
188
|
-
startTime: '2025-12-03T00:00:00Z',
|
|
189
|
-
lastUpdated: '2025-12-03T00:10:00Z',
|
|
190
|
-
messages: [
|
|
191
|
-
{
|
|
192
|
-
id: '1',
|
|
193
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
194
|
-
type: 'user',
|
|
195
|
-
content: [{ text: 'Hello' }],
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
};
|
|
199
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
200
|
-
await generateAndSaveSummary(mockConfig);
|
|
201
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledTimes(1);
|
|
202
|
-
expect(mockChatRecordingService.getConversation).toHaveBeenCalledWith();
|
|
203
|
-
});
|
|
204
|
-
it('should call generateSummary() with correct messages', async () => {
|
|
205
|
-
const mockMessages = [
|
|
206
|
-
{
|
|
207
|
-
id: '1',
|
|
208
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
209
|
-
type: 'user',
|
|
210
|
-
content: [{ text: 'How do I add dark mode?' }],
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
id: '2',
|
|
214
|
-
timestamp: '2025-12-03T00:01:00Z',
|
|
215
|
-
type: 'gemini',
|
|
216
|
-
content: [{ text: 'To add dark mode...' }],
|
|
217
|
-
},
|
|
218
|
-
];
|
|
219
|
-
const mockConversation = {
|
|
220
|
-
sessionId: 'test-session',
|
|
221
|
-
projectHash: 'test-hash',
|
|
222
|
-
startTime: '2025-12-03T00:00:00Z',
|
|
223
|
-
lastUpdated: '2025-12-03T00:10:00Z',
|
|
224
|
-
messages: mockMessages,
|
|
225
|
-
};
|
|
226
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
227
|
-
await generateAndSaveSummary(mockConfig);
|
|
228
|
-
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
229
|
-
expect(mockGenerateSummary).toHaveBeenCalledWith({
|
|
230
|
-
messages: mockMessages,
|
|
231
|
-
});
|
|
112
|
+
describe('generateSummary', () => {
|
|
113
|
+
it('should not throw if getPreviousSession returns null', async () => {
|
|
114
|
+
vi.mocked(fs.access).mockRejectedValue(new Error('ENOENT'));
|
|
115
|
+
await expect(generateSummary(mockConfig)).resolves.not.toThrow();
|
|
232
116
|
});
|
|
233
|
-
it('should
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
{
|
|
241
|
-
id: '1',
|
|
242
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
243
|
-
type: 'user',
|
|
244
|
-
content: [{ text: 'Hello' }],
|
|
245
|
-
},
|
|
246
|
-
],
|
|
247
|
-
};
|
|
248
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
249
|
-
mockGenerateSummary.mockResolvedValue('Test summary');
|
|
250
|
-
await generateAndSaveSummary(mockConfig);
|
|
251
|
-
expect(mockChatRecordingService.saveSummary).toHaveBeenCalledTimes(1);
|
|
252
|
-
expect(mockChatRecordingService.saveSummary).toHaveBeenCalledWith('Test summary');
|
|
253
|
-
});
|
|
254
|
-
it('should not call saveSummary() if generation fails', async () => {
|
|
255
|
-
const mockConversation = {
|
|
256
|
-
sessionId: 'test-session',
|
|
257
|
-
projectHash: 'test-hash',
|
|
258
|
-
startTime: '2025-12-03T00:00:00Z',
|
|
259
|
-
lastUpdated: '2025-12-03T00:10:00Z',
|
|
260
|
-
messages: [
|
|
261
|
-
{
|
|
262
|
-
id: '1',
|
|
263
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
264
|
-
type: 'user',
|
|
265
|
-
content: [{ text: 'Hello' }],
|
|
266
|
-
},
|
|
267
|
-
],
|
|
268
|
-
};
|
|
269
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
270
|
-
mockGenerateSummary.mockResolvedValue(null);
|
|
271
|
-
await generateAndSaveSummary(mockConfig);
|
|
117
|
+
it('should generate and save summary for session needing one', async () => {
|
|
118
|
+
const sessionPath = path.join('/tmp/project', 'chats', 'session-2024-01-01T10-00-abc12345.json');
|
|
119
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
120
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
121
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(2));
|
|
122
|
+
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
123
|
+
await generateSummary(mockConfig);
|
|
272
124
|
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
273
|
-
expect(
|
|
125
|
+
expect(fs.writeFile).toHaveBeenCalledTimes(1);
|
|
126
|
+
expect(fs.writeFile).toHaveBeenCalledWith(sessionPath, expect.stringContaining('Add dark mode to the app'));
|
|
274
127
|
});
|
|
275
|
-
it('should
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
messages: [
|
|
282
|
-
{
|
|
283
|
-
id: '1',
|
|
284
|
-
timestamp: '2025-12-03T00:00:00Z',
|
|
285
|
-
type: 'user',
|
|
286
|
-
content: [{ text: 'Hello' }],
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
};
|
|
290
|
-
mockChatRecordingService.getConversation.mockReturnValue(mockConversation);
|
|
291
|
-
mockGenerateSummary.mockRejectedValue(new Error('Generation failed'));
|
|
292
|
-
await generateAndSaveSummary(mockConfig);
|
|
293
|
-
expect(mockGenerateSummary).toHaveBeenCalledTimes(1);
|
|
294
|
-
expect(mockChatRecordingService.saveSummary).not.toHaveBeenCalled();
|
|
128
|
+
it('should handle errors gracefully without throwing', async () => {
|
|
129
|
+
vi.mocked(fs.access).mockResolvedValue(undefined);
|
|
130
|
+
mockReaddir.mockResolvedValue(['session-2024-01-01T10-00-abc12345.json']);
|
|
131
|
+
vi.mocked(fs.readFile).mockResolvedValue(createSessionWithUserMessages(2));
|
|
132
|
+
mockGenerateSummary.mockRejectedValue(new Error('API Error'));
|
|
133
|
+
await expect(generateSummary(mockConfig)).resolves.not.toThrow();
|
|
295
134
|
});
|
|
296
135
|
});
|
|
297
136
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionSummaryUtils.test.js","sourceRoot":"","sources":["../../../src/services/sessionSummaryUtils.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sessionSummaryUtils.test.js","sourceRoot":"","sources":["../../../src/services/sessionSummaryUtils.test.ts"],"names":[],"mappings":"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"}
|