@lobehub/lobehub 2.0.0-next.13 → 2.0.0-next.15

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 (219) hide show
  1. package/.github/workflows/desktop-pr-build.yml +6 -6
  2. package/.github/workflows/release-desktop-beta.yml +4 -4
  3. package/.github/workflows/release.yml +1 -2
  4. package/.github/workflows/test.yml +4 -5
  5. package/.nvmrc +1 -1
  6. package/CHANGELOG.md +42 -0
  7. package/apps/desktop/tsconfig.json +0 -1
  8. package/changelog/v1.json +14 -0
  9. package/e2e/tsconfig.json +0 -1
  10. package/package.json +58 -58
  11. package/packages/const/src/version.ts +3 -3
  12. package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
  13. package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
  14. package/packages/web-crawler/tsconfig.json +0 -1
  15. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
  16. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
  17. package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +3 -28
  18. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +0 -2
  19. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +1 -5
  20. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
  21. package/src/app/[variants]/(main)/image/page.tsx +0 -2
  22. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
  23. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
  24. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
  25. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
  26. package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
  27. package/src/app/[variants]/loading/index.tsx +1 -10
  28. package/src/components/Link.tsx +12 -0
  29. package/src/envs/app.ts +5 -8
  30. package/src/features/DataImporter/index.tsx +15 -60
  31. package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
  32. package/src/hooks/useInterceptingRoutes.test.ts +21 -3
  33. package/src/libs/trpc/client/index.ts +0 -1
  34. package/src/libs/trpc/client/lambda.ts +8 -5
  35. package/src/server/routers/desktop/mcp.ts +1 -3
  36. package/src/server/routers/lambda/config/index.test.ts +2 -2
  37. package/src/server/routers/tools/mcp.ts +2 -3
  38. package/src/server/routers/tools/search.test.ts +1 -7
  39. package/src/server/routers/tools/search.ts +1 -4
  40. package/src/services/__tests__/tool.test.ts +0 -3
  41. package/src/services/aiModel/index.test.ts +0 -3
  42. package/src/services/aiModel/index.ts +1 -7
  43. package/src/services/aiProvider/index.test.ts +0 -3
  44. package/src/services/aiProvider/index.ts +1 -7
  45. package/src/services/chatGroup/index.ts +1 -10
  46. package/src/services/config.ts +1 -65
  47. package/src/services/export/index.ts +1 -4
  48. package/src/services/file/index.ts +1 -11
  49. package/src/services/import/index.ts +1 -7
  50. package/src/services/message/index.ts +1 -11
  51. package/src/services/plugin/index.ts +1 -11
  52. package/src/services/session/index.ts +1 -11
  53. package/src/services/tableViewer/client.ts +12 -15
  54. package/src/services/thread/index.ts +1 -7
  55. package/src/services/topic/index.ts +1 -11
  56. package/src/services/user/index.ts +1 -13
  57. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -241
  58. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +26 -1
  59. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +3 -1
  60. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +1 -138
  61. package/src/store/user/slices/common/action.test.ts +1 -4
  62. package/tsconfig.json +0 -1
  63. package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
  64. package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
  65. package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
  66. package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
  67. package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
  68. package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +0 -29
  69. package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
  70. package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
  71. package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
  72. package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
  73. package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
  74. package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
  75. package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
  76. package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
  77. package/src/app/[variants]/loading/Client/Content.tsx +0 -48
  78. package/src/app/[variants]/loading/Client/Error.tsx +0 -27
  79. package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
  80. package/src/app/[variants]/loading/Client/index.tsx +0 -22
  81. package/src/components/InnerLink.tsx +0 -20
  82. package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
  83. package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
  84. package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
  85. package/src/database/_deprecated/core/db.ts +0 -246
  86. package/src/database/_deprecated/core/index.ts +0 -2
  87. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
  88. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
  89. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
  90. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
  91. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
  92. package/src/database/_deprecated/core/model.ts +0 -218
  93. package/src/database/_deprecated/core/schemas.ts +0 -88
  94. package/src/database/_deprecated/core/types/db.ts +0 -15
  95. package/src/database/_deprecated/models/__DEBUG.ts +0 -124
  96. package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
  97. package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
  98. package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
  99. package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
  100. package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
  101. package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
  102. package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
  103. package/src/database/_deprecated/models/file.ts +0 -51
  104. package/src/database/_deprecated/models/message.ts +0 -277
  105. package/src/database/_deprecated/models/plugin.ts +0 -62
  106. package/src/database/_deprecated/models/session.ts +0 -271
  107. package/src/database/_deprecated/models/sessionGroup.ts +0 -93
  108. package/src/database/_deprecated/models/topic.ts +0 -250
  109. package/src/database/_deprecated/models/user.ts +0 -69
  110. package/src/database/_deprecated/schemas/files.ts +0 -39
  111. package/src/database/_deprecated/schemas/message.ts +0 -50
  112. package/src/database/_deprecated/schemas/plugin.ts +0 -12
  113. package/src/database/_deprecated/schemas/session.ts +0 -54
  114. package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
  115. package/src/database/_deprecated/schemas/topic.ts +0 -12
  116. package/src/database/_deprecated/schemas/user.ts +0 -40
  117. package/src/features/DataImporter/_deprecated.ts +0 -43
  118. package/src/features/InitClientDB/EnableModal.tsx +0 -118
  119. package/src/features/InitClientDB/ErrorResult.tsx +0 -143
  120. package/src/features/InitClientDB/InitIndicator.tsx +0 -124
  121. package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
  122. package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
  123. package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
  124. package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
  125. package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
  126. package/src/features/InitClientDB/index.tsx +0 -37
  127. package/src/libs/trpc/client/edge.ts +0 -26
  128. package/src/libs/trpc/edge/context.ts +0 -71
  129. package/src/libs/trpc/edge/index.ts +0 -45
  130. package/src/libs/trpc/edge/init.ts +0 -26
  131. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
  132. package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
  133. package/src/migrations/FromV0ToV1.ts +0 -10
  134. package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
  135. package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
  136. package/src/migrations/FromV1ToV2/index.ts +0 -82
  137. package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
  138. package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
  139. package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
  140. package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
  141. package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
  142. package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
  143. package/src/migrations/FromV2ToV3/index.ts +0 -30
  144. package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
  145. package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
  146. package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
  147. package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
  148. package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
  149. package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
  150. package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
  151. package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
  152. package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
  153. package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
  154. package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
  155. package/src/migrations/FromV3ToV4/index.ts +0 -102
  156. package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
  157. package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
  158. package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
  159. package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
  160. package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
  161. package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
  162. package/src/migrations/FromV4ToV5/index.ts +0 -58
  163. package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
  164. package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
  165. package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
  166. package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
  167. package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
  168. package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
  169. package/src/migrations/FromV5ToV6/index.ts +0 -61
  170. package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
  171. package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
  172. package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
  173. package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
  174. package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
  175. package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
  176. package/src/migrations/FromV6ToV7/index.ts +0 -101
  177. package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
  178. package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
  179. package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
  180. package/src/migrations/VersionController.test.ts +0 -88
  181. package/src/migrations/VersionController.ts +0 -67
  182. package/src/migrations/index.ts +0 -61
  183. package/src/server/routers/edge/appStatus.ts +0 -3
  184. package/src/server/routers/edge/index.ts +0 -14
  185. package/src/server/routers/edge/upload.ts +0 -16
  186. package/src/services/aiModel/client.ts +0 -70
  187. package/src/services/aiProvider/client.ts +0 -58
  188. package/src/services/baseClientService/index.ts +0 -9
  189. package/src/services/chatGroup/client.ts +0 -63
  190. package/src/services/export/_deprecated.ts +0 -155
  191. package/src/services/export/client.ts +0 -15
  192. package/src/services/file/_deprecated.test.ts +0 -119
  193. package/src/services/file/_deprecated.ts +0 -80
  194. package/src/services/file/client.test.ts +0 -199
  195. package/src/services/file/client.ts +0 -85
  196. package/src/services/import/_deprecated.ts +0 -115
  197. package/src/services/import/client.test.ts +0 -1015
  198. package/src/services/import/client.ts +0 -64
  199. package/src/services/message/_deprecated.test.ts +0 -398
  200. package/src/services/message/_deprecated.ts +0 -168
  201. package/src/services/message/client.test.ts +0 -410
  202. package/src/services/message/client.ts +0 -192
  203. package/src/services/plugin/_deprecated.test.ts +0 -162
  204. package/src/services/plugin/_deprecated.ts +0 -42
  205. package/src/services/plugin/client.test.ts +0 -177
  206. package/src/services/plugin/client.ts +0 -46
  207. package/src/services/session/_deprecated.test.ts +0 -440
  208. package/src/services/session/_deprecated.ts +0 -190
  209. package/src/services/session/client.test.ts +0 -413
  210. package/src/services/session/client.ts +0 -193
  211. package/src/services/thread/client.ts +0 -51
  212. package/src/services/topic/_deprecated.test.ts +0 -245
  213. package/src/services/topic/_deprecated.ts +0 -75
  214. package/src/services/topic/client.ts +0 -89
  215. package/src/services/topic/pglite.test.ts +0 -212
  216. package/src/services/user/_deprecated.test.ts +0 -101
  217. package/src/services/user/_deprecated.ts +0 -70
  218. package/src/services/user/client.test.ts +0 -111
  219. package/src/services/user/client.ts +0 -104
