@lobehub/lobehub 2.0.0-next.12 → 2.0.0-next.14
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/package.json +1 -1
- package/packages/const/src/version.ts +3 -3
- package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
- package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
- package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
- package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +3 -28
- package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +0 -2
- package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +1 -5
- package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
- package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -1
- package/src/app/[variants]/(main)/image/page.tsx +0 -2
- package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
- package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
- package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
- package/src/app/[variants]/loading/index.tsx +1 -10
- package/src/components/Link.tsx +12 -0
- package/src/envs/app.ts +5 -8
- package/src/features/DataImporter/index.tsx +15 -60
- package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
- package/src/hooks/useInterceptingRoutes.test.ts +21 -3
- package/src/libs/trpc/client/index.ts +0 -1
- package/src/libs/trpc/client/lambda.ts +8 -5
- package/src/libs/trpc/lambda/context.ts +4 -1
- package/src/server/routers/desktop/mcp.ts +1 -3
- package/src/server/routers/lambda/config/index.test.ts +2 -2
- package/src/server/routers/tools/mcp.ts +2 -3
- package/src/server/routers/tools/search.test.ts +1 -7
- package/src/server/routers/tools/search.ts +1 -4
- package/src/services/__tests__/tool.test.ts +0 -3
- package/src/services/aiModel/index.test.ts +0 -3
- package/src/services/aiModel/index.ts +1 -7
- package/src/services/aiProvider/index.test.ts +0 -3
- package/src/services/aiProvider/index.ts +1 -7
- package/src/services/chatGroup/index.ts +1 -10
- package/src/services/config.ts +1 -65
- package/src/services/export/index.ts +1 -4
- package/src/services/file/index.ts +1 -11
- package/src/services/import/index.ts +1 -7
- package/src/services/message/index.ts +1 -11
- package/src/services/plugin/index.ts +1 -11
- package/src/services/session/index.ts +1 -11
- package/src/services/tableViewer/client.ts +12 -15
- package/src/services/thread/index.ts +1 -7
- package/src/services/topic/index.ts +1 -11
- package/src/services/user/index.ts +1 -13
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -241
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +26 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +3 -1
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +1 -138
- package/src/store/user/slices/common/action.test.ts +1 -4
- package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
- package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
- package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
- package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +0 -29
- package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
- package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
- package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
- package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
- package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
- package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
- package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
- package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
- package/src/app/[variants]/loading/Client/Content.tsx +0 -48
- package/src/app/[variants]/loading/Client/Error.tsx +0 -27
- package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
- package/src/app/[variants]/loading/Client/index.tsx +0 -22
- package/src/components/InnerLink.tsx +0 -20
- package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
- package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
- package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
- package/src/database/_deprecated/core/db.ts +0 -246
- package/src/database/_deprecated/core/index.ts +0 -2
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
- package/src/database/_deprecated/core/model.ts +0 -218
- package/src/database/_deprecated/core/schemas.ts +0 -88
- package/src/database/_deprecated/core/types/db.ts +0 -15
- package/src/database/_deprecated/models/__DEBUG.ts +0 -124
- package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
- package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
- package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
- package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
- package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
- package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
- package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
- package/src/database/_deprecated/models/file.ts +0 -51
- package/src/database/_deprecated/models/message.ts +0 -277
- package/src/database/_deprecated/models/plugin.ts +0 -62
- package/src/database/_deprecated/models/session.ts +0 -271
- package/src/database/_deprecated/models/sessionGroup.ts +0 -93
- package/src/database/_deprecated/models/topic.ts +0 -250
- package/src/database/_deprecated/models/user.ts +0 -69
- package/src/database/_deprecated/schemas/files.ts +0 -39
- package/src/database/_deprecated/schemas/message.ts +0 -50
- package/src/database/_deprecated/schemas/plugin.ts +0 -12
- package/src/database/_deprecated/schemas/session.ts +0 -54
- package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
- package/src/database/_deprecated/schemas/topic.ts +0 -12
- package/src/database/_deprecated/schemas/user.ts +0 -40
- package/src/features/DataImporter/_deprecated.ts +0 -43
- package/src/features/InitClientDB/EnableModal.tsx +0 -118
- package/src/features/InitClientDB/ErrorResult.tsx +0 -143
- package/src/features/InitClientDB/InitIndicator.tsx +0 -124
- package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
- package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
- package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
- package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
- package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
- package/src/features/InitClientDB/index.tsx +0 -37
- package/src/libs/trpc/client/edge.ts +0 -26
- package/src/libs/trpc/edge/context.ts +0 -71
- package/src/libs/trpc/edge/index.ts +0 -45
- package/src/libs/trpc/edge/init.ts +0 -26
- package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
- package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
- package/src/migrations/FromV0ToV1.ts +0 -10
- package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
- package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
- package/src/migrations/FromV1ToV2/index.ts +0 -82
- package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
- package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
- package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
- package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
- package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
- package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
- package/src/migrations/FromV2ToV3/index.ts +0 -30
- package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
- package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
- package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
- package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
- package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
- package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
- package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
- package/src/migrations/FromV3ToV4/index.ts +0 -102
- package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
- package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
- package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
- package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
- package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
- package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
- package/src/migrations/FromV4ToV5/index.ts +0 -58
- package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
- package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
- package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
- package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
- package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
- package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
- package/src/migrations/FromV5ToV6/index.ts +0 -61
- package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
- package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
- package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
- package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
- package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
- package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
- package/src/migrations/FromV6ToV7/index.ts +0 -101
- package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
- package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
- package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
- package/src/migrations/VersionController.test.ts +0 -88
- package/src/migrations/VersionController.ts +0 -67
- package/src/migrations/index.ts +0 -61
- package/src/server/routers/edge/appStatus.ts +0 -3
- package/src/server/routers/edge/index.ts +0 -14
- package/src/server/routers/edge/upload.ts +0 -16
- package/src/services/aiModel/client.ts +0 -70
- package/src/services/aiProvider/client.ts +0 -58
- package/src/services/baseClientService/index.ts +0 -9
- package/src/services/chatGroup/client.ts +0 -63
- package/src/services/export/_deprecated.ts +0 -155
- package/src/services/export/client.ts +0 -15
- package/src/services/file/_deprecated.test.ts +0 -119
- package/src/services/file/_deprecated.ts +0 -80
- package/src/services/file/client.test.ts +0 -199
- package/src/services/file/client.ts +0 -85
- package/src/services/import/_deprecated.ts +0 -115
- package/src/services/import/client.test.ts +0 -1015
- package/src/services/import/client.ts +0 -64
- package/src/services/message/_deprecated.test.ts +0 -398
- package/src/services/message/_deprecated.ts +0 -168
- package/src/services/message/client.test.ts +0 -410
- package/src/services/message/client.ts +0 -192
- package/src/services/plugin/_deprecated.test.ts +0 -162
- package/src/services/plugin/_deprecated.ts +0 -42
- package/src/services/plugin/client.test.ts +0 -177
- package/src/services/plugin/client.ts +0 -46
- package/src/services/session/_deprecated.test.ts +0 -440
- package/src/services/session/_deprecated.ts +0 -190
- package/src/services/session/client.test.ts +0 -413
- package/src/services/session/client.ts +0 -193
- package/src/services/thread/client.ts +0 -51
- package/src/services/topic/_deprecated.test.ts +0 -245
- package/src/services/topic/_deprecated.ts +0 -75
- package/src/services/topic/client.ts +0 -89
- package/src/services/topic/pglite.test.ts +0 -212
- package/src/services/user/_deprecated.test.ts +0 -101
- package/src/services/user/_deprecated.ts +0 -70
- package/src/services/user/client.test.ts +0 -111
- package/src/services/user/client.ts +0 -104
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChatMessageError,
|
|
3
|
-
ChatTTS,
|
|
4
|
-
ChatTranslate,
|
|
5
|
-
CreateMessageParams,
|
|
6
|
-
DBMessageItem,
|
|
7
|
-
UIChatMessage,
|
|
8
|
-
} from '@lobechat/types';
|
|
9
|
-
import { and, eq } from 'drizzle-orm';
|
|
10
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
11
|
-
|
|
12
|
-
import { clientDB, initializeDB } from '@/database/client/db';
|
|
13
|
-
import {
|
|
14
|
-
files,
|
|
15
|
-
messagePlugins,
|
|
16
|
-
messageTTS,
|
|
17
|
-
messageTranslates,
|
|
18
|
-
messages,
|
|
19
|
-
sessions,
|
|
20
|
-
topics,
|
|
21
|
-
users,
|
|
22
|
-
} from '@/database/schemas';
|
|
23
|
-
|
|
24
|
-
import { ClientService } from './client';
|
|
25
|
-
|
|
26
|
-
const userId = 'message-db';
|
|
27
|
-
const sessionId = '1';
|
|
28
|
-
const topicId = 'topic-id';
|
|
29
|
-
|
|
30
|
-
// Mock data
|
|
31
|
-
const mockMessageId = 'mock-message-id';
|
|
32
|
-
const mockMessage = {
|
|
33
|
-
id: mockMessageId,
|
|
34
|
-
content: 'Mock message content',
|
|
35
|
-
sessionId,
|
|
36
|
-
role: 'user',
|
|
37
|
-
} as UIChatMessage;
|
|
38
|
-
|
|
39
|
-
const mockMessages = [mockMessage];
|
|
40
|
-
|
|
41
|
-
beforeEach(async () => {
|
|
42
|
-
await initializeDB();
|
|
43
|
-
|
|
44
|
-
// 在每个测试用例之前,清空表
|
|
45
|
-
await clientDB.transaction(async (trx) => {
|
|
46
|
-
await trx.delete(users);
|
|
47
|
-
await trx.insert(users).values([{ id: userId }, { id: '456' }]);
|
|
48
|
-
|
|
49
|
-
await trx.insert(sessions).values([{ id: sessionId, userId }]);
|
|
50
|
-
await trx.insert(topics).values([{ id: topicId, sessionId, userId }]);
|
|
51
|
-
await trx.insert(files).values({
|
|
52
|
-
id: 'f1',
|
|
53
|
-
userId: userId,
|
|
54
|
-
url: 'abc',
|
|
55
|
-
name: 'file-1',
|
|
56
|
-
fileType: 'image/png',
|
|
57
|
-
size: 1000,
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
afterEach(async () => {
|
|
63
|
-
// 在每个测试用例之后,清空表
|
|
64
|
-
await clientDB.delete(users);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const messageService = new ClientService(userId);
|
|
68
|
-
|
|
69
|
-
describe('MessageClientService', () => {
|
|
70
|
-
describe('create', () => {
|
|
71
|
-
it('should create a message and return its id', async () => {
|
|
72
|
-
// Setup
|
|
73
|
-
const createParams: CreateMessageParams = {
|
|
74
|
-
content: 'New message content',
|
|
75
|
-
sessionId,
|
|
76
|
-
role: 'user',
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// Execute
|
|
80
|
-
const messageId = await messageService.createMessage(createParams);
|
|
81
|
-
|
|
82
|
-
// Assert
|
|
83
|
-
expect(messageId).toMatch(/^msg_/);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('batchCreate', () => {
|
|
88
|
-
it('should batch create messages', async () => {
|
|
89
|
-
// Execute
|
|
90
|
-
await messageService.batchCreateMessages([
|
|
91
|
-
{
|
|
92
|
-
content: 'Mock message content',
|
|
93
|
-
sessionId,
|
|
94
|
-
role: 'user',
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
content: 'Mock message content',
|
|
98
|
-
sessionId,
|
|
99
|
-
role: 'user',
|
|
100
|
-
},
|
|
101
|
-
] as DBMessageItem[]);
|
|
102
|
-
const count = await clientDB.$count(messages);
|
|
103
|
-
|
|
104
|
-
// Assert
|
|
105
|
-
expect(count).toBe(2);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
describe('removeMessage', () => {
|
|
110
|
-
it('should remove a message by id', async () => {
|
|
111
|
-
// Execute
|
|
112
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
113
|
-
await messageService.removeMessage(mockMessageId);
|
|
114
|
-
|
|
115
|
-
// Assert
|
|
116
|
-
const count = await clientDB.$count(messages);
|
|
117
|
-
|
|
118
|
-
expect(count).toBe(0);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
describe('removeMessages', () => {
|
|
122
|
-
it('should remove a message by id', async () => {
|
|
123
|
-
// Setup
|
|
124
|
-
await clientDB.insert(messages).values([
|
|
125
|
-
{ id: mockMessageId, role: 'user', userId },
|
|
126
|
-
{ role: 'assistant', userId },
|
|
127
|
-
]);
|
|
128
|
-
|
|
129
|
-
// Execute
|
|
130
|
-
await messageService.removeMessages([mockMessageId]);
|
|
131
|
-
|
|
132
|
-
// Assert
|
|
133
|
-
const count = await clientDB.$count(messages);
|
|
134
|
-
|
|
135
|
-
expect(count).toBe(1);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('getMessages', () => {
|
|
140
|
-
it('should retrieve messages by sessionId and topicId', async () => {
|
|
141
|
-
// Setup
|
|
142
|
-
await clientDB
|
|
143
|
-
.insert(messages)
|
|
144
|
-
.values({ id: mockMessageId, sessionId, topicId, role: 'user', userId });
|
|
145
|
-
|
|
146
|
-
// Execute
|
|
147
|
-
const data = await messageService.getMessages(sessionId, topicId);
|
|
148
|
-
|
|
149
|
-
// Assert
|
|
150
|
-
expect(data[0]).toMatchObject({ id: mockMessageId, role: 'user' });
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('getAllMessagesInSession', () => {
|
|
155
|
-
it('should retrieve all messages in a session', async () => {
|
|
156
|
-
// Setup
|
|
157
|
-
const sessionId = 'session-id';
|
|
158
|
-
await clientDB.insert(sessions).values([
|
|
159
|
-
{ id: 'bbb', userId },
|
|
160
|
-
{ id: sessionId, userId },
|
|
161
|
-
]);
|
|
162
|
-
await clientDB.insert(messages).values([
|
|
163
|
-
{ sessionId, topicId, role: 'user', userId },
|
|
164
|
-
{ sessionId, topicId, role: 'assistant', userId },
|
|
165
|
-
{ sessionId: 'bbb', topicId, role: 'assistant', userId },
|
|
166
|
-
]);
|
|
167
|
-
|
|
168
|
-
// Execute
|
|
169
|
-
const data = await messageService.getAllMessagesInSession(sessionId);
|
|
170
|
-
|
|
171
|
-
// Assert
|
|
172
|
-
expect(data.length).toBe(2);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('removeMessagesByAssistant', () => {
|
|
177
|
-
it('should batch remove messages by assistantId and topicId', async () => {
|
|
178
|
-
// Setup
|
|
179
|
-
const assistantId = 'assistant-id';
|
|
180
|
-
const sessionId = 'session-id';
|
|
181
|
-
await clientDB.insert(sessions).values([
|
|
182
|
-
{ id: 'bbb', userId },
|
|
183
|
-
{ id: sessionId, userId },
|
|
184
|
-
]);
|
|
185
|
-
await clientDB.insert(messages).values([
|
|
186
|
-
{ sessionId, topicId, role: 'user', userId },
|
|
187
|
-
{ sessionId, topicId, role: 'assistant', userId },
|
|
188
|
-
{ sessionId: 'bbb', topicId, role: 'assistant', userId },
|
|
189
|
-
]);
|
|
190
|
-
|
|
191
|
-
// Execute
|
|
192
|
-
await messageService.removeMessagesByAssistant(sessionId, topicId);
|
|
193
|
-
|
|
194
|
-
// Assert
|
|
195
|
-
const result = await clientDB.query.messages.findMany({
|
|
196
|
-
where: and(eq(messages.sessionId, sessionId), eq(messages.topicId, topicId)),
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
expect(result.length).toBe(0);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('clearAllMessage', () => {
|
|
204
|
-
it('should clear all messages from the table', async () => {
|
|
205
|
-
// Setup
|
|
206
|
-
await clientDB.insert(users).values({ id: 'another' });
|
|
207
|
-
await clientDB.insert(messages).values([
|
|
208
|
-
{ id: mockMessageId, role: 'user', userId },
|
|
209
|
-
{ role: 'user', userId: 'another' },
|
|
210
|
-
]);
|
|
211
|
-
|
|
212
|
-
// Execute
|
|
213
|
-
await messageService.removeAllMessages();
|
|
214
|
-
|
|
215
|
-
// Assert
|
|
216
|
-
const result = await clientDB.query.messages.findMany({
|
|
217
|
-
where: eq(messages.userId, userId),
|
|
218
|
-
});
|
|
219
|
-
expect(result.length).toBe(0);
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
describe('getAllMessages', () => {
|
|
224
|
-
it('should retrieve all messages', async () => {
|
|
225
|
-
await clientDB.insert(messages).values([
|
|
226
|
-
{ sessionId, topicId, content: '1', role: 'user', userId },
|
|
227
|
-
{ sessionId, topicId, content: '2', role: 'assistant', userId },
|
|
228
|
-
]);
|
|
229
|
-
|
|
230
|
-
// Execute
|
|
231
|
-
const data = await messageService.getAllMessages();
|
|
232
|
-
|
|
233
|
-
// Assert
|
|
234
|
-
expect(data).toMatchObject([
|
|
235
|
-
{ sessionId, topicId, content: '1', role: 'user', userId },
|
|
236
|
-
{ sessionId, topicId, content: '2', role: 'assistant', userId },
|
|
237
|
-
]);
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
describe('updateMessageError', () => {
|
|
242
|
-
it('should update the error field of a message', async () => {
|
|
243
|
-
// Setup
|
|
244
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
245
|
-
const newError = {
|
|
246
|
-
type: 'InvalidProviderAPIKey',
|
|
247
|
-
message: 'Error occurred',
|
|
248
|
-
} as ChatMessageError;
|
|
249
|
-
|
|
250
|
-
// Execute
|
|
251
|
-
await messageService.updateMessageError(mockMessageId, newError);
|
|
252
|
-
|
|
253
|
-
// Assert
|
|
254
|
-
const result = await clientDB.query.messages.findFirst({
|
|
255
|
-
where: eq(messages.id, mockMessageId),
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
expect(result!.error).toEqual(newError);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// describe('updateMessagePlugin', () => {
|
|
263
|
-
// it('should update the plugin payload of a message', async () => {
|
|
264
|
-
// // Setup
|
|
265
|
-
// const newPlugin = {
|
|
266
|
-
// type: 'default',
|
|
267
|
-
// apiName: 'abc',
|
|
268
|
-
// arguments: '',
|
|
269
|
-
// identifier: 'plugin1',
|
|
270
|
-
// } as ChatPluginPayload;
|
|
271
|
-
//
|
|
272
|
-
// (MessageModel.update as Mock).mockResolvedValue({ ...mockMessage, plugin: newPlugin });
|
|
273
|
-
//
|
|
274
|
-
// // Execute
|
|
275
|
-
// const result = await messageService.updateMessagePlugin(mockMessageId, newPlugin);
|
|
276
|
-
//
|
|
277
|
-
// // Assert
|
|
278
|
-
// expect(MessageModel.update).toHaveBeenCalledWith(mockMessageId, { plugin: newPlugin });
|
|
279
|
-
// expect(result).toEqual({ ...mockMessage, plugin: newPlugin });
|
|
280
|
-
// });
|
|
281
|
-
// });
|
|
282
|
-
|
|
283
|
-
describe('updateMessagePluginState', () => {
|
|
284
|
-
it('should update the plugin state of a message', async () => {
|
|
285
|
-
// Setup
|
|
286
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
287
|
-
await clientDB.insert(messagePlugins).values({ id: mockMessageId, userId });
|
|
288
|
-
const key = 'stateKey';
|
|
289
|
-
const value = 'stateValue';
|
|
290
|
-
const newPluginState = { [key]: value };
|
|
291
|
-
|
|
292
|
-
// Execute
|
|
293
|
-
await messageService.updateMessagePluginState(mockMessageId, { stateKey: value });
|
|
294
|
-
|
|
295
|
-
// Assert
|
|
296
|
-
const result = await clientDB.query.messagePlugins.findFirst({
|
|
297
|
-
where: eq(messagePlugins.id, mockMessageId),
|
|
298
|
-
});
|
|
299
|
-
expect(result!.state).toEqual(newPluginState);
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
describe('updateMessagePluginArguments', () => {
|
|
304
|
-
it('should update the plugin arguments object of a message', async () => {
|
|
305
|
-
// Setup
|
|
306
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
307
|
-
await clientDB.insert(messagePlugins).values({ id: mockMessageId, userId });
|
|
308
|
-
const value = 'stateValue';
|
|
309
|
-
|
|
310
|
-
// Execute
|
|
311
|
-
await messageService.updateMessagePluginArguments(mockMessageId, { key: value });
|
|
312
|
-
|
|
313
|
-
// Assert
|
|
314
|
-
const result = await clientDB.query.messagePlugins.findFirst({
|
|
315
|
-
where: eq(messageTTS.id, mockMessageId),
|
|
316
|
-
});
|
|
317
|
-
expect(result).toMatchObject({ arguments: '{"key":"stateValue"}' });
|
|
318
|
-
});
|
|
319
|
-
it('should update the plugin arguments string of a message', async () => {
|
|
320
|
-
// Setup
|
|
321
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
322
|
-
await clientDB.insert(messagePlugins).values({ id: mockMessageId, userId });
|
|
323
|
-
const value = 'stateValue';
|
|
324
|
-
// Execute
|
|
325
|
-
await messageService.updateMessagePluginArguments(
|
|
326
|
-
mockMessageId,
|
|
327
|
-
JSON.stringify({ abc: value }),
|
|
328
|
-
);
|
|
329
|
-
|
|
330
|
-
// Assert
|
|
331
|
-
const result = await clientDB.query.messagePlugins.findFirst({
|
|
332
|
-
where: eq(messageTTS.id, mockMessageId),
|
|
333
|
-
});
|
|
334
|
-
expect(result).toMatchObject({ arguments: '{"abc":"stateValue"}' });
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
describe('countMessages', () => {
|
|
339
|
-
it('should count the total number of messages', async () => {
|
|
340
|
-
// Setup
|
|
341
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
342
|
-
|
|
343
|
-
// Execute
|
|
344
|
-
const count = await messageService.countMessages();
|
|
345
|
-
|
|
346
|
-
// Assert
|
|
347
|
-
expect(count).toBe(1);
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
describe('updateMessageTTS', () => {
|
|
352
|
-
it('should update the TTS field of a message', async () => {
|
|
353
|
-
// Setup
|
|
354
|
-
await clientDB
|
|
355
|
-
.insert(files)
|
|
356
|
-
.values({ id: 'file-abc', fileType: 'text', name: 'abc', url: 'abc', size: 100, userId });
|
|
357
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
358
|
-
const newTTS: ChatTTS = { contentMd5: 'abc', file: 'file-abc' };
|
|
359
|
-
|
|
360
|
-
// Execute
|
|
361
|
-
await messageService.updateMessageTTS(mockMessageId, newTTS);
|
|
362
|
-
|
|
363
|
-
// Assert
|
|
364
|
-
const result = await clientDB.query.messageTTS.findFirst({
|
|
365
|
-
where: eq(messageTTS.id, mockMessageId),
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
expect(result).toMatchObject({ contentMd5: 'abc', fileId: 'file-abc', id: mockMessageId });
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
describe('updateMessageTranslate', () => {
|
|
373
|
-
it('should update the translate field of a message', async () => {
|
|
374
|
-
// Setup
|
|
375
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
376
|
-
const newTranslate: ChatTranslate = { content: 'Translated text', to: 'es' };
|
|
377
|
-
|
|
378
|
-
// Execute
|
|
379
|
-
await messageService.updateMessageTranslate(mockMessageId, newTranslate);
|
|
380
|
-
|
|
381
|
-
// Assert
|
|
382
|
-
const result = await clientDB.query.messageTranslates.findFirst({
|
|
383
|
-
where: eq(messageTranslates.id, mockMessageId),
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
expect(result).toMatchObject(newTranslate);
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
describe('hasMessages', () => {
|
|
391
|
-
it('should return true if there are messages', async () => {
|
|
392
|
-
// Setup
|
|
393
|
-
await clientDB.insert(messages).values({ id: mockMessageId, role: 'user', userId });
|
|
394
|
-
|
|
395
|
-
// Execute
|
|
396
|
-
const result = await messageService.hasMessages();
|
|
397
|
-
|
|
398
|
-
// Assert
|
|
399
|
-
expect(result).toBe(true);
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
it('should return false if there are no messages', async () => {
|
|
403
|
-
// Execute
|
|
404
|
-
const result = await messageService.hasMessages();
|
|
405
|
-
|
|
406
|
-
// Assert
|
|
407
|
-
expect(result).toBe(false);
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
});
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import { UIChatMessage } from '@lobechat/types';
|
|
2
|
-
|
|
3
|
-
import { INBOX_SESSION_ID } from '@/const/session';
|
|
4
|
-
import { clientDB } from '@/database/client/db';
|
|
5
|
-
import { MessageModel } from '@/database/models/message';
|
|
6
|
-
import { BaseClientService } from '@/services/baseClientService';
|
|
7
|
-
import { clientS3Storage } from '@/services/file/ClientS3';
|
|
8
|
-
|
|
9
|
-
import { IMessageService } from './type';
|
|
10
|
-
|
|
11
|
-
export class ClientService extends BaseClientService implements IMessageService {
|
|
12
|
-
private get messageModel(): MessageModel {
|
|
13
|
-
return new MessageModel(clientDB as any, this.userId);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createMessage: IMessageService['createMessage'] = async ({ sessionId, ...params }) => {
|
|
17
|
-
const { id } = await this.messageModel.create({
|
|
18
|
-
...params,
|
|
19
|
-
sessionId: sessionId ? (this.toDbSessionId(sessionId) as string) : '',
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
return id;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
createNewMessage: IMessageService['createNewMessage'] = async ({ sessionId, ...params }) => {
|
|
26
|
-
return await this.messageModel.createNewMessage(
|
|
27
|
-
{
|
|
28
|
-
...params,
|
|
29
|
-
sessionId: sessionId ? (this.toDbSessionId(sessionId) as string) : '',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
postProcessUrl: this.postProcessUrl,
|
|
33
|
-
},
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
batchCreateMessages: IMessageService['batchCreateMessages'] = async (messages) => {
|
|
38
|
-
return this.messageModel.batchCreate(messages);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
getMessages: IMessageService['getMessages'] = async (sessionId, topicId) => {
|
|
42
|
-
const data = await this.messageModel.query(
|
|
43
|
-
{
|
|
44
|
-
sessionId: this.toDbSessionId(sessionId),
|
|
45
|
-
topicId,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
groupAssistantMessages: false,
|
|
49
|
-
postProcessUrl: this.postProcessUrl,
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
return data as unknown as UIChatMessage[];
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
getGroupMessages: IMessageService['getGroupMessages'] = async (groupId, topicId) => {
|
|
57
|
-
// Use full query to hydrate fileList/imageList like single chat
|
|
58
|
-
const data = await this.messageModel.query(
|
|
59
|
-
{
|
|
60
|
-
sessionId: groupId,
|
|
61
|
-
topicId,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
groupAssistantMessages: false,
|
|
65
|
-
postProcessUrl: this.postProcessUrl,
|
|
66
|
-
},
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
return data as unknown as UIChatMessage[];
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
getAllMessages: IMessageService['getAllMessages'] = async () => {
|
|
73
|
-
const data = await this.messageModel.queryAll();
|
|
74
|
-
|
|
75
|
-
return data as unknown as UIChatMessage[];
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
countMessages: IMessageService['countMessages'] = async (params) => {
|
|
79
|
-
return this.messageModel.count(params);
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
countWords: IMessageService['countWords'] = async (params) => {
|
|
83
|
-
return this.messageModel.countWords(params);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
rankModels: IMessageService['rankModels'] = async () => {
|
|
87
|
-
return this.messageModel.rankModels();
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
getHeatmaps: IMessageService['getHeatmaps'] = async () => {
|
|
91
|
-
return this.messageModel.getHeatmaps();
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
getAllMessagesInSession: IMessageService['getAllMessagesInSession'] = async (sessionId) => {
|
|
95
|
-
const data = this.messageModel.queryBySessionId(this.toDbSessionId(sessionId));
|
|
96
|
-
|
|
97
|
-
return data as unknown as UIChatMessage[];
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
updateMessageError: IMessageService['updateMessageError'] = async (id, error) => {
|
|
101
|
-
return this.messageModel.update(id, { error });
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
updateMessage: IMessageService['updateMessage'] = async (id, message, options) => {
|
|
105
|
-
return this.messageModel.update(id, message, {
|
|
106
|
-
postProcessUrl: this.postProcessUrl,
|
|
107
|
-
sessionId: options?.sessionId,
|
|
108
|
-
topicId: options?.topicId,
|
|
109
|
-
});
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
updateMessageTTS: IMessageService['updateMessageTTS'] = async (id, tts) => {
|
|
113
|
-
return this.messageModel.updateTTS(id, tts as any);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
updateMessageTranslate: IMessageService['updateMessageTranslate'] = async (id, translate) => {
|
|
117
|
-
return this.messageModel.updateTranslate(id, translate as any);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
updateMessagePluginState: IMessageService['updateMessagePluginState'] = async (id, value) => {
|
|
121
|
-
return this.messageModel.updatePluginState(id, value);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
updateMessagePluginError: IMessageService['updateMessagePluginError'] = async (id, value) => {
|
|
125
|
-
return this.messageModel.updateMessagePlugin(id, { error: value });
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
updateMessageRAG: IMessageService['updateMessageRAG'] = async (id, value) => {
|
|
129
|
-
console.log(id, value);
|
|
130
|
-
throw new Error('not implemented');
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
updateMessagePluginArguments: IMessageService['updateMessagePluginArguments'] = async (
|
|
134
|
-
id,
|
|
135
|
-
value,
|
|
136
|
-
) => {
|
|
137
|
-
const args = typeof value === 'string' ? value : JSON.stringify(value);
|
|
138
|
-
|
|
139
|
-
return this.messageModel.updateMessagePlugin(id, { arguments: args });
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
removeMessage: IMessageService['removeMessage'] = async (id) => {
|
|
143
|
-
return this.messageModel.deleteMessage(id);
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
removeMessages: IMessageService['removeMessages'] = async (ids) => {
|
|
147
|
-
return this.messageModel.deleteMessages(ids);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
removeMessagesByAssistant: IMessageService['removeMessagesByAssistant'] = async (
|
|
151
|
-
sessionId,
|
|
152
|
-
topicId,
|
|
153
|
-
) => {
|
|
154
|
-
return this.messageModel.deleteMessagesBySession(this.toDbSessionId(sessionId), topicId);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
removeMessagesByGroup: IMessageService['removeMessagesByGroup'] = async (groupId, topicId) => {
|
|
158
|
-
return this.messageModel.deleteMessagesBySession(groupId, topicId);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
removeAllMessages: IMessageService['removeAllMessages'] = async () => {
|
|
162
|
-
return this.messageModel.deleteAllMessages();
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
hasMessages: IMessageService['hasMessages'] = async () => {
|
|
166
|
-
const number = await this.countMessages();
|
|
167
|
-
return number > 0;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
messageCountToCheckTrace: IMessageService['messageCountToCheckTrace'] = async () => {
|
|
171
|
-
const number = await this.countMessages();
|
|
172
|
-
return number >= 4;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
private toDbSessionId = (sessionId: string | undefined) => {
|
|
176
|
-
return sessionId === INBOX_SESSION_ID ? undefined : sessionId;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
private postProcessUrl = async (url: string | null, file: any) => {
|
|
180
|
-
const hash = (url as string).replace('client-s3://', '');
|
|
181
|
-
const base64 = await this.getBase64ByFileHash(hash);
|
|
182
|
-
|
|
183
|
-
return `data:${file.fileType};base64,${base64}`;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
private getBase64ByFileHash = async (hash: string) => {
|
|
187
|
-
const fileItem = await clientS3Storage.getObject(hash);
|
|
188
|
-
if (!fileItem) throw new Error('file not found');
|
|
189
|
-
|
|
190
|
-
return Buffer.from(await fileItem.arrayBuffer()).toString('base64');
|
|
191
|
-
};
|
|
192
|
-
}
|