@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.
Files changed (212) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/package.json +1 -1
  4. package/packages/const/src/version.ts +3 -3
  5. package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
  6. package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
  7. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
  8. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
  9. package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +3 -28
  10. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +0 -2
  11. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +1 -5
  12. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
  13. package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -1
  14. package/src/app/[variants]/(main)/image/page.tsx +0 -2
  15. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
  16. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
  17. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
  18. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
  19. package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
  20. package/src/app/[variants]/loading/index.tsx +1 -10
  21. package/src/components/Link.tsx +12 -0
  22. package/src/envs/app.ts +5 -8
  23. package/src/features/DataImporter/index.tsx +15 -60
  24. package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
  25. package/src/hooks/useInterceptingRoutes.test.ts +21 -3
  26. package/src/libs/trpc/client/index.ts +0 -1
  27. package/src/libs/trpc/client/lambda.ts +8 -5
  28. package/src/libs/trpc/lambda/context.ts +4 -1
  29. package/src/server/routers/desktop/mcp.ts +1 -3
  30. package/src/server/routers/lambda/config/index.test.ts +2 -2
  31. package/src/server/routers/tools/mcp.ts +2 -3
  32. package/src/server/routers/tools/search.test.ts +1 -7
  33. package/src/server/routers/tools/search.ts +1 -4
  34. package/src/services/__tests__/tool.test.ts +0 -3
  35. package/src/services/aiModel/index.test.ts +0 -3
  36. package/src/services/aiModel/index.ts +1 -7
  37. package/src/services/aiProvider/index.test.ts +0 -3
  38. package/src/services/aiProvider/index.ts +1 -7
  39. package/src/services/chatGroup/index.ts +1 -10
  40. package/src/services/config.ts +1 -65
  41. package/src/services/export/index.ts +1 -4
  42. package/src/services/file/index.ts +1 -11
  43. package/src/services/import/index.ts +1 -7
  44. package/src/services/message/index.ts +1 -11
  45. package/src/services/plugin/index.ts +1 -11
  46. package/src/services/session/index.ts +1 -11
  47. package/src/services/tableViewer/client.ts +12 -15
  48. package/src/services/thread/index.ts +1 -7
  49. package/src/services/topic/index.ts +1 -11
  50. package/src/services/user/index.ts +1 -13
  51. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -241
  52. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +26 -1
  53. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +3 -1
  54. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +1 -138
  55. package/src/store/user/slices/common/action.test.ts +1 -4
  56. package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
  57. package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
  58. package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
  59. package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
  60. package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
  61. package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +0 -29
  62. package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
  63. package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
  64. package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
  65. package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
  66. package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
  67. package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
  68. package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
  69. package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
  70. package/src/app/[variants]/loading/Client/Content.tsx +0 -48
  71. package/src/app/[variants]/loading/Client/Error.tsx +0 -27
  72. package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
  73. package/src/app/[variants]/loading/Client/index.tsx +0 -22
  74. package/src/components/InnerLink.tsx +0 -20
  75. package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
  76. package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
  77. package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
  78. package/src/database/_deprecated/core/db.ts +0 -246
  79. package/src/database/_deprecated/core/index.ts +0 -2
  80. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
  81. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
  82. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
  83. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
  84. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
  85. package/src/database/_deprecated/core/model.ts +0 -218
  86. package/src/database/_deprecated/core/schemas.ts +0 -88
  87. package/src/database/_deprecated/core/types/db.ts +0 -15
  88. package/src/database/_deprecated/models/__DEBUG.ts +0 -124
  89. package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
  90. package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
  91. package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
  92. package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
  93. package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
  94. package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
  95. package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
  96. package/src/database/_deprecated/models/file.ts +0 -51
  97. package/src/database/_deprecated/models/message.ts +0 -277
  98. package/src/database/_deprecated/models/plugin.ts +0 -62
  99. package/src/database/_deprecated/models/session.ts +0 -271
  100. package/src/database/_deprecated/models/sessionGroup.ts +0 -93
  101. package/src/database/_deprecated/models/topic.ts +0 -250
  102. package/src/database/_deprecated/models/user.ts +0 -69
  103. package/src/database/_deprecated/schemas/files.ts +0 -39
  104. package/src/database/_deprecated/schemas/message.ts +0 -50
  105. package/src/database/_deprecated/schemas/plugin.ts +0 -12
  106. package/src/database/_deprecated/schemas/session.ts +0 -54
  107. package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
  108. package/src/database/_deprecated/schemas/topic.ts +0 -12
  109. package/src/database/_deprecated/schemas/user.ts +0 -40
  110. package/src/features/DataImporter/_deprecated.ts +0 -43
  111. package/src/features/InitClientDB/EnableModal.tsx +0 -118
  112. package/src/features/InitClientDB/ErrorResult.tsx +0 -143
  113. package/src/features/InitClientDB/InitIndicator.tsx +0 -124
  114. package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
  115. package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
  116. package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
  117. package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
  118. package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
  119. package/src/features/InitClientDB/index.tsx +0 -37
  120. package/src/libs/trpc/client/edge.ts +0 -26
  121. package/src/libs/trpc/edge/context.ts +0 -71
  122. package/src/libs/trpc/edge/index.ts +0 -45
  123. package/src/libs/trpc/edge/init.ts +0 -26
  124. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
  125. package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
  126. package/src/migrations/FromV0ToV1.ts +0 -10
  127. package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
  128. package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
  129. package/src/migrations/FromV1ToV2/index.ts +0 -82
  130. package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
  131. package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
  132. package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
  133. package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
  134. package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
  135. package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
  136. package/src/migrations/FromV2ToV3/index.ts +0 -30
  137. package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
  138. package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
  139. package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
  140. package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
  141. package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
  142. package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
  143. package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
  144. package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
  145. package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
  146. package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
  147. package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
  148. package/src/migrations/FromV3ToV4/index.ts +0 -102
  149. package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
  150. package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
  151. package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
  152. package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
  153. package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
  154. package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
  155. package/src/migrations/FromV4ToV5/index.ts +0 -58
  156. package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
  157. package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
  158. package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
  159. package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
  160. package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
  161. package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
  162. package/src/migrations/FromV5ToV6/index.ts +0 -61
  163. package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
  164. package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
  165. package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
  166. package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
  167. package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
  168. package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
  169. package/src/migrations/FromV6ToV7/index.ts +0 -101
  170. package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
  171. package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
  172. package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
  173. package/src/migrations/VersionController.test.ts +0 -88
  174. package/src/migrations/VersionController.ts +0 -67
  175. package/src/migrations/index.ts +0 -61
  176. package/src/server/routers/edge/appStatus.ts +0 -3
  177. package/src/server/routers/edge/index.ts +0 -14
  178. package/src/server/routers/edge/upload.ts +0 -16
  179. package/src/services/aiModel/client.ts +0 -70
  180. package/src/services/aiProvider/client.ts +0 -58
  181. package/src/services/baseClientService/index.ts +0 -9
  182. package/src/services/chatGroup/client.ts +0 -63
  183. package/src/services/export/_deprecated.ts +0 -155
  184. package/src/services/export/client.ts +0 -15
  185. package/src/services/file/_deprecated.test.ts +0 -119
  186. package/src/services/file/_deprecated.ts +0 -80
  187. package/src/services/file/client.test.ts +0 -199
  188. package/src/services/file/client.ts +0 -85
  189. package/src/services/import/_deprecated.ts +0 -115
  190. package/src/services/import/client.test.ts +0 -1015
  191. package/src/services/import/client.ts +0 -64
  192. package/src/services/message/_deprecated.test.ts +0 -398
  193. package/src/services/message/_deprecated.ts +0 -168
  194. package/src/services/message/client.test.ts +0 -410
  195. package/src/services/message/client.ts +0 -192
  196. package/src/services/plugin/_deprecated.test.ts +0 -162
  197. package/src/services/plugin/_deprecated.ts +0 -42
  198. package/src/services/plugin/client.test.ts +0 -177
  199. package/src/services/plugin/client.ts +0 -46
  200. package/src/services/session/_deprecated.test.ts +0 -440
  201. package/src/services/session/_deprecated.ts +0 -190
  202. package/src/services/session/client.test.ts +0 -413
  203. package/src/services/session/client.ts +0 -193
  204. package/src/services/thread/client.ts +0 -51
  205. package/src/services/topic/_deprecated.test.ts +0 -245
  206. package/src/services/topic/_deprecated.ts +0 -75
  207. package/src/services/topic/client.ts +0 -89
  208. package/src/services/topic/pglite.test.ts +0 -212
  209. package/src/services/user/_deprecated.test.ts +0 -101
  210. package/src/services/user/_deprecated.ts +0 -70
  211. package/src/services/user/client.test.ts +0 -111
  212. package/src/services/user/client.ts +0 -104
