@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.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/docs/self-hosting/environment-variables/model-provider.mdx +7 -0
- package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +7 -0
- package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +12 -12
- package/package.json +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +3 -9
- package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +2 -4
- package/src/app/(main)/chat/@session/features/SessionListContent/DefaultMode.tsx +2 -5
- package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InstallPlugin.tsx +10 -15
- package/src/database/repositories/dataImporter/__tests__/index.test.ts +11 -18
- package/src/database/repositories/dataImporter/index.ts +31 -46
- package/src/database/server/models/__tests__/_test_template.ts +1 -1
- package/src/database/server/models/__tests__/agent.test.ts +1 -1
- package/src/database/server/models/__tests__/asyncTask.test.ts +1 -1
- package/src/database/server/models/__tests__/chunk.test.ts +1 -1
- package/src/database/server/models/__tests__/file.test.ts +1 -1
- package/src/database/server/models/__tests__/knowledgeBase.test.ts +1 -2
- package/src/database/server/models/__tests__/message.test.ts +35 -72
- package/src/database/server/models/__tests__/nextauth.test.ts +1 -1
- package/src/database/server/models/__tests__/session.test.ts +1 -1
- package/src/database/server/models/__tests__/sessionGroup.test.ts +1 -2
- package/src/database/server/models/__tests__/topic.test.ts +1 -1
- package/src/database/server/models/__tests__/user.test.ts +1 -1
- package/src/database/server/models/_template.ts +2 -2
- package/src/database/server/models/agent.ts +17 -25
- package/src/database/server/models/asyncTask.ts +2 -2
- package/src/database/server/models/chunk.ts +14 -14
- package/src/database/server/models/embedding.ts +1 -1
- package/src/database/server/models/file.ts +8 -10
- package/src/database/server/models/knowledgeBase.ts +4 -6
- package/src/database/server/models/message.ts +54 -65
- package/src/database/server/models/plugin.ts +6 -2
- package/src/database/server/models/ragEval/dataset.ts +2 -2
- package/src/database/server/models/ragEval/datasetRecord.ts +3 -8
- package/src/database/server/models/ragEval/evaluation.ts +3 -2
- package/src/database/server/models/ragEval/evaluationRecord.ts +2 -2
- package/src/database/server/models/session.ts +40 -35
- package/src/database/server/models/sessionGroup.ts +4 -4
- package/src/database/server/models/thread.ts +2 -2
- package/src/database/server/models/topic.ts +48 -53
- package/src/database/server/models/user.ts +12 -12
- package/src/features/AgentSetting/AgentPlugin/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Tools/Dropdown.tsx +4 -4
- package/src/features/Portal/Thread/Chat/ChatList.tsx +1 -2
- package/src/hooks/useCheckPluginsIsInstalled.ts +10 -0
- package/src/hooks/useFetchInstalledPlugins.ts +10 -0
- package/src/hooks/useFetchMessages.ts +15 -0
- package/src/hooks/useFetchSessions.ts +13 -0
- package/src/hooks/useFetchThreads.ts +11 -0
- package/src/hooks/useFetchTopics.ts +6 -6
- package/src/layout/GlobalProvider/StoreInitialization.tsx +3 -1
- package/src/libs/agent-runtime/utils/streams/azureOpenai.test.ts +0 -1
- package/src/libs/next-auth/adapter/index.ts +1 -1
- package/src/server/routers/lambda/chunk.ts +2 -2
- package/src/services/user/client.ts +2 -2
- package/src/store/agent/slices/chat/action.test.ts +21 -10
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +10 -0
- package/src/store/chat/slices/builtinTool/action.ts +0 -1
- package/src/store/chat/slices/message/action.test.ts +3 -1
- package/src/store/chat/slices/message/action.ts +7 -3
- package/src/store/chat/slices/thread/action.ts +3 -3
- package/src/store/chat/slices/topic/action.test.ts +1 -1
- package/src/store/chat/slices/topic/action.ts +3 -3
- package/src/store/global/selectors.ts +6 -0
- package/src/store/session/slices/session/action.ts +6 -3
- package/src/store/session/slices/sessionGroup/action.test.ts +8 -6
- package/src/store/tool/slices/plugin/action.ts +5 -3
- package/src/store/tool/slices/store/action.ts +4 -3
- package/src/store/user/slices/common/action.test.ts +3 -1
- 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: (
|
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
|
-
|
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(
|
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
|
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) =>
|
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
|
-
|
94
|
-
|
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
|
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