@@ -17,15 +17,12 @@ import { StateCreator } from 'zustand/vanilla';
17
17
 
18
18
  import { chatService } from '@/services/chat';
19
19
  import { messageService } from '@/services/message';
20
- import { useAgentStore } from '@/store/agent';
21
20
  import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
22
21
  import { getAgentStoreState } from '@/store/agent/store';
23
22
  import { aiModelSelectors, aiProviderSelectors } from '@/store/aiInfra';
24
23
  import { getAiInfraStoreState } from '@/store/aiInfra/store';
25
24
  import { ChatStore } from '@/store/chat/store';
26
- import { messageMapKey } from '@/store/chat/utils/messageMapKey';
27
25
  import { getFileStoreState } from '@/store/file/store';
28
- import { useSessionStore } from '@/store/session';
29
26
  import { WebBrowsingManifest } from '@/tools/web-browsing';
30
27
  import { Action, setNamespace } from '@/utils/storeDebug';
31
28
 
@@ -158,13 +155,7 @@ export const generateAIChat: StateCreator<
158
155
  },
159
156
 
160
157
  sendMessage: async ({ message, files, onlyAddUserMessage, isWelcomeQuestion }) => {
161
- const {
162
- internal_coreProcessMessage,
163
- activeTopicId,
164
- activeId,
165
- activeThreadId,
166
- sendMessageInServer,
167
- } = get();
158
+ const { activeId, sendMessageInServer } = get();
168
159
  if (!activeId) return;
169
160
 
170
161
  const fileIdList = files?.map((f) => f.id);
@@ -177,134 +168,6 @@ export const generateAIChat: StateCreator<
177
168
  // router to server mode send message
178
169
  if (isServerMode)
179
170
  return sendMessageInServer({ message, files, onlyAddUserMessage, isWelcomeQuestion });
180
-
181
- set({ isCreatingMessage: true }, false, n('creatingMessage/start'));
182
-
183
- const newMessage: CreateMessageParams = {
184
- content: message,
185
- // if message has attached with files, then add files to message and the agent
186
- files: fileIdList,
187
- role: 'user',
188
- sessionId: activeId,
189
- // if there is activeTopicId,then add topicId to message
190
- topicId: activeTopicId,
191
- threadId: activeThreadId,
192
- };
193
-
194
- const agentConfig = agentChatConfigSelectors.currentChatConfig(getAgentStoreState());
195
-
196
- let tempMessageId: string | undefined = undefined;
197
- let newTopicId: string | undefined = undefined;
198
-
199
- // it should be the default topic, then
200
- // if autoCreateTopic is enabled, check to whether we need to create a topic
201
- if (!onlyAddUserMessage && !activeTopicId && agentConfig.enableAutoCreateTopic) {
202
- // check activeTopic and then auto create topic
203
- const chats = chatSelectors.activeBaseChats(get());
204
-
205
- // we will add two messages (user and assistant), so the finial length should +2
206
- const featureLength = chats.length + 2;
207
-
208
- // if there is no activeTopicId and the feature length is greater than the threshold
209
- // then create a new topic and active it
210
- if (!activeTopicId && featureLength >= agentConfig.autoCreateTopicThreshold) {
211
- // we need to create a temp message for optimistic update
212
- tempMessageId = get().internal_createTmpMessage(newMessage);
213
- get().internal_toggleMessageLoading(true, tempMessageId);
214
-
215
- const topicId = await get().createTopic();
216
-
217
- if (topicId) {
218
- newTopicId = topicId;
219
- newMessage.topicId = topicId;
220
-
221
- // we need to copy the messages to the new topic or the message will disappear
222
- const mapKey = chatSelectors.currentChatKey(get());
223
- const newMaps = {
224
- ...get().messagesMap,
225
- [messageMapKey(activeId, topicId)]: get().messagesMap[mapKey],
226
- };
227
- set({ messagesMap: newMaps }, false, n('moveMessagesToNewTopic'));
228
-
229
- // make the topic loading
230
- get().internal_updateTopicLoading(topicId, true);
231
- }
232
- }
233
- }
234
- // update assistant update to make it rerank
235
- useSessionStore.getState().triggerSessionUpdate(get().activeId);
236
-
237
- const id = await get().internal_createMessage(newMessage, {
238
- tempMessageId,
239
- skipRefresh: !onlyAddUserMessage && newMessage.fileList?.length === 0,
240
- });
241
-
242
- if (!id) {
243
- set({ isCreatingMessage: false }, false, n('creatingMessage/start'));
244
- if (!!newTopicId) get().internal_updateTopicLoading(newTopicId, false);
245
- return;
246
- }
247
-
248
- if (tempMessageId) get().internal_toggleMessageLoading(false, tempMessageId);
249
-
250
- // switch to the new topic if create the new topic
251
- if (!!newTopicId) {
252
- await get().switchTopic(newTopicId, true);
253
- await get().internal_fetchMessages();
254
-
255
- // delete previous messages
256
- // remove the temp message map
257
- const newMaps = { ...get().messagesMap, [messageMapKey(activeId, null)]: [] };
258
- set({ messagesMap: newMaps }, false, 'internal_copyMessages');
259
- }
260
-
261
- // if only add user message, then stop
262
- if (onlyAddUserMessage) {
263
- set({ isCreatingMessage: false }, false, 'creatingMessage/start');
264
- return;
265
- }
266
-
267
- // Get the current messages to generate AI response
268
- const messages = chatSelectors.activeBaseChats(get());
269
- const userFiles = chatSelectors.currentUserFiles(get()).map((f) => f.id);
270
-
271
- await internal_coreProcessMessage(messages, id, {
272
- isWelcomeQuestion,
273
- ragQuery: get().internal_shouldUseRAG() ? message : undefined,
274
- threadId: activeThreadId,
275
- });
276
-
277
- set({ isCreatingMessage: false }, false, n('creatingMessage/stop'));
278
-
279
- const summaryTitle = async () => {
280
- // if autoCreateTopic is false, then stop
281
- if (!agentConfig.enableAutoCreateTopic) return;
282
-
283
- // check activeTopic and then auto update topic title
284
- if (newTopicId) {
285
- const chats = chatSelectors.getBaseChatsByKey(messageMapKey(activeId, newTopicId))(get());
286
- await get().summaryTopicTitle(newTopicId, chats);
287
- return;
288
- }
289
-
290
- if (!activeTopicId) return;
291
- const topic = topicSelectors.getTopicById(activeTopicId)(get());
292
-
293
- if (topic && !topic.title) {
294
- const chats = chatSelectors.getBaseChatsByKey(messageMapKey(activeId, topic.id))(get());
295
- await get().summaryTopicTitle(topic.id, chats);
296
- }
297
- };
298
-
299
- // if there is relative files, then add files to agent
300
- // only available in server mode
301
- const addFilesToAgent = async () => {
302
- if (userFiles.length === 0 || !isServerMode) return;
303
-
304
- await useAgentStore.getState().addFilesToAgent(userFiles, false);
305
- };
306
-
307
- await Promise.all([summaryTitle(), addFilesToAgent()]);
308
171
  },
