@lobehub/chat 1.36.30 → 1.36.32

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 (71) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/docs/self-hosting/environment-variables/model-provider.mdx +7 -0
  4. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +7 -0
  5. package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +12 -12
  6. package/package.json +1 -1
  7. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +3 -9
  8. package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +2 -4
  9. package/src/app/(main)/chat/@session/features/SessionListContent/DefaultMode.tsx +2 -5
  10. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InstallPlugin.tsx +10 -15
  11. package/src/database/repositories/dataImporter/__tests__/index.test.ts +11 -18
  12. package/src/database/repositories/dataImporter/index.ts +31 -46
  13. package/src/database/server/models/__tests__/_test_template.ts +1 -1
  14. package/src/database/server/models/__tests__/agent.test.ts +1 -1
  15. package/src/database/server/models/__tests__/asyncTask.test.ts +1 -1
  16. package/src/database/server/models/__tests__/chunk.test.ts +1 -1
  17. package/src/database/server/models/__tests__/file.test.ts +1 -1
  18. package/src/database/server/models/__tests__/knowledgeBase.test.ts +1 -2
  19. package/src/database/server/models/__tests__/message.test.ts +35 -72
  20. package/src/database/server/models/__tests__/nextauth.test.ts +1 -1
  21. package/src/database/server/models/__tests__/session.test.ts +1 -1
  22. package/src/database/server/models/__tests__/sessionGroup.test.ts +1 -2
  23. package/src/database/server/models/__tests__/topic.test.ts +1 -1
  24. package/src/database/server/models/__tests__/user.test.ts +1 -1
  25. package/src/database/server/models/_template.ts +2 -2
  26. package/src/database/server/models/agent.ts +17 -25
  27. package/src/database/server/models/asyncTask.ts +2 -2
  28. package/src/database/server/models/chunk.ts +14 -14
  29. package/src/database/server/models/embedding.ts +1 -1
  30. package/src/database/server/models/file.ts +8 -10
  31. package/src/database/server/models/knowledgeBase.ts +4 -6
  32. package/src/database/server/models/message.ts +54 -65
  33. package/src/database/server/models/plugin.ts +6 -2
  34. package/src/database/server/models/ragEval/dataset.ts +2 -2
  35. package/src/database/server/models/ragEval/datasetRecord.ts +3 -8
  36. package/src/database/server/models/ragEval/evaluation.ts +3 -2
  37. package/src/database/server/models/ragEval/evaluationRecord.ts +2 -2
  38. package/src/database/server/models/session.ts +40 -35
  39. package/src/database/server/models/sessionGroup.ts +4 -4
  40. package/src/database/server/models/thread.ts +2 -2
  41. package/src/database/server/models/topic.ts +48 -53
  42. package/src/database/server/models/user.ts +12 -12
  43. package/src/features/AgentSetting/AgentPlugin/index.tsx +1 -1
  44. package/src/features/ChatInput/ActionBar/Tools/Dropdown.tsx +4 -4
  45. package/src/features/Portal/Thread/Chat/ChatList.tsx +1 -2
  46. package/src/hooks/useCheckPluginsIsInstalled.ts +10 -0
  47. package/src/hooks/useFetchInstalledPlugins.ts +10 -0
  48. package/src/hooks/useFetchMessages.ts +15 -0
  49. package/src/hooks/useFetchSessions.ts +13 -0
  50. package/src/hooks/useFetchThreads.ts +11 -0
  51. package/src/hooks/useFetchTopics.ts +6 -6
  52. package/src/layout/GlobalProvider/StoreInitialization.tsx +3 -1
  53. package/src/libs/agent-runtime/utils/streams/azureOpenai.test.ts +0 -1
  54. package/src/libs/next-auth/adapter/index.ts +1 -1
  55. package/src/server/routers/lambda/chunk.ts +2 -2
  56. package/src/services/user/client.ts +2 -2
  57. package/src/store/agent/slices/chat/action.test.ts +21 -10
  58. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +10 -0
  59. package/src/store/chat/slices/builtinTool/action.ts +0 -1
  60. package/src/store/chat/slices/message/action.test.ts +3 -1
  61. package/src/store/chat/slices/message/action.ts +7 -3
  62. package/src/store/chat/slices/thread/action.ts +3 -3
  63. package/src/store/chat/slices/topic/action.test.ts +1 -1
  64. package/src/store/chat/slices/topic/action.ts +3 -3
  65. package/src/store/global/selectors.ts +6 -0
  66. package/src/store/session/slices/session/action.ts +6 -3
  67. package/src/store/session/slices/sessionGroup/action.test.ts +8 -6
  68. package/src/store/tool/slices/plugin/action.ts +5 -3
  69. package/src/store/tool/slices/store/action.ts +4 -3
  70. package/src/store/user/slices/common/action.test.ts +3 -1
  71. package/vercel.json +1 -1