@@ -1,124 +0,0 @@
1
- // This file is for debugging purposes only.
2
- // DON'T USE IT IN PRODUCTION.
3
- import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
4
- import { DBModel } from '@/database/_deprecated/core/types/db';
5
- import { DB_Message } from '@/database/_deprecated/schemas/message';
6
- import { DB_Topic } from '@/database/_deprecated/schemas/topic';
7
-
8
- import { BaseModel } from '../core';
9
- import { DB_Session, DB_SessionSchema } from '../schemas/session';
10
-
11
- class _DEBUG_MODEL extends BaseModel<'sessions'> {
12
- constructor() {
13
- super('sessions', DB_SessionSchema);
14
- }
15
- private getRandomInt(min: number, max: number) {
16
- return Math.floor(Math.random() * (max - min + 1)) + min;
17
- }
18
-
19
- private randomString(length: number) {
20
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
21
- let result = '';
22
- for (let i = 0; i < length; i++) {
23
- result += characters.charAt(Math.floor(Math.random() * characters.length));
24
- }
25
- return result;
26
- }
27
-
28
- private randomDate(start: Date, end: Date) {
29
- return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).getTime();
30
- }
31
-
32
- private randomPick<T>(array: T[]): T {
33
- const randomIndex = this.getRandomInt(0, array.length - 1);
34
- return array[randomIndex];
35
- }
36
-
37
- createRandomData = async ({
38
- sessionCount = 10,
39
- topicCount = 2000,
40
- messageCount = 10_000,
41
- startIndex = 1,
42
- }) => {
43
- const numberOfSessions = sessionCount;
44
- const numberOfTopics = topicCount;
45
- const numberOfMessages = messageCount;
46
-
47
- // Prepare data for batch inserts
48
- const sessionsData: DBModel<DB_Session>[] = [];
49
- const topicsData: DBModel<DB_Topic>[] = [];
50
- const messagesData: DBModel<DB_Message>[] = [];
51
-
52
- // Prepare sessions
53
- for (let i = startIndex; i < numberOfSessions + startIndex; i++) {
54
- sessionsData.push({
55
- config: DEFAULT_AGENT_CONFIG,
56
- createdAt: this.randomDate(new Date(2020, 0, 1), new Date()),
57
- group: 'default',
58
- id: `sess_${i}`,
59
- meta: {
60
- description: `Session Description ${i}`,
61
- title: `Session Title ${i}`,
62
- },
63
- type: 'agent',
64
- updatedAt: this.randomDate(new Date(2020, 0, 1), new Date()),
65
- });
66
- }
67
-
68
- // Prepare topics
69
- for (let i = startIndex; i < numberOfTopics + startIndex; i++) {
70
- topicsData.push({
71
- createdAt: this.randomDate(new Date(2020, 0, 1), new Date()),
72
- favorite: this.getRandomInt(0, 1),
73
- id: `topic_${i}`,
74
- sessionId: `sess_${this.getRandomInt(startIndex, numberOfSessions)}`,
75
- title: `Topic Title ${i}`,
76
- updatedAt: this.randomDate(new Date(2020, 0, 1), new Date()),
77
- });
78
- }
79
-
80
- // Prepare messages
81
- for (let i = startIndex; i < numberOfMessages + startIndex; i++) {
82
- messagesData.push({
83
- content: this.randomString(300),
84
- createdAt: this.randomDate(new Date(2020, 0, 1), new Date()),
85
- favorite: this.getRandomInt(0, 1),
86
- fromModel: 'model',
87
- id: `msg_${i}`,
88
- parentId: `msg_${this.getRandomInt(startIndex, numberOfMessages)}`,
89
- quotaId: `msg_${this.getRandomInt(startIndex, numberOfMessages)}`,
90
- role: this.randomPick(['user', 'assistant']),
91
- sessionId: `sess_${this.getRandomInt(startIndex, numberOfSessions)}`,
92
- topicId: `topic_${this.getRandomInt(startIndex, numberOfTopics)}`,
93
- updatedAt: this.randomDate(new Date(2020, 0, 1), new Date()),
94
- });
95
- }
96
-
97
- // Start a transaction for batch inserts
98
- await this.db.transaction(
99
- 'rw',
100
- this.db.sessions,
101
- this.db.topics,
102
- this.db.messages,
103
- async () => {
104
- // Batch insert sessions, topics, and messages
105
- console.log('开始插入 sessions');
106
- console.time('插入sessions');
107
- await this.db.sessions.bulkAdd(sessionsData);
108
- console.timeEnd('插入sessions');
109
-
110
- console.log('开始插入 topics');
111
- console.time('插入topics');
112
- await this.db.topics.bulkAdd(topicsData);
113
- console.timeEnd('插入topics');
114
-
115
- console.log('开始插入 messages');
116
- console.time('插入messages');
117
- await this.db.messages.bulkAdd(messagesData);
118
- console.timeEnd('插入messages');
119
- },
120
- );
121
- };
122
- }
123
-
124
- export const DEBUG_MODEL = new _DEBUG_MODEL();
@@ -1,83 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
-
3
- import { BrowserDB } from '../../core/db';
4
- import { DB_File } from '../../schemas/files';
5
- import { FileModel } from '../file';
6
-
7
- // Assuming LocalDB is already mocked or using an in-memory database
8
- // and LocalFileSchema has been imported correctly.
9
-
10
- describe('_FileModel', () => {
11
- let fileData: DB_File;
12
-
13
- beforeEach(() => {
14
- // Set up file data with the correct structure according to LocalFileSchema
15
- fileData = {
16
- data: new ArrayBuffer(10),
17
- fileType: 'image/png',
18
- name: 'test.png',
19
- saveMode: 'local',
20
- size: 10,
21
- // url is optional, only needed if saveMode is 'url'
22
- };
23
- });
24
-
25
- afterEach(async () => {
26
- // Clean up the database after each test
27
- const db = new BrowserDB();
28
- await db.files.clear();
29
- db.close();
30
- });
31
-
32
- it('should create a file record', async () => {
33
- // First, create a file to test the create method
34
- const fileData: DB_File = {
35
- data: new ArrayBuffer(10),
36
- fileType: 'image/png',
37
- name: 'test.png',
38
- saveMode: 'local',
39
- size: 10,
40
- };
41
-
42
- const result = await FileModel.create(fileData);
43
-
44
- expect(result).toHaveProperty('id');
45
- expect(result.id).toMatch(/^file-/);
46
-
47
- // Verify that the file has been added to the database
48
- const fileInDb = await FileModel.findById(result.id);
49
-
50
- expect(fileInDb).toEqual(expect.objectContaining(fileData));
51
- });
52
-
53
- it('should find a file by id', async () => {
54
- // First, create a file to test the findById method
55
- const createdFile = await FileModel.create(fileData);
56
- const foundFile = await FileModel.findById(createdFile.id);
57
-
58
- expect(foundFile).toEqual(expect.objectContaining(fileData));
59
- });
60
-
61
- it('should delete a file by id', async () => {
62
- // First, create a file to test the delete method
63
- const createdFile = await FileModel.create(fileData);
64
- await FileModel.delete(createdFile.id);
65
-
66
- // Verify that the file has been removed from the database
67
- const fileInDb = await FileModel.findById(createdFile.id);
68
- expect(fileInDb).toBeUndefined();
69
- });
70
-
71
- it('should clear all files', async () => {
72
- // First, create a file to test the delete method
73
- const createdFile = await FileModel.create(fileData);
74
- const createdFile2 = await FileModel.create(fileData);
75
- await FileModel.clear();
76
-
77
- // Verify that the file has been removed from the database
78
- const fileInDb = await FileModel.findById(createdFile.id);
79
- expect(fileInDb).toBeUndefined();
80
- const fileInDb2 = await FileModel.findById(createdFile2.id);
81
- expect(fileInDb2).toBeUndefined();
82
- });
83
- });
@@ -1,426 +0,0 @@
1
- import { UIChatMessage } from '@lobechat/types';
2
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
3
-
4
- import { CreateMessageParams, MessageModel } from '../message';
5
-
6
- describe('MessageModel', () => {
7
- let messageData: CreateMessageParams;
8
-
9
- beforeEach(() => {
10
- // 设置正确结构的消息数据
11
- messageData = {
12
- content: 'Test message content',
13
- role: 'user',
14
- sessionId: 'session1',
15
- topicId: 'topic1',
16
- };
17
- });
18
-
19
- afterEach(async () => {
20
- // 每次测试后清理数据库
21
- await MessageModel.clearTable();
22
- });
23
-
24
- describe('create', () => {
25
- it('should create a message record', async () => {
26
- const result = await MessageModel.create(messageData);
27
-
28
- expect(result).toHaveProperty('id');
29
- // 验证消息是否已添加到数据库
30
- const messageInDb = await MessageModel.findById(result.id);
31
-
32
- expect(messageInDb).toEqual(
33
- expect.objectContaining({
34
- content: messageData.content,
35
- role: messageData.role,
36
- sessionId: messageData.sessionId,
37
- topicId: messageData.topicId,
38
- }),
39
- );
40
- });
41
-
42
- it('should create with tts', async () => {
43
- const result = await MessageModel.create({
44
- content: 'abc',
45
- role: 'assistant',
46
- extra: { translate: { content: 'avc', from: 'a', to: 'f' } },
47
- sessionId: 'a',
48
- });
49
-
50
- // 验证消息是否已添加到数据库
51
- const messageInDb = await MessageModel.findById(result.id);
52
-
53
- expect(messageInDb).toEqual(
54
- expect.objectContaining({
55
- content: 'abc',
56
- role: 'assistant',
57
- translate: { content: 'avc', from: 'a', to: 'f' },
58
- sessionId: 'a',
59
- }),
60
- );
61
- });
62
- });
63
-
64
- describe('batchCreate', () => {
65
- it('should batch create message records', async () => {
66
- const messagesToCreate = [messageData, messageData] as UIChatMessage[];
67
- const results = await MessageModel.batchCreate(messagesToCreate);
68
-
69
- expect(results.success).toBeTruthy();
70
- expect(results.errors).toBeUndefined();
71
-
72
- // 验证消息是否已添加到数据库
73
- for (const message of results.ids!) {
74
- const messageInDb = await MessageModel.findById(message);
75
- expect(messageInDb).toEqual(
76
- expect.objectContaining({
77
- content: messageData.content,
78
- role: messageData.role,
79
- sessionId: messageData.sessionId,
80
- topicId: messageData.topicId,
81
- }),
82
- );
83
- }
84
- });
85
- });
86
-
87
- describe('query', () => {
88
- it('should query messages with pagination', async () => {
89
- // 创建多条消息以测试查询方法
90
- await MessageModel.batchCreate([messageData, messageData] as UIChatMessage[]);
91
-
92
- const queriedMessages = await MessageModel.query({
93
- pageSize: 1,
94
- current: 0,
95
- sessionId: messageData.sessionId,
96
- topicId: messageData.topicId,
97
- });
98
-
99
- expect(queriedMessages).toHaveLength(1);
100
- });
101
-
102
- it('should query correctly without topic id', async () => {
103
- // 创建多条消息以测试查询方法
104
- await MessageModel.batchCreate([messageData, messageData] as UIChatMessage[]);
105
-
106
- const queriedMessages = await MessageModel.query({ sessionId: messageData.sessionId });
107
-
108
- expect(queriedMessages).toHaveLength(0);
109
- });
110
-
111
- it('should query correctly with exactly topic id', async () => {
112
- // 创建多条消息以测试查询方法
113
- await MessageModel.batchCreate([
114
- messageData,
115
- { ...messageData, topicId: undefined },
116
- ] as UIChatMessage[]);
117
-
118
- const queriedMessages = await MessageModel.query({ sessionId: messageData.sessionId });
119
-
120
- expect(queriedMessages).toHaveLength(1);
121
- });
122
-
123
- it('should should have correct order', async () => {
124
- const data: UIChatMessage[] = [
125
- {
126
- role: 'user',
127
- content: '1',
128
- createdAt: 1697120044345,
129
- id: 'NQ7RscYx',
130
- updatedAt: 1697120181827,
131
- extra: {},
132
- meta: {},
133
- sessionId: '1',
134
- },
135
- {
136
- role: 'assistant',
137
- content: '2',
138
- parentId: 'NQ7RscYx',
139
- createdAt: 1697120130973,
140
- id: '9tDAumEx',
141
- updatedAt: 1697120181827,
142
- meta: {},
143
- extra: {
144
- fromModel: 'gpt-3.5-turbo-16k',
145
- },
146
- sessionId: '1',
147
- },
148
- {
149
- role: 'assistant',
150
- content: '3',
151
- parentId: 'tOMH7c5R',
152
- meta: {},
153
- createdAt: 1697120163272,
154
- id: '5Ie5hClg',
155
- updatedAt: 1697120181827,
156
- extra: {
157
- fromModel: 'gpt-3.5-turbo-16k',
158
- },
159
- sessionId: '1',
160
- },
161
- {
162
- role: 'user',
163
- content: '4',
164
- meta: {},
165
- createdAt: 1697120163272,
166
- id: 'tOMH7c5R',
167
- updatedAt: 1697120181827,
168
- extra: {},
169
- sessionId: '1',
170
- },
171
- ];
172
-
173
- await MessageModel.batchCreate(data);
174
-
175
- const queriedMessages = await MessageModel.query({ sessionId: '1' });
176
-
177
- expect(queriedMessages).toEqual([
178
- {
179
- role: 'user',
180
- content: '1',
181
- createdAt: 1697120044345,
182
- id: 'NQ7RscYx',
183
- updatedAt: 1697120181827,
184
- sessionId: '1',
185
- extra: {},
186
- meta: {},
187
- },
188
- {
189
- role: 'assistant',
190
- content: '2',
191
- parentId: 'NQ7RscYx',
192
- createdAt: 1697120130973,
193
- id: '9tDAumEx',
194
- sessionId: '1',
195
- updatedAt: 1697120181827,
196
- meta: {},
197
- extra: {
198
- fromModel: 'gpt-3.5-turbo-16k',
199
- },
200
- },
201
- {
202
- role: 'user',
203
- content: '4',
204
- sessionId: '1',
205
- createdAt: 1697120163272,
206
- id: 'tOMH7c5R',
207
- updatedAt: 1697120181827,
208
- meta: {},
209
- extra: {},
210
- },
211
- {
212
- role: 'assistant',
213
- content: '3',
214
- parentId: 'tOMH7c5R',
215
- meta: {},
216
- createdAt: 1697120163272,
217
- sessionId: '1',
218
- id: '5Ie5hClg',
219
- updatedAt: 1697120181827,
220
- extra: {
221
- fromModel: 'gpt-3.5-turbo-16k',
222
- },
223
- },
224
- ]);
225
- });
226
- });
227
-
228
- describe('findById', () => {
229
- it('should find a message by id', async () => {
230
- const createdMessage = await MessageModel.create(messageData);
231
- const messageInDb = await MessageModel.findById(createdMessage.id);
232
-
233
- expect(messageInDb).toEqual(
234
- expect.objectContaining({
235
- id: createdMessage.id,
236
- content: messageData.content,
237
- }),
238
- );
239
- });
240
- });
241
-
242
- describe('delete', () => {
243
- it('should delete a message', async () => {
244
- const createdMessage = await MessageModel.create(messageData);
245
- await MessageModel.delete(createdMessage.id);
246
-
247
- const messageInDb = await MessageModel.findById(createdMessage.id);
248
- expect(messageInDb).toBeUndefined();
249
- });
250
- });
251
-
252
- describe('bulkDelete', () => {
253
- it('should delete many messages', async () => {
254
- const createdMessage = await MessageModel.create(messageData);
255
- const createdMessage2 = await MessageModel.create(messageData);
256
- await MessageModel.bulkDelete([createdMessage.id, createdMessage2.id]);
257
-
258
- const messageInDb1 = await MessageModel.findById(createdMessage.id);
259
- const messageInDb2 = await MessageModel.findById(createdMessage2.id);
260
- expect(messageInDb1).toBeUndefined();
261
- expect(messageInDb2).toBeUndefined();
262
- });
263
- });
264
-
265
- describe('update', () => {
266
- it('should update a message', async () => {
267
- const createdMessage = await MessageModel.create(messageData);
268
- const updateData = { content: 'Updated content' };
269
-
270
- await MessageModel.update(createdMessage.id, updateData);
271
- const updatedMessage = await MessageModel.findById(createdMessage.id);
272
-
273
- expect(updatedMessage).toHaveProperty('content', 'Updated content');
274
- });
275
-
276
- it('should update a role and plugins', async () => {
277
- const createdMessage = await MessageModel.create(messageData);
278
- const updateData = {
279
- role: 'tool' as const,
280
- plugin: { apiName: 'a', identifier: 'b', arguments: 'abc' },
281
- };
282
-
283
- await MessageModel.update(createdMessage.id, updateData);
284
- const updatedMessage = await MessageModel.findById(createdMessage.id);
285
-
286
- expect(updatedMessage).toHaveProperty('role', 'tool');
287
- });
288
- });
289
-
290
- describe('batchUpdate', () => {
291
- it('should batch update messages', async () => {
292
- const createdMessage1 = await MessageModel.create(messageData);
293
- const createdMessage2 = await MessageModel.create(messageData);
294
- const updateData = { content: 'Batch updated content' };
295
-
296
- const numUpdated = await MessageModel.batchUpdate(
297
- [createdMessage1.id, createdMessage2.id],
298
- updateData,
299
- );
300
-
301
- expect(numUpdated).toBe(2);
302
-
303
- const updatedMessage1 = await MessageModel.findById(createdMessage1.id);
304
- const updatedMessage2 = await MessageModel.findById(createdMessage2.id);
305
-
306
- expect(updatedMessage1).toHaveProperty('content', 'Batch updated content');
307
- expect(updatedMessage2).toHaveProperty('content', 'Batch updated content');
308
- });
309
- });
310
-
311
- describe('batchDelete', () => {
312
- it('should batch delete messages by session id', async () => {
313
- // 创建多条消息以测试批量删除方法
314
- const createdMessage1 = await MessageModel.create(messageData);
315
- const createdMessage2 = await MessageModel.create(messageData);
316
-
317
- await MessageModel.batchDelete(messageData.sessionId, undefined);
318
-
319
- // 验证所有具有给定会话 ID 的消息是否已删除
320
- const messagesInDb = await MessageModel.query({ sessionId: messageData.sessionId });
321
- expect(messagesInDb).toHaveLength(0);
322
- });
323
-
324
- it('should batch delete messages by session id and topic id', async () => {
325
- // 创建多条消息以测试批量删除方法
326
- const createdMessage1 = await MessageModel.create(messageData);
327
- const createdMessage2 = await MessageModel.create(messageData);
328
-
329
- await MessageModel.batchDelete(messageData.sessionId, messageData.topicId);
330
-
331
- // 验证所有具有给定会话 ID 和话题 ID 的消息是否已删除
332
- const messagesInDb = await MessageModel.query({
333
- sessionId: messageData.sessionId,
334
- topicId: messageData.topicId,
335
- });
336
- expect(messagesInDb).toHaveLength(0);
337
- });
338
- });
339
-
340
- describe('duplicateMessages', () => {
341
- it('should duplicate messages and update parentId for copied messages', async () => {
342
- // 创建原始消息和父消息
343
- const parentMessageData: CreateMessageParams = {
344
- content: 'Parent message content',
345
- role: 'user',
346
- sessionId: 'session1',
347
- topicId: undefined,
348
- };
349
- const parentMessage = await MessageModel.create(parentMessageData);
350
-
351
- const childMessageData: CreateMessageParams = {
352
- content: 'Child message content',
353
- role: 'user',
354
- sessionId: 'session1',
355
- parentId: parentMessage.id,
356
- };
357
-
358
- await MessageModel.create(childMessageData);
359
-
360
- // 获取数据库中的消息以进行复制
361
- const originalMessages = await MessageModel.queryAll();
362
-
363
- // 执行复制操作
364
- const duplicatedMessages = await MessageModel.duplicateMessages(originalMessages);
365
-
366
- // 验证复制的消息数量是否正确
367
- expect(duplicatedMessages.length).toBe(originalMessages.length);
368
-
369
- // 验证每个复制的消息是否具有新的唯一ID,并且parentId被正确更新
370
- for (const original of originalMessages) {
371
- const copied = duplicatedMessages.find((m) => m.content === original.content);
372
- expect(copied).toBeDefined();
373
- expect(copied).not.toBeNull();
374
- expect(copied!.id).not.toBe(original.id);
375
- if (original.parentId) {
376
- const originalParent = originalMessages.find((m) => m.id === original.parentId);
377
- expect(originalParent).toBeDefined();
378
- const copiedParent = duplicatedMessages.find(
379
- (m) => m.content === originalParent!.content,
380
- );
381
-
382
- expect(copied!.parentId).toBe(copiedParent!.id);
383
- }
384
- }
385
- });
386
- });
387
-
388
- describe('clearTable', () => {
389
- it('should clear the table', async () => {
390
- await MessageModel.create(messageData);
391
- await MessageModel.clearTable();
392
- const messages = await MessageModel.queryAll();
393
- expect(messages).toHaveLength(0);
394
- });
395
- });
396
-
397
- describe('updatePluginState', () => {
398
- it('should update plugin state', async () => {
399
- const createdMessage = await MessageModel.create(messageData);
400
- await MessageModel.updatePluginState(createdMessage.id, { testKey: 'testValue' });
401
- const updatedMessage = await MessageModel.findById(createdMessage.id);
402
- expect(updatedMessage.pluginState).toHaveProperty('testKey', 'testValue');
403
- });
404
- });
405
-
406
- describe('updatePlugin', () => {
407
- it('should update plugin', async () => {
408
- const value = {
409
- identifier: 'testValue',
410
- arguments: 'abc',
411
- apiName: 'abc',
412
- };
413
- const createdMessage = await MessageModel.create(messageData);
414
- await MessageModel.updatePlugin(createdMessage.id, value);
415
- const updatedMessage = await MessageModel.findById(createdMessage.id);
416
- expect(updatedMessage.plugin).toEqual(value);
417
- });
418
- });
419
-
420
- describe('isEmpty', () => {
421
- it('should return true if table is empty', async () => {
422
- const number = await MessageModel.count();
423
- expect(number === 0).toBeTruthy();
424
- });
425
- });
426
- });