309
172
  stopGenerateMessage: () => {
310
173
  const { chatLoadingIdsAbortController, internal_toggleChatLoading } = get();
@@ -4,7 +4,6 @@ import { withSWR } from '~test-utils';
4
4
 
5
5
  import { DEFAULT_PREFERENCE } from '@/const/user';
6
6
  import { userService } from '@/services/user';
7
- import { ClientService } from '@/services/user/_deprecated';
8
7
  import { useUserStore } from '@/store/user';
9
8
  import { preferenceSelectors } from '@/store/user/selectors';
10
9
  import { GlobalServerConfig } from '@/types/serverConfig';
@@ -31,9 +30,7 @@ describe('createCommonSlice', () => {
31
30
  const avatar = 'data:image/png;base64,';
32
31
 
33
32
  const spyOn = vi.spyOn(result.current, 'refreshUserState');
34
- const updateAvatarSpy = vi
35
- .spyOn(ClientService.prototype, 'updateAvatar')
36
- .mockResolvedValue(undefined);
33
+ const updateAvatarSpy = vi.spyOn(userService, 'updateAvatar').mockResolvedValue(undefined);
37
34
 
38
35
  await act(async () => {
39
36
  await result.current.updateAvatar(avatar);
package/tsconfig.json CHANGED
@@ -15,7 +15,6 @@
15
15
  "isolatedModules": true,
16
16
  "jsx": "react-jsx",
17
17
  "incremental": true,
18
- "baseUrl": ".",
19
18
  "types": ["vitest/globals", "@serwist/next/typings"],
20
19
  "paths": {
21
20
  "@/database/*": ["./packages/database/src/*", "./src/database/*"],
@@ -1,26 +0,0 @@
1
- import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
2
- import type { NextRequest } from 'next/server';
3
-
4
- import { pino } from '@/libs/logger';
5
- import { createEdgeContext } from '@/libs/trpc/edge/context';
6
- import { edgeRouter } from '@/server/routers/edge';
7
-
8
- const handler = (req: NextRequest) =>
9
- fetchRequestHandler({
10
- /**
11
- * @link https://trpc.io/docs/v11/context
12
- */
13
- createContext: () => createEdgeContext(req),
14
-
15
- endpoint: '/trpc/edge',
16
-
17
- onError: ({ error, path }) => {
18
- pino.info(`Error in tRPC handler (edge) on path: ${path}`);
19
- console.error(error);
20
- },
21
-
22
- req,
23
- router: edgeRouter,
24
- });
25
-
26
- export { handler as GET, handler as POST };
@@ -1,48 +0,0 @@
1
- 'use client';
2
-
3
- import { memo } from 'react';
4
- import { useTranslation } from 'react-i18next';
5
-
6
- import Cell, { CellProps } from '@/components/Cell';
7
- import DataImporter from '@/features/DataImporter';
8
- import { configService } from '@/services/export/_deprecated';
9
-
10
- const Category = memo(() => {
11
- const { t } = useTranslation('common');
12
- const items: CellProps[] = [
13
- {
14
- key: 'allAgent',
15
- label: t('exportType.allAgent'),
16
- onClick: configService.exportAgents,
17
- },
18
- {
19
- key: 'allAgentWithMessage',
20
- label: t('exportType.allAgentWithMessage'),
21
- onClick: configService.exportSessions,
22
- },
23
- {
24
- key: 'globalSetting',
25
- label: t('exportType.globalSetting'),
26
- onClick: configService.exportSettings,
27
- },
28
- {
29
- type: 'divider',
30
- },
31
- {
32
- key: 'all',
33
- label: t('exportType.all'),
34
- onClick: configService.exportAll,
35
- },
36
- {
37
- type: 'divider',
38
- },
39
- {
40
- key: 'import',
41
- label: <DataImporter>{t('importData')}</DataImporter>,
42
- },
43
- ];
44
-
45
- return items?.map(({ key, ...item }, index) => <Cell key={key || index} {...item} />);
46
- });
47
-
48
- export default Category;
@@ -1,33 +0,0 @@
1
- 'use client';
2
-
3
- import { ChatHeader } from '@lobehub/ui/mobile';
4
- import { useRouter } from 'next/navigation';
5
- import { memo } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
- import { Flexbox } from 'react-layout-kit';
8
-
9
- import { mobileHeaderSticky } from '@/styles/mobileHeader';
10
-
11
- const Header = memo(() => {
12
- const { t } = useTranslation('common');
13
-
14
- const router = useRouter();
15
- return (
16
- <ChatHeader
17
- center={
18
- <ChatHeader.Title
19
- title={
20
- <Flexbox align={'center'} gap={4} horizontal>
21
- {t('userPanel.data')}
22
- </Flexbox>
23
- }
24
- />
25
- }
26
- onBackClick={() => router.push('/me')}
27
- showBackButton
28
- style={mobileHeaderSticky}
29
- />
30
- );
31
- });
32
-
33
- export default Header;
@@ -1,13 +0,0 @@
1
- import { PropsWithChildren } from 'react';
2
-
3
- import MobileContentLayout from '@/components/server/MobileNavLayout';
4
-
5
- import Header from './features/Header';
6
-
7
- const Layout = ({ children }: PropsWithChildren) => {
8
- return <MobileContentLayout header={<Header />}>{children}</MobileContentLayout>;
9
- };
10
-
11
- Layout.displayName = 'MeDataLayout';
12
-
13
- export default Layout;
@@ -1,5 +0,0 @@
1
- import SkeletonLoading from '@/components/Loading/SkeletonLoading';
2
-
3
- export default () => {
4
- return <SkeletonLoading paragraph={{ rows: 8 }} />;
5
- };
@@ -1,29 +0,0 @@
1
- import { redirect } from 'next/navigation';
2
-
3
- import { metadataModule } from '@/server/metadata';
4
- import { translation } from '@/server/translation';
5
- import { DynamicLayoutProps } from '@/types/next';
6
- import { RouteVariants } from '@/utils/server/routeVariants';
7
-
8
- import Category from './features/Category';
9
-
10
- export const generateMetadata = async (props: DynamicLayoutProps) => {
11
- const locale = await RouteVariants.getLocale(props);
12
- const { t } = await translation('common', locale);
13
- return metadataModule.generate({
14
- title: t('userPanel.data'),
15
- url: '/me/data',
16
- });
17
- };
18
-
19
- const Page = async (props: DynamicLayoutProps) => {
20
- const mobile = await RouteVariants.getIsMobile(props);
21
-
22
- if (!mobile) return redirect('/chat');
23
-
24
- return <Category />;
25
- };
26
-
27
- Page.displayName = 'MeData';
28
-
29
- export default Page;
@@ -1,290 +0,0 @@
1
- import {
2
- ImportMessage,
3
- ImportSession,
4
- ImportSessionGroup,
5
- ImportTopic,
6
- ImporterEntryData,
7
- } from '@/types/importer';
8
-
9
- interface V2DB_File {
10
- /**
11
- * create Time
12
- */
13
- createdAt: number;
14
- /**
15
- * file data array buffer
16
- */
17
- data: ArrayBuffer;
18
- /**
19
- * file type
20
- * @example 'image/png'
21
- */
22
- fileType: string;
23
- id: string;
24
- metadata: any;
25
- /**
26
- * file name
27
- * @example 'test.png'
28
- */
29
- name: string;
30
- /**
31
- * the mode database save the file
32
- * local mean save the raw file into data
33
- * url mean upload the file to a cdn and then save the url
34
- */
35
- saveMode: 'local' | 'url';
36
- /**
37
- * file size
38
- */
39
- size: number;
40
- /**
41
- * file url if saveMode is url
42
- */
43
- url: string;
44
- }
45
-
46
- interface V2DB_MESSAGE {
47
- content: string;
48
- createdAt: number;
49
- error?: any;
50
- favorite: 0 | 1;
51
- files?: string[];
52
- fromModel?: string;
53
- fromProvider?: string;
54
- id: string;
55
- observationId?: string;
56
- // foreign keys
57
- parentId?: string;
58
- plugin?: any;
59
- pluginError?: any;
60
- pluginState?: any;
61
-
62
- quotaId?: string;
63
- role: string;
64
- sessionId?: string;
65
- tool_call_id?: string;
66
- tools?: object[];
67
- topicId?: string;
68
-
69
- traceId?: string;
70
- translate?: object | false;
71
- tts?: any;
72
- updatedAt: number;
73
- }
74
-
75
- interface DB_Plugin {
76
- createdAt: number;
77
- id: string;
78
- identifier: string;
79
- manifest?: object;
80
- settings?: object;
81
- type: 'plugin' | 'customPlugin';
82
- updatedAt: number;
83
- }
84
-
85
- interface DB_Session {
86
- config: object;
87
- createdAt: number;
88
- group?: string;
89
- // 原 Agent 类型
90
- id: string;
91
- meta: object;
92
- pinned?: number;
93
- type?: 'agent' | 'group';
94
- updatedAt: number;
95
- }
96
-
97
- interface DB_SessionGroup {
98
- createdAt: number;
99
- id: string;
100
- name: string;
101
- sort?: number;
102
- updatedAt: number;
103
- }
104
-
105
- interface DB_Topic {
106
- createdAt: number;
107
- favorite?: number;
108
- id: string;
109
- sessionId?: string;
110
- title: string;
111
- updatedAt: number;
112
- }
113
-
114
- interface DB_User {
115
- avatar?: string;
116
- createdAt: number;
117
- id: string;
118
- settings: object;
119
- updatedAt: number;
120
- uuid: string;
121
- }
122
-
123
- interface MigrationData {
124
- files: V2DB_File[];
125
- messages: V2DB_MESSAGE[];
126
- plugins: DB_Plugin[];
127
- sessionGroups: DB_SessionGroup[];
128
- sessions: DB_Session[];
129
- topics: DB_Topic[];
130
- users: DB_User[];
131
- }
132
-
133
- const LOBE_CHAT_LOCAL_DB_NAME = 'LOBE_CHAT_DB';
134
-
135
- const V2DB_LASET_SCHEMA_VERSION = 7;
136
- export class V2DBReader {
137
- private dbName: string = LOBE_CHAT_LOCAL_DB_NAME;
138
- private storeNames: string[];
139
-
140
- constructor(storeNames: string[]) {
141
- this.storeNames = storeNames;
142
- }
143
-
144
- /**
145
- * 读取所有数据
146
- */
147
- async readAllData(): Promise<MigrationData> {
148
- try {
149
- // 打开数据库连接
150
- const db = await this.openDB();
151
-
152
- // 并行读取所有表的数据
153
- const results = await Promise.all(
154
- this.storeNames.map((storeName) => this.readStore(db, storeName)),
155
- );
156
-
157
- // 构建返回结果
158
- const migrationData = this.storeNames.reduce((acc, storeName, index) => {
159
- // @ts-expect-error
160
- acc[storeName] = results[index];
161
- return acc;
162
- }, {} as MigrationData);
163
-
164
- // 关闭数据库连接
165
- db.close();
166
-
167
- return migrationData;
168
- } catch (error) {
169
- console.error('读取数据库失败:', error);
170
- throw error;
171
- }
172
- }
173
-
174
- async convertToImportData(data: MigrationData): Promise<ImporterEntryData> {
175
- // 转换 messages
176
- const messages = data.messages.map(
177
- (msg): ImportMessage => ({
178
- // 使用原有的 id
179
- content: msg.content,
180
- createdAt: msg.createdAt,
181
- // 处理 error
182
- error: msg.error || msg.pluginError,
183
-
184
- // 处理额外信息
185
- extra: {
186
- fromModel: msg.fromModel,
187
- fromProvider: msg.fromProvider,
188
- translate: msg.translate as any,
189
- tts: msg.tts,
190
- },
191
-
192
- files: msg.files,
193
- id: msg.id,
194
-
195
- // 复制原有字段
196
- observationId: msg.observationId,
197
- parentId: msg.parentId,
198
- plugin: msg.plugin,
199
- pluginState: msg.pluginState,
200
- quotaId: msg.quotaId,
201
- role: msg.role as any,
202
- sessionId: msg.sessionId,
203
- tool_call_id: msg.tool_call_id,
204
- tools: msg.tools as any,
205
-
206
- topicId: msg.topicId,
207
-
208
- traceId: msg.traceId,
209
-
210
- updatedAt: msg.updatedAt,
211
- }),
212
- );
213
-
214
- // 转换 sessionGroups
215
- const sessionGroups = data.sessionGroups.map(
216
- (group): ImportSessionGroup => ({
217
- createdAt: group.createdAt,
218
- id: group.id,
219
- // 使用原有的 id
220
- name: group.name,
221
- sort: group.sort || null,
222
- updatedAt: group.updatedAt,
223
- }),
224
- );
225
-
226
- // 转换 sessions
227
- const sessions = data.sessions.map(
228
- (session): ImportSession => ({
229
- // 使用原有的 id
230
- config: session.config as any,
231
- createdAt: new Date(session.createdAt).toString(),
232
- group: session.group,
233
- id: session.id,
234
- meta: session.meta as any,
235
- pinned: session.pinned ? true : undefined,
236
- type: session.type || 'agent',
237
- updatedAt: new Date(session.updatedAt).toString(),
238
- }),
239
- );
240
-
241
- const topics = data.topics.map(
242
- (topic): ImportTopic => ({
243
- ...topic,
244
- favorite: topic.favorite ? true : undefined,
245
- }),
246
- );
247
-
248
- return {
249
- messages,
250
- sessionGroups,
251
- sessions,
252
- topics,
253
- version: V2DB_LASET_SCHEMA_VERSION,
254
- };
255
- }
256
-
257
- /**
258
- * 打开数据库
259
- */
260
- private openDB(): Promise<IDBDatabase> {
261
- return new Promise((resolve, reject) => {
262
- const request = indexedDB.open(this.dbName);
263
-
264
- // eslint-disable-next-line unicorn/prefer-add-event-listener
265
- request.onerror = () => {
266
- reject(request.error);
267
- };
268
- request.onsuccess = () => resolve(request.result);
269
- });
270
- }
271
-
272
- /**
273
- * 读取单个存储对象的所有数据
274
- */
275
- private readStore(db: IDBDatabase, storeName: string): Promise<any[]> {
276
- return new Promise((resolve, reject) => {
277
- try {
278
- const transaction = db.transaction(storeName, 'readonly');
279
- const store = transaction.objectStore(storeName);
280
- const request = store.getAll();
281
-
282
- // eslint-disable-next-line unicorn/prefer-add-event-listener
283
- request.onerror = () => reject(request.error);
284
- request.onsuccess = () => resolve(request.result);
285
- } catch (error) {
286
- reject(error);
287
- }
288
- });
289
- }
290
- }
@@ -1,35 +0,0 @@
1
- import { Button } from '@lobehub/ui';
2
- import { memo } from 'react';
3
- import { useTranslation } from 'react-i18next';
4
-
5
- import { BRANDING_NAME } from '@/const/branding';
6
-
7
- const ExportConfigButton = memo<{ primary?: boolean; state: any }>(({ state, primary }) => {
8
- const { t } = useTranslation('migration');
9
-
10
- const exportData = () => {
11
- const config = { exportType: 'sessions', state, version: 1 };
12
-
13
- const url = URL.createObjectURL(
14
- new Blob([JSON.stringify(config)], { type: 'application/json' }),
15
- );
16
-
17
- const a = document.createElement('a');
18
- a.href = url;
19
- a.download = `${BRANDING_NAME}-backup-v1.json`;
20
-
21
- document.body.append(a);
22
- a.click();
23
-
24
- URL.revokeObjectURL(url);
25
- a.remove();
26
- };
27
-
28
- return (
29
- <Button onClick={exportData} size={'large'} type={primary ? 'primary' : undefined}>
30
- {t('dbV1.action.downloadBackup')}
31
- </Button>
32
- );
33
- });
34
-
35
- export default ExportConfigButton;