@@ -232,7 +232,7 @@ describe('topic action', () => {
232
232
  (topicService.getTopics as Mock).mockResolvedValue(topics);
233
233
 
234
234
  // Use the hook with the session id
235
- const { result } = renderHook(() => useChatStore().useFetchTopics(sessionId));
235
+ const { result } = renderHook(() => useChatStore().useFetchTopics(true, sessionId));
236
236
 
237
237
  // Wait for the hook to resolve and update the state
238
238
  await waitFor(() => {
@@ -48,7 +48,7 @@ export interface ChatTopicAction {
48
48
  summaryTopicTitle: (topicId: string, messages: ChatMessage[]) => Promise<void>;
49
49
  switchTopic: (id?: string, skipRefreshMessage?: boolean) => Promise<void>;
50
50
  updateTopicTitle: (id: string, title: string) => Promise<void>;
51
- useFetchTopics: (sessionId: string) => SWRResponse<ChatTopic[]>;
51
+ useFetchTopics: (enable: boolean, sessionId: string) => SWRResponse<ChatTopic[]>;
52
52
  useSearchTopics: (keywords?: string, sessionId?: string) => SWRResponse<ChatTopic[]>;
53
53
 
54
54
  internal_updateTopicTitleInSummary: (id: string, title: string) => void;
@@ -190,9 +190,9 @@ export const chatTopic: StateCreator<
190
190
  },
191
191
 
192
192
  // query
193
- useFetchTopics: (sessionId) =>
193
+ useFetchTopics: (enable, sessionId) =>
194
194
  useClientDataSWR<ChatTopic[]>(
195
- [SWR_USE_FETCH_TOPIC, sessionId],
195
+ enable ? [SWR_USE_FETCH_TOPIC, sessionId] : null,
196
196
  async ([, sessionId]: [string, string]) => topicService.getTopics({ sessionId }),
197
197
  {
198
198
  suspense: true,
@@ -24,12 +24,18 @@ const threadInputHeight = (s: GlobalStore) => s.status.threadInputHeight;
24
24
 
25
25
  const isPgliteNotEnabled = () => false;
26
26
 
27
+ const isPgliteNotInited = () => false;
28
+
29
+ const isPgliteInited = (): boolean => true;
30
+
27
31
  export const systemStatusSelectors = {
28
32
  filePanelWidth,
29
33
  hidePWAInstaller,
30
34
  inZenMode,
31
35
  inputHeight,
36
+ isPgliteInited,
32
37
  isPgliteNotEnabled,
38
+ isPgliteNotInited,
33
39
  mobileShowPortal,
34
40
  mobileShowTopic,
35
41
  sessionGroupKeys,
@@ -73,7 +73,10 @@ export interface SessionAction {
73
73
 
74
74
  updateSearchKeywords: (keywords: string) => void;
75
75
 
76
- useFetchSessions: (isLogin: boolean | undefined) => SWRResponse<ChatSessionList>;
76
+ useFetchSessions: (
77
+ enabled: boolean,
78
+ isLogin: boolean | undefined,
79
+ ) => SWRResponse<ChatSessionList>;
77
80
  useSearchSessions: (keyword?: string) => SWRResponse<any>;
78
81
 
79
82
  internal_dispatchSessions: (payload: SessionDispatch) => void;
@@ -197,9 +200,9 @@ export const createSessionSlice: StateCreator<
197
200
  await refreshSessions();
198
201
  },
199
202
 
200
- useFetchSessions: (isLogin) =>
203
+ useFetchSessions: (enabled, isLogin) =>
201
204
  useClientDataSWR<ChatSessionList>(
202
- [FETCH_SESSIONS_KEY, isLogin],
205
+ enabled ? [FETCH_SESSIONS_KEY, isLogin] : null,
203
206
  () => sessionService.getGroupedSessions(),
204
207
  {
205
208
  fallbackData: {
@@ -40,7 +40,9 @@ describe('createSessionGroupSlice', () => {
40
40
 
41
41
  describe('clearSessionGroups', () => {
42
42
  it('should clear session groups and refresh sessions', async () => {
43
- vi.spyOn(sessionService, 'removeSessionGroups');
43
+ const spyOn = vi
44
+ .spyOn(sessionService, 'removeSessionGroups')
45
+ .mockResolvedValueOnce(undefined);
44
46
  const spyOnRefreshSessions = vi.spyOn(useSessionStore.getState(), 'refreshSessions');
45
47
 
46
48
  const { result } = renderHook(() => useSessionStore());
@@ -49,7 +51,7 @@ describe('createSessionGroupSlice', () => {
49
51
  await result.current.clearSessionGroups();
50
52
  });
51
53
 
52
- expect(sessionService.removeSessionGroups).toHaveBeenCalled();
54
+ expect(spyOn).toHaveBeenCalled();
53
55
  expect(spyOnRefreshSessions).toHaveBeenCalled();
54
56
  });
55
57
  });
@@ -57,7 +59,7 @@ describe('createSessionGroupSlice', () => {
57
59
  describe('removeSessionGroup', () => {
58
60
  it('should remove a session group and refresh sessions', async () => {
59
61
  const mockId = 'mock-id';
60
- vi.spyOn(sessionService, 'removeSessionGroup');
62
+ vi.spyOn(sessionService, 'removeSessionGroup').mockResolvedValueOnce(undefined);
61
63
  const spyOnRefreshSessions = vi.spyOn(useSessionStore.getState(), 'refreshSessions');
62
64
 
63
65
  const { result } = renderHook(() => useSessionStore());
@@ -75,7 +77,7 @@ describe('createSessionGroupSlice', () => {
75
77
  it('should update a session group id and refresh sessions', async () => {
76
78
  const mockSessionId = 'session-id';
77
79
  const mockGroupId = 'group-id';
78
- vi.spyOn(sessionService, 'updateSession');
80
+ vi.spyOn(sessionService, 'updateSession').mockResolvedValueOnce(undefined);
79
81
  const spyOnRefreshSessions = vi.spyOn(useSessionStore.getState(), 'refreshSessions');
80
82
 
81
83
  const { result } = renderHook(() => useSessionStore());
@@ -96,7 +98,7 @@ describe('createSessionGroupSlice', () => {
96
98
  const mockId = 'mock-id';
97
99
  const mockName = 'New Name';
98
100
  const spyOnRefreshSessions = vi.spyOn(useSessionStore.getState(), 'refreshSessions');
99
- vi.spyOn(sessionService, 'updateSessionGroup');
101
+ vi.spyOn(sessionService, 'updateSessionGroup').mockResolvedValueOnce(undefined);
100
102
 
101
103
  const { result } = renderHook(() => useSessionStore());
102
104
 
@@ -115,7 +117,7 @@ describe('createSessionGroupSlice', () => {
115
117
  { id: 'id1', sort: 0 },
116
118
  { id: 'id2', sort: 1 },
117
119
  ];
118
- vi.spyOn(sessionService, 'updateSessionGroupOrder');
120
+ vi.spyOn(sessionService, 'updateSessionGroupOrder').mockResolvedValueOnce(undefined);
119
121
  const spyOnRefreshSessions = vi.spyOn(useSessionStore.getState(), 'refreshSessions');
120
122
 
121
123
  const { result } = renderHook(() => useSessionStore());
@@ -1,8 +1,9 @@
1
1
  import { Schema, ValidationResult } from '@cfworker/json-schema';
2
- import useSWR, { SWRResponse } from 'swr';
2
+ import { SWRResponse } from 'swr';
3
3
  import { StateCreator } from 'zustand/vanilla';
4
4
 
5
5
  import { MESSAGE_CANCEL_FLAT } from '@/const/message';
6
+ import { useClientDataSWR } from '@/libs/swr';
6
7
  import { pluginService } from '@/services/plugin';
7
8
  import { merge } from '@/utils/merge';
8
9
 
@@ -17,7 +18,7 @@ export interface PluginAction {
17
18
  checkPluginsIsInstalled: (plugins: string[]) => Promise<void>;
18
19
  removeAllPlugins: () => Promise<void>;
19
20
  updatePluginSettings: <T>(id: string, settings: Partial<T>) => Promise<void>;
20
- useCheckPluginsIsInstalled: (plugins: string[]) => SWRResponse;
21
+ useCheckPluginsIsInstalled: (enable: boolean, plugins: string[]) => SWRResponse;
21
22
  validatePluginSettings: (identifier: string) => Promise<ValidationResult | undefined>;
22
23
  }
23
24
 
@@ -59,7 +60,8 @@ export const createPluginSlice: StateCreator<
59
60
 
60
61
  await get().refreshPlugins();
61
62
  },
62
- useCheckPluginsIsInstalled: (plugins) => useSWR(plugins, get().checkPluginsIsInstalled),
63
+ useCheckPluginsIsInstalled: (enable, plugins) =>
64
+ useClientDataSWR(enable ? plugins : null, get().checkPluginsIsInstalled),
63
65
  validatePluginSettings: async (identifier) => {
64
66
  const manifest = pluginSelectors.getToolManifestById(identifier)(get());
65
67
  if (!manifest || !manifest.settings) return;
@@ -27,7 +27,7 @@ export interface PluginStoreAction {
27
27
  uninstallPlugin: (identifier: string) => Promise<void>;
28
28
 
29
29
  updateInstallLoadingState: (key: string, value: boolean | undefined) => void;
30
- useFetchInstalledPlugins: () => SWRResponse<LobeTool[]>;
30
+ useFetchInstalledPlugins: (enabled: boolean) => SWRResponse<LobeTool[]>;
31
31
  useFetchPluginStore: () => SWRResponse<LobeChatPluginMeta[]>;
32
32
  }
33
33
 
@@ -90,8 +90,9 @@ export const createPluginStoreSlice: StateCreator<
90
90
  n('updateInstallLoadingState'),
91
91
  );
92
92
  },
93
- useFetchInstalledPlugins: () =>
94
- useSWR<LobeTool[]>(INSTALLED_PLUGINS, pluginService.getInstalledPlugins, {
93
+
94
+ useFetchInstalledPlugins: (enabled: boolean) =>
95
+ useSWR<LobeTool[]>(enabled ? INSTALLED_PLUGINS : null, pluginService.getInstalledPlugins, {
95
96
  fallbackData: [],
96
97
  onSuccess: (data) => {
97
98
  set(
@@ -37,7 +37,9 @@ describe('createCommonSlice', () => {
37
37
  const avatar = 'new-avatar';
38
38
 
39
39
  const spyOn = vi.spyOn(result.current, 'refreshUserState');
40
- const updateAvatarSpy = vi.spyOn(ClientService.prototype, 'updateAvatar');
40
+ const updateAvatarSpy = vi
41
+ .spyOn(ClientService.prototype, 'updateAvatar')
42
+ .mockResolvedValue(undefined);
41
43
 
42
44
  await act(async () => {
43
45
  await result.current.updateAvatar(avatar);
package/vercel.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "installCommand": "bun install"
2
+ "installCommand": "npx bun@1.1.38 install"
3
3
  }