@lobehub/chat 1.37.0 → 1.37.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/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/locales/en-US/common.json +2 -2
- package/package.json +1 -1
- package/src/services/file/_deprecated.test.ts +119 -0
- package/src/services/file/{pglite.ts → _deprecated.ts} +28 -32
- package/src/services/file/client.test.ts +153 -74
- package/src/services/file/client.ts +32 -28
- package/src/services/file/index.ts +2 -2
- package/src/services/import/_deprecated.ts +74 -0
- package/src/services/import/{pglite.test.ts → client.test.ts} +1 -1
- package/src/services/import/client.ts +21 -61
- package/src/services/import/index.ts +2 -2
- package/src/services/message/_deprecated.test.ts +398 -0
- package/src/services/message/_deprecated.ts +121 -0
- package/src/services/message/client.test.ts +191 -159
- package/src/services/message/client.ts +47 -50
- package/src/services/message/index.ts +2 -2
- package/src/services/plugin/_deprecated.test.ts +162 -0
- package/src/services/plugin/_deprecated.ts +42 -0
- package/src/services/plugin/client.test.ts +68 -55
- package/src/services/plugin/client.ts +20 -11
- package/src/services/plugin/index.ts +2 -2
- package/src/services/session/_deprecated.test.ts +440 -0
- package/src/services/session/_deprecated.ts +183 -0
- package/src/services/session/client.test.ts +212 -241
- package/src/services/session/client.ts +61 -60
- package/src/services/session/index.ts +2 -2
- package/src/services/topic/{client.test.ts → _deprecated.test.ts} +1 -1
- package/src/services/topic/_deprecated.ts +70 -0
- package/src/services/topic/client.ts +40 -25
- package/src/services/topic/index.ts +2 -2
- package/src/services/topic/pglite.test.ts +1 -1
- package/src/services/user/{pglite.test.ts → _deprecated.test.ts} +32 -29
- package/src/services/user/_deprecated.ts +57 -0
- package/src/services/user/client.test.ts +28 -31
- package/src/services/user/client.ts +51 -16
- package/src/services/user/index.ts +2 -2
- package/src/store/chat/slices/builtinTool/action.test.ts +1 -1
- package/src/store/user/slices/common/action.test.ts +1 -1
- package/src/services/file/pglite.test.ts +0 -198
- package/src/services/import/pglite.ts +0 -34
- package/src/services/message/pglite.test.ts +0 -430
- package/src/services/message/pglite.ts +0 -118
- package/src/services/plugin/pglite.test.ts +0 -175
- package/src/services/plugin/pglite.ts +0 -51
- package/src/services/session/pglite.test.ts +0 -411
- package/src/services/session/pglite.ts +0 -184
- package/src/services/topic/pglite.ts +0 -85
- package/src/services/user/pglite.ts +0 -92
@@ -1,5 +1,5 @@
|
|
1
|
-
import { ClientService as DeprecatedService } from './
|
2
|
-
import { ClientService } from './
|
1
|
+
import { ClientService as DeprecatedService } from './_deprecated';
|
2
|
+
import { ClientService } from './client';
|
3
3
|
import { ServerService } from './server';
|
4
4
|
|
5
5
|
const clientService =
|
@@ -0,0 +1,440 @@
|
|
1
|
+
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
2
|
+
|
3
|
+
import { SessionModel } from '@/database/_deprecated/models/session';
|
4
|
+
import { SessionGroupModel } from '@/database/_deprecated/models/sessionGroup';
|
5
|
+
import { LobeAgentConfig } from '@/types/agent';
|
6
|
+
import { LobeAgentSession, LobeSessionType, SessionGroups } from '@/types/session';
|
7
|
+
|
8
|
+
import { ClientService } from './_deprecated';
|
9
|
+
|
10
|
+
const sessionService = new ClientService();
|
11
|
+
|
12
|
+
// Mock the SessionModel
|
13
|
+
vi.mock('@/database/_deprecated/models/session', () => {
|
14
|
+
return {
|
15
|
+
SessionModel: {
|
16
|
+
create: vi.fn(),
|
17
|
+
query: vi.fn(),
|
18
|
+
delete: vi.fn(),
|
19
|
+
clearTable: vi.fn(),
|
20
|
+
update: vi.fn(),
|
21
|
+
count: vi.fn(),
|
22
|
+
batchCreate: vi.fn(),
|
23
|
+
findById: vi.fn(),
|
24
|
+
isEmpty: vi.fn(),
|
25
|
+
queryByKeyword: vi.fn(),
|
26
|
+
updateConfig: vi.fn(),
|
27
|
+
queryByGroupIds: vi.fn(),
|
28
|
+
updatePinned: vi.fn(),
|
29
|
+
duplicate: vi.fn(),
|
30
|
+
queryWithGroups: vi.fn(),
|
31
|
+
},
|
32
|
+
};
|
33
|
+
});
|
34
|
+
|
35
|
+
// Mock the SessionGroupModel
|
36
|
+
vi.mock('@/database/_deprecated/models/sessionGroup', () => {
|
37
|
+
return {
|
38
|
+
SessionGroupModel: {
|
39
|
+
create: vi.fn(),
|
40
|
+
query: vi.fn(),
|
41
|
+
delete: vi.fn(),
|
42
|
+
clear: vi.fn(),
|
43
|
+
update: vi.fn(),
|
44
|
+
batchCreate: vi.fn(),
|
45
|
+
isEmpty: vi.fn(),
|
46
|
+
updateOrder: vi.fn(),
|
47
|
+
queryByKeyword: vi.fn(),
|
48
|
+
updateConfig: vi.fn(),
|
49
|
+
queryByGroupIds: vi.fn(),
|
50
|
+
},
|
51
|
+
};
|
52
|
+
});
|
53
|
+
|
54
|
+
describe('SessionService', () => {
|
55
|
+
const mockSessionId = 'mock-session-id';
|
56
|
+
const mockSession = {
|
57
|
+
id: mockSessionId,
|
58
|
+
type: 'agent',
|
59
|
+
meta: { title: 'Mock Session' },
|
60
|
+
} as LobeAgentSession;
|
61
|
+
const mockSessions = [mockSession];
|
62
|
+
|
63
|
+
beforeEach(() => {
|
64
|
+
// Reset all mocks before running each test case
|
65
|
+
vi.resetAllMocks();
|
66
|
+
});
|
67
|
+
|
68
|
+
describe('createSession', () => {
|
69
|
+
it('should create a new session and return its id', async () => {
|
70
|
+
// Setup
|
71
|
+
const sessionType = LobeSessionType.Agent;
|
72
|
+
const defaultValue = { meta: { title: 'New Session' } } as Partial<LobeAgentSession>;
|
73
|
+
(SessionModel.create as Mock).mockResolvedValue(mockSession);
|
74
|
+
|
75
|
+
// Execute
|
76
|
+
const sessionId = await sessionService.createSession(sessionType, defaultValue);
|
77
|
+
|
78
|
+
// Assert
|
79
|
+
expect(SessionModel.create).toHaveBeenCalledWith(sessionType, defaultValue);
|
80
|
+
expect(sessionId).toBe(mockSessionId);
|
81
|
+
});
|
82
|
+
|
83
|
+
it('should throw an error if session creation fails', async () => {
|
84
|
+
// Setup
|
85
|
+
const sessionType = LobeSessionType.Agent;
|
86
|
+
const defaultValue = { meta: { title: 'New Session' } } as Partial<LobeAgentSession>;
|
87
|
+
(SessionModel.create as Mock).mockResolvedValue(null);
|
88
|
+
|
89
|
+
// Execute & Assert
|
90
|
+
await expect(sessionService.createSession(sessionType, defaultValue)).rejects.toThrow(
|
91
|
+
'session create Error',
|
92
|
+
);
|
93
|
+
});
|
94
|
+
});
|
95
|
+
|
96
|
+
describe('batchCreateSessions', () => {
|
97
|
+
it('should batch create sessions', async () => {
|
98
|
+
// Setup
|
99
|
+
(SessionModel.batchCreate as Mock).mockResolvedValue(mockSessions);
|
100
|
+
|
101
|
+
// Execute
|
102
|
+
const result = await sessionService.batchCreateSessions(mockSessions);
|
103
|
+
|
104
|
+
// Assert
|
105
|
+
expect(SessionModel.batchCreate).toHaveBeenCalledWith(mockSessions);
|
106
|
+
expect(result).toBe(mockSessions);
|
107
|
+
});
|
108
|
+
});
|
109
|
+
|
110
|
+
describe('getSessionsByType', () => {
|
111
|
+
it('should retrieve sessions with their group ids', async () => {
|
112
|
+
// Setup
|
113
|
+
(SessionModel.query as Mock).mockResolvedValue(mockSessions);
|
114
|
+
|
115
|
+
// Execute
|
116
|
+
const sessions = await sessionService.getSessionsByType();
|
117
|
+
|
118
|
+
// Assert
|
119
|
+
expect(SessionModel.query).toHaveBeenCalled();
|
120
|
+
expect(sessions).toBe(mockSessions);
|
121
|
+
});
|
122
|
+
|
123
|
+
it('should retrieve all agent sessions', async () => {
|
124
|
+
// Setup
|
125
|
+
// Assuming that SessionModel.query has been modified to accept filters
|
126
|
+
const agentSessions = mockSessions.filter((session) => session.type === 'agent');
|
127
|
+
(SessionModel.query as Mock).mockResolvedValue(agentSessions);
|
128
|
+
|
129
|
+
// Execute
|
130
|
+
const result = await sessionService.getSessionsByType('agent');
|
131
|
+
|
132
|
+
// Assert
|
133
|
+
// Assuming that SessionModel.query would be called with a filter for agents
|
134
|
+
expect(SessionModel.query).toHaveBeenCalled(); // Add filter argument if applicable
|
135
|
+
expect(result).toBe(agentSessions);
|
136
|
+
});
|
137
|
+
});
|
138
|
+
|
139
|
+
describe('removeSession', () => {
|
140
|
+
it('should remove a session by its id', async () => {
|
141
|
+
// Setup
|
142
|
+
(SessionModel.delete as Mock).mockResolvedValue(true);
|
143
|
+
|
144
|
+
// Execute
|
145
|
+
const result = await sessionService.removeSession(mockSessionId);
|
146
|
+
|
147
|
+
// Assert
|
148
|
+
expect(SessionModel.delete).toHaveBeenCalledWith(mockSessionId);
|
149
|
+
expect(result).toBe(true);
|
150
|
+
});
|
151
|
+
});
|
152
|
+
|
153
|
+
describe('removeAllSessions', () => {
|
154
|
+
it('should clear all sessions from the table', async () => {
|
155
|
+
// Setup
|
156
|
+
(SessionModel.clearTable as Mock).mockResolvedValue(true);
|
157
|
+
|
158
|
+
// Execute
|
159
|
+
const result = await sessionService.removeAllSessions();
|
160
|
+
|
161
|
+
// Assert
|
162
|
+
expect(SessionModel.clearTable).toHaveBeenCalled();
|
163
|
+
expect(result).toBe(true);
|
164
|
+
});
|
165
|
+
});
|
166
|
+
|
167
|
+
describe('updateSession', () => {
|
168
|
+
it('should update the group of a session', async () => {
|
169
|
+
// Setup
|
170
|
+
const groupId = 'new-group';
|
171
|
+
(SessionModel.update as Mock).mockResolvedValue({ ...mockSession, group: groupId });
|
172
|
+
|
173
|
+
// Execute
|
174
|
+
const result = await sessionService.updateSession(mockSessionId, { group: groupId });
|
175
|
+
|
176
|
+
// Assert
|
177
|
+
expect(SessionModel.update).toHaveBeenCalledWith(mockSessionId, { group: groupId });
|
178
|
+
expect(result).toEqual({ ...mockSession, group: groupId });
|
179
|
+
});
|
180
|
+
|
181
|
+
it('should update the meta of a session', async () => {
|
182
|
+
// Setup
|
183
|
+
const newMeta = { description: 'Updated description' };
|
184
|
+
(SessionModel.update as Mock).mockResolvedValue({ ...mockSession, meta: newMeta });
|
185
|
+
|
186
|
+
// Execute
|
187
|
+
const result = await sessionService.updateSession(mockSessionId, { meta: newMeta });
|
188
|
+
|
189
|
+
// Assert
|
190
|
+
expect(SessionModel.update).toHaveBeenCalledWith(mockSessionId, { meta: newMeta });
|
191
|
+
expect(result).toEqual({ ...mockSession, meta: newMeta });
|
192
|
+
});
|
193
|
+
|
194
|
+
it('should update the pinned status of a session', async () => {
|
195
|
+
// Setup
|
196
|
+
const pinned = true;
|
197
|
+
|
198
|
+
// Execute
|
199
|
+
await sessionService.updateSession(mockSessionId, { pinned });
|
200
|
+
|
201
|
+
// Assert
|
202
|
+
expect(SessionModel.update).toHaveBeenCalledWith(mockSessionId, { pinned: 1 });
|
203
|
+
});
|
204
|
+
});
|
205
|
+
|
206
|
+
describe('updateSessionConfig', () => {
|
207
|
+
it('should update the config of a session', async () => {
|
208
|
+
// Setup
|
209
|
+
const newConfig = { model: 'abc' } as LobeAgentConfig;
|
210
|
+
(SessionModel.updateConfig as Mock).mockResolvedValue({ ...mockSession, config: newConfig });
|
211
|
+
|
212
|
+
// Execute
|
213
|
+
const result = await sessionService.updateSessionConfig(mockSessionId, newConfig);
|
214
|
+
|
215
|
+
// Assert
|
216
|
+
expect(SessionModel.updateConfig).toHaveBeenCalledWith(mockSessionId, newConfig);
|
217
|
+
expect(result).toEqual({ ...mockSession, config: newConfig });
|
218
|
+
});
|
219
|
+
});
|
220
|
+
|
221
|
+
describe('countSessions', () => {
|
222
|
+
it('should return false if no sessions exist', async () => {
|
223
|
+
// Setup
|
224
|
+
(SessionModel.count as Mock).mockResolvedValue(0);
|
225
|
+
|
226
|
+
// Execute
|
227
|
+
const result = await sessionService.countSessions();
|
228
|
+
|
229
|
+
// Assert
|
230
|
+
expect(SessionModel.count).toHaveBeenCalled();
|
231
|
+
expect(result).toBe(0);
|
232
|
+
});
|
233
|
+
|
234
|
+
it('should return true if sessions exist', async () => {
|
235
|
+
// Setup
|
236
|
+
(SessionModel.count as Mock).mockResolvedValue(1);
|
237
|
+
|
238
|
+
// Execute
|
239
|
+
const result = await sessionService.countSessions();
|
240
|
+
|
241
|
+
// Assert
|
242
|
+
expect(SessionModel.count).toHaveBeenCalled();
|
243
|
+
expect(result).toBe(1);
|
244
|
+
});
|
245
|
+
});
|
246
|
+
|
247
|
+
describe('hasSessions', () => {
|
248
|
+
it('should return false if no sessions exist', async () => {
|
249
|
+
// Setup
|
250
|
+
(SessionModel.count as Mock).mockResolvedValue(0);
|
251
|
+
|
252
|
+
// Execute
|
253
|
+
const result = await sessionService.hasSessions();
|
254
|
+
|
255
|
+
// Assert
|
256
|
+
expect(SessionModel.count).toHaveBeenCalled();
|
257
|
+
expect(result).toBe(false);
|
258
|
+
});
|
259
|
+
|
260
|
+
it('should return true if sessions exist', async () => {
|
261
|
+
// Setup
|
262
|
+
(SessionModel.count as Mock).mockResolvedValue(1);
|
263
|
+
|
264
|
+
// Execute
|
265
|
+
const result = await sessionService.hasSessions();
|
266
|
+
|
267
|
+
// Assert
|
268
|
+
expect(SessionModel.count).toHaveBeenCalled();
|
269
|
+
expect(result).toBe(true);
|
270
|
+
});
|
271
|
+
});
|
272
|
+
|
273
|
+
describe('searchSessions', () => {
|
274
|
+
it('should return sessions that match the keyword', async () => {
|
275
|
+
// Setup
|
276
|
+
const keyword = 'search';
|
277
|
+
(SessionModel.queryByKeyword as Mock).mockResolvedValue(mockSessions);
|
278
|
+
|
279
|
+
// Execute
|
280
|
+
const result = await sessionService.searchSessions(keyword);
|
281
|
+
|
282
|
+
// Assert
|
283
|
+
expect(SessionModel.queryByKeyword).toHaveBeenCalledWith(keyword);
|
284
|
+
expect(result).toBe(mockSessions);
|
285
|
+
});
|
286
|
+
});
|
287
|
+
|
288
|
+
describe('cloneSession', () => {
|
289
|
+
it('should duplicate a session and return its id', async () => {
|
290
|
+
// Setup
|
291
|
+
const newTitle = 'Duplicated Session';
|
292
|
+
(SessionModel.duplicate as Mock).mockResolvedValue({
|
293
|
+
...mockSession,
|
294
|
+
id: 'duplicated-session-id',
|
295
|
+
});
|
296
|
+
|
297
|
+
// Execute
|
298
|
+
const duplicatedSessionId = await sessionService.cloneSession(mockSessionId, newTitle);
|
299
|
+
|
300
|
+
// Assert
|
301
|
+
expect(SessionModel.duplicate).toHaveBeenCalledWith(mockSessionId, newTitle);
|
302
|
+
expect(duplicatedSessionId).toBe('duplicated-session-id');
|
303
|
+
});
|
304
|
+
});
|
305
|
+
|
306
|
+
describe('getGroupedSessions', () => {
|
307
|
+
it('should retrieve sessions with their group', async () => {
|
308
|
+
// Setup
|
309
|
+
(SessionModel.queryWithGroups as Mock).mockResolvedValue(mockSessions);
|
310
|
+
|
311
|
+
// Execute
|
312
|
+
const sessionsWithGroup = await sessionService.getGroupedSessions();
|
313
|
+
|
314
|
+
// Assert
|
315
|
+
expect(SessionModel.queryWithGroups).toHaveBeenCalled();
|
316
|
+
expect(sessionsWithGroup).toBe(mockSessions);
|
317
|
+
});
|
318
|
+
});
|
319
|
+
|
320
|
+
// SessionGroup related tests
|
321
|
+
describe('createSessionGroup', () => {
|
322
|
+
it('should create a new session group and return its id', async () => {
|
323
|
+
// Setup
|
324
|
+
const groupName = 'New Group';
|
325
|
+
const sort = 1;
|
326
|
+
(SessionGroupModel.create as Mock).mockResolvedValue({
|
327
|
+
id: 'new-group-id',
|
328
|
+
name: groupName,
|
329
|
+
sort,
|
330
|
+
});
|
331
|
+
|
332
|
+
// Execute
|
333
|
+
const groupId = await sessionService.createSessionGroup(groupName, sort);
|
334
|
+
|
335
|
+
// Assert
|
336
|
+
expect(SessionGroupModel.create).toHaveBeenCalledWith(groupName, sort);
|
337
|
+
expect(groupId).toBe('new-group-id');
|
338
|
+
});
|
339
|
+
});
|
340
|
+
|
341
|
+
describe('batchCreateSessionGroups', () => {
|
342
|
+
it('should batch create session groups', async () => {
|
343
|
+
// Setup
|
344
|
+
const groups = [
|
345
|
+
{ id: 'group-1', name: 'Group 1', sort: 1 },
|
346
|
+
{ id: 'group-2', name: 'Group 2', sort: 2 },
|
347
|
+
] as SessionGroups;
|
348
|
+
|
349
|
+
(SessionGroupModel.batchCreate as Mock).mockResolvedValue(groups);
|
350
|
+
|
351
|
+
// Execute
|
352
|
+
const result = await sessionService.batchCreateSessionGroups(groups);
|
353
|
+
|
354
|
+
// Assert
|
355
|
+
expect(SessionGroupModel.batchCreate).toHaveBeenCalledWith(groups);
|
356
|
+
expect(result).toBe(groups);
|
357
|
+
});
|
358
|
+
});
|
359
|
+
|
360
|
+
describe('removeSessionGroup', () => {
|
361
|
+
it('should remove a session group by its id', async () => {
|
362
|
+
// Setup
|
363
|
+
const removeChildren = true;
|
364
|
+
(SessionGroupModel.delete as Mock).mockResolvedValue(true);
|
365
|
+
|
366
|
+
// Execute
|
367
|
+
const result = await sessionService.removeSessionGroup('group-id', removeChildren);
|
368
|
+
|
369
|
+
// Assert
|
370
|
+
expect(SessionGroupModel.delete).toHaveBeenCalledWith('group-id', removeChildren);
|
371
|
+
expect(result).toBe(true);
|
372
|
+
});
|
373
|
+
});
|
374
|
+
|
375
|
+
describe('clearSessionGroups', () => {
|
376
|
+
it('should clear all session groups', async () => {
|
377
|
+
// Setup
|
378
|
+
(SessionGroupModel.clear as Mock).mockResolvedValue(true);
|
379
|
+
|
380
|
+
// Execute
|
381
|
+
const result = await sessionService.removeSessionGroups();
|
382
|
+
|
383
|
+
// Assert
|
384
|
+
expect(SessionGroupModel.clear).toHaveBeenCalled();
|
385
|
+
expect(result).toBe(true);
|
386
|
+
});
|
387
|
+
});
|
388
|
+
|
389
|
+
describe('getSessionGroups', () => {
|
390
|
+
it('should retrieve all session groups', async () => {
|
391
|
+
// Setup
|
392
|
+
const groups = [
|
393
|
+
{ id: 'group-1', name: 'Group 1', sort: 1 },
|
394
|
+
{ id: 'group-2', name: 'Group 2', sort: 2 },
|
395
|
+
];
|
396
|
+
(SessionGroupModel.query as Mock).mockResolvedValue(groups);
|
397
|
+
|
398
|
+
// Execute
|
399
|
+
const result = await sessionService.getSessionGroups();
|
400
|
+
|
401
|
+
// Assert
|
402
|
+
expect(SessionGroupModel.query).toHaveBeenCalled();
|
403
|
+
expect(result).toBe(groups);
|
404
|
+
});
|
405
|
+
});
|
406
|
+
|
407
|
+
describe('updateSessionGroup', () => {
|
408
|
+
it('should update a session group', async () => {
|
409
|
+
// Setup
|
410
|
+
const groupId = 'group-1';
|
411
|
+
const data = { name: 'Updated Group', sort: 2 };
|
412
|
+
(SessionGroupModel.update as Mock).mockResolvedValue({ id: groupId, ...data });
|
413
|
+
|
414
|
+
// Execute
|
415
|
+
const result = await sessionService.updateSessionGroup(groupId, data);
|
416
|
+
|
417
|
+
// Assert
|
418
|
+
expect(SessionGroupModel.update).toHaveBeenCalledWith(groupId, data);
|
419
|
+
expect(result).toEqual({ id: groupId, ...data });
|
420
|
+
});
|
421
|
+
});
|
422
|
+
|
423
|
+
describe('updateSessionGroupOrder', () => {
|
424
|
+
it('should update the order of session groups', async () => {
|
425
|
+
// Setup
|
426
|
+
const sortMap = [
|
427
|
+
{ id: 'group-1', sort: 2 },
|
428
|
+
{ id: 'group-2', sort: 1 },
|
429
|
+
];
|
430
|
+
(SessionGroupModel.updateOrder as Mock).mockResolvedValue(true);
|
431
|
+
|
432
|
+
// Execute
|
433
|
+
const result = await sessionService.updateSessionGroupOrder(sortMap);
|
434
|
+
|
435
|
+
// Assert
|
436
|
+
expect(SessionGroupModel.updateOrder).toHaveBeenCalledWith(sortMap);
|
437
|
+
expect(result).toBe(true);
|
438
|
+
});
|
439
|
+
});
|
440
|
+
});
|
@@ -0,0 +1,183 @@
|
|
1
|
+
import { DeepPartial } from 'utility-types';
|
2
|
+
|
3
|
+
import { INBOX_SESSION_ID } from '@/const/session';
|
4
|
+
import { SessionModel } from '@/database/_deprecated/models/session';
|
5
|
+
import { SessionGroupModel } from '@/database/_deprecated/models/sessionGroup';
|
6
|
+
import { UserModel } from '@/database/_deprecated/models/user';
|
7
|
+
import { useUserStore } from '@/store/user';
|
8
|
+
import { LobeAgentChatConfig, LobeAgentConfig } from '@/types/agent';
|
9
|
+
import { MetaData } from '@/types/meta';
|
10
|
+
import {
|
11
|
+
ChatSessionList,
|
12
|
+
LobeAgentSession,
|
13
|
+
LobeSessionType,
|
14
|
+
LobeSessions,
|
15
|
+
SessionGroupItem,
|
16
|
+
SessionGroups,
|
17
|
+
} from '@/types/session';
|
18
|
+
import { merge } from '@/utils/merge';
|
19
|
+
|
20
|
+
import { ISessionService } from './type';
|
21
|
+
|
22
|
+
export class ClientService implements ISessionService {
|
23
|
+
async createSession(
|
24
|
+
type: LobeSessionType,
|
25
|
+
defaultValue: Partial<LobeAgentSession>,
|
26
|
+
): Promise<string> {
|
27
|
+
const item = await SessionModel.create(type, defaultValue);
|
28
|
+
if (!item) {
|
29
|
+
throw new Error('session create Error');
|
30
|
+
}
|
31
|
+
return item.id;
|
32
|
+
}
|
33
|
+
|
34
|
+
async batchCreateSessions(importSessions: LobeSessions) {
|
35
|
+
return SessionModel.batchCreate(importSessions);
|
36
|
+
}
|
37
|
+
|
38
|
+
async cloneSession(id: string, newTitle: string): Promise<string | undefined> {
|
39
|
+
const res = await SessionModel.duplicate(id, newTitle);
|
40
|
+
|
41
|
+
if (res) return res?.id;
|
42
|
+
}
|
43
|
+
|
44
|
+
async getGroupedSessions(): Promise<ChatSessionList> {
|
45
|
+
return SessionModel.queryWithGroups();
|
46
|
+
}
|
47
|
+
|
48
|
+
async getSessionConfig(id: string): Promise<LobeAgentConfig> {
|
49
|
+
if (!id || id === INBOX_SESSION_ID) {
|
50
|
+
return UserModel.getAgentConfig();
|
51
|
+
}
|
52
|
+
|
53
|
+
const res = await SessionModel.findById(id);
|
54
|
+
|
55
|
+
if (!res) throw new Error('Session not found');
|
56
|
+
|
57
|
+
return res.config as LobeAgentConfig;
|
58
|
+
}
|
59
|
+
|
60
|
+
async getSessionsByType(type: 'agent' | 'group' | 'all' = 'all'): Promise<LobeSessions> {
|
61
|
+
switch (type) {
|
62
|
+
// TODO: add a filter to get only agents or agents
|
63
|
+
case 'group': {
|
64
|
+
return SessionModel.query();
|
65
|
+
}
|
66
|
+
case 'agent': {
|
67
|
+
return SessionModel.query();
|
68
|
+
}
|
69
|
+
|
70
|
+
case 'all': {
|
71
|
+
return SessionModel.query();
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
async getAllAgents(): Promise<LobeSessions> {
|
77
|
+
// TODO: add a filter to get only agents
|
78
|
+
return await SessionModel.query();
|
79
|
+
}
|
80
|
+
|
81
|
+
async countSessions() {
|
82
|
+
return SessionModel.count();
|
83
|
+
}
|
84
|
+
|
85
|
+
async hasSessions() {
|
86
|
+
return (await this.countSessions()) !== 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
async searchSessions(keyword: string) {
|
90
|
+
return SessionModel.queryByKeyword(keyword);
|
91
|
+
}
|
92
|
+
|
93
|
+
async updateSession(
|
94
|
+
id: string,
|
95
|
+
data: Partial<Pick<LobeAgentSession, 'group' | 'meta' | 'pinned'>>,
|
96
|
+
) {
|
97
|
+
const pinned = typeof data.pinned === 'boolean' ? (data.pinned ? 1 : 0) : undefined;
|
98
|
+
const prev = await SessionModel.findById(id);
|
99
|
+
|
100
|
+
return SessionModel.update(id, merge(prev, { ...data, pinned }));
|
101
|
+
}
|
102
|
+
|
103
|
+
async updateSessionConfig(
|
104
|
+
activeId: string,
|
105
|
+
config: DeepPartial<LobeAgentConfig>,
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
107
|
+
_?: AbortSignal,
|
108
|
+
) {
|
109
|
+
// TODO: 需要删除这部分处理逻辑
|
110
|
+
// 后续直接给用户创建一个 inbox 的 session
|
111
|
+
if (activeId === INBOX_SESSION_ID) {
|
112
|
+
return useUserStore.getState().updateDefaultAgent({ config });
|
113
|
+
}
|
114
|
+
|
115
|
+
return SessionModel.updateConfig(activeId, config);
|
116
|
+
}
|
117
|
+
|
118
|
+
async updateSessionMeta(
|
119
|
+
activeId: string,
|
120
|
+
meta: Partial<MetaData>,
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
122
|
+
_?: AbortSignal,
|
123
|
+
) {
|
124
|
+
// inbox 不允许修改 meta
|
125
|
+
if (activeId === INBOX_SESSION_ID) return;
|
126
|
+
|
127
|
+
return SessionModel.update(activeId, { meta });
|
128
|
+
}
|
129
|
+
|
130
|
+
async updateSessionChatConfig(
|
131
|
+
activeId: string,
|
132
|
+
config: DeepPartial<LobeAgentChatConfig>,
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
134
|
+
_?: AbortSignal,
|
135
|
+
) {
|
136
|
+
return this.updateSessionConfig(activeId, { chatConfig: config });
|
137
|
+
}
|
138
|
+
|
139
|
+
async removeSession(id: string) {
|
140
|
+
return SessionModel.delete(id);
|
141
|
+
}
|
142
|
+
|
143
|
+
async removeAllSessions() {
|
144
|
+
return SessionModel.clearTable();
|
145
|
+
}
|
146
|
+
|
147
|
+
// ************************************** //
|
148
|
+
// *********** SessionGroup *********** //
|
149
|
+
// ************************************** //
|
150
|
+
|
151
|
+
async createSessionGroup(name: string, sort?: number) {
|
152
|
+
const item = await SessionGroupModel.create(name, sort);
|
153
|
+
if (!item) {
|
154
|
+
throw new Error('session group create Error');
|
155
|
+
}
|
156
|
+
|
157
|
+
return item.id;
|
158
|
+
}
|
159
|
+
|
160
|
+
async batchCreateSessionGroups(groups: SessionGroups) {
|
161
|
+
return SessionGroupModel.batchCreate(groups);
|
162
|
+
}
|
163
|
+
|
164
|
+
async removeSessionGroup(id: string, removeChildren?: boolean) {
|
165
|
+
return await SessionGroupModel.delete(id, removeChildren);
|
166
|
+
}
|
167
|
+
|
168
|
+
async updateSessionGroup(id: string, data: Partial<SessionGroupItem>) {
|
169
|
+
return SessionGroupModel.update(id, data as any);
|
170
|
+
}
|
171
|
+
|
172
|
+
async updateSessionGroupOrder(sortMap: { id: string; sort: number }[]) {
|
173
|
+
return SessionGroupModel.updateOrder(sortMap);
|
174
|
+
}
|
175
|
+
|
176
|
+
async getSessionGroups(): Promise<SessionGroupItem[]> {
|
177
|
+
return SessionGroupModel.query();
|
178
|
+
}
|
179
|
+
|
180
|
+
async removeSessionGroups() {
|
181
|
+
return SessionGroupModel.clear();
|
182
|
+
}
|
183
|
+
}
|