@lobehub/chat 0.150.9 → 0.150.10
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 +25 -0
- package/package.json +1 -1
- package/src/app/chat/(desktop)/features/ChatHeader/Tags.tsx +3 -3
- package/src/app/chat/(desktop)/features/ChatInput/Footer/DragUpload.tsx +3 -3
- package/src/app/chat/(desktop)/features/ChatInput/Footer/SendMore.tsx +3 -3
- package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +3 -3
- package/src/app/chat/(desktop)/features/ChatInput/TextArea.test.tsx +5 -5
- package/src/app/chat/(desktop)/features/ChatInput/TextArea.tsx +3 -3
- package/src/app/chat/(mobile)/features/SessionHeader.tsx +3 -3
- package/src/app/chat/features/ShareButton/ShareModal.tsx +3 -3
- package/src/app/chat/features/TelemetryNotification/index.tsx +2 -2
- package/src/app/chat/features/TopicListContent/Topic/index.tsx +2 -2
- package/src/app/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +3 -3
- package/src/app/settings/(mobile)/index.tsx +3 -3
- package/src/app/settings/about/Analytics.tsx +4 -4
- package/src/app/settings/agent/Agent.tsx +4 -4
- package/src/app/settings/common/Common.tsx +4 -4
- package/src/app/settings/common/Theme.tsx +4 -4
- package/src/app/settings/features/ThemeSwatches/ThemeSwatchesNeutral.tsx +3 -3
- package/src/app/settings/features/ThemeSwatches/ThemeSwatchesPrimary.tsx +3 -3
- package/src/app/settings/hooks/useSyncSettings.ts +3 -3
- package/src/app/settings/llm/Azure/index.tsx +3 -3
- package/src/app/settings/llm/components/ProviderConfig/index.tsx +3 -3
- package/src/app/settings/llm/components/ProviderModelList/CustomModelOption.tsx +4 -4
- package/src/app/settings/llm/components/ProviderModelList/ModelConfigModal.tsx +4 -4
- package/src/app/settings/llm/components/ProviderModelList/ModelFetcher.tsx +6 -6
- package/src/app/settings/llm/components/ProviderModelList/Option.tsx +3 -3
- package/src/app/settings/llm/components/ProviderModelList/index.tsx +6 -6
- package/src/app/settings/sync/Alert.tsx +3 -3
- package/src/app/settings/sync/DeviceInfo/DeviceName.tsx +3 -3
- package/src/app/settings/sync/WebRTC/index.tsx +2 -2
- package/src/app/settings/tts/TTS/index.tsx +4 -4
- package/src/chains/__tests__/summaryAgentName.test.ts +2 -2
- package/src/chains/__tests__/summaryDescription.test.ts +2 -2
- package/src/chains/__tests__/summaryTags.test.ts +2 -2
- package/src/chains/__tests__/summaryTitle.test.ts +2 -2
- package/src/chains/summaryAgentName.ts +1 -1
- package/src/chains/summaryDescription.ts +1 -1
- package/src/chains/summaryTags.ts +1 -1
- package/src/chains/summaryTitle.ts +1 -1
- package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +3 -6
- package/src/features/AgentSetting/AgentMeta/index.tsx +3 -3
- package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +4 -4
- package/src/features/AgentSetting/AgentTTS/index.tsx +3 -3
- package/src/features/AvatarWithUpload/index.tsx +3 -3
- package/src/features/ChatInput/ActionBar/FileUpload.tsx +3 -3
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +4 -4
- package/src/features/ChatInput/ActionBar/Token/index.tsx +3 -3
- package/src/features/ChatInput/ActionBar/Tools/index.tsx +3 -3
- package/src/features/ChatInput/STT/browser.tsx +4 -4
- package/src/features/ChatInput/STT/index.tsx +3 -3
- package/src/features/ChatInput/STT/openai.tsx +4 -4
- package/src/features/ChatInput/useChatInput.ts +3 -3
- package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +3 -3
- package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +3 -3
- package/src/features/Conversation/Error/AccessCodeForm.tsx +3 -3
- package/src/features/Conversation/Extras/TTS/index.tsx +3 -3
- package/src/features/Conversation/Plugins/Render/MarkdownType/index.tsx +3 -3
- package/src/features/Conversation/components/ChatItem/index.tsx +3 -3
- package/src/features/ModelSwitchPanel/index.tsx +3 -6
- package/src/features/PluginDevModal/LocalForm.tsx +3 -3
- package/src/features/SyncStatusInspector/DisableSync.tsx +3 -3
- package/src/features/SyncStatusInspector/EnableSync.tsx +4 -4
- package/src/features/SyncStatusInspector/index.tsx +2 -2
- package/src/hooks/_header.ts +4 -4
- package/src/hooks/useSyncData.ts +3 -3
- package/src/hooks/useTTS.ts +4 -4
- package/src/layout/DefaultLayout/Desktop/SideBar/BottomActions.tsx +2 -2
- package/src/layout/DefaultLayout/Desktop/SideBar/TopActions.tsx +2 -2
- package/src/layout/DefaultLayout/Mobile/index.tsx +1 -1
- package/src/layout/GlobalProvider/AppTheme.tsx +4 -4
- package/src/layout/GlobalProvider/StoreInitialization.tsx +6 -1
- package/src/services/__tests__/chat.test.ts +17 -20
- package/src/services/__tests__/tool.test.ts +2 -2
- package/src/services/_auth.test.ts +2 -2
- package/src/services/_auth.ts +7 -7
- package/src/services/_header.ts +4 -4
- package/src/services/chat.ts +13 -13
- package/src/services/config.ts +4 -4
- package/src/services/models.ts +3 -3
- package/src/services/ollama.ts +3 -3
- package/src/services/session/client.ts +2 -2
- package/src/services/tool.ts +1 -1
- package/src/services/trace.ts +3 -3
- package/src/store/agent/slices/chat/selectors.test.ts +2 -2
- package/src/store/chat/slices/message/selectors.test.ts +1 -1
- package/src/store/chat/slices/message/selectors.ts +3 -3
- package/src/store/global/{slices/preference/action.test.ts → action.test.ts} +65 -13
- package/src/store/global/{slices/preference/action.ts → action.ts} +30 -16
- package/src/store/global/initialState.ts +58 -8
- package/src/store/global/selectors.ts +9 -8
- package/src/store/global/store.ts +3 -7
- package/src/store/market/action.ts +1 -1
- package/src/store/session/slices/session/action.ts +3 -3
- package/src/store/{global → user}/helpers.ts +2 -2
- package/src/store/user/index.ts +1 -0
- package/src/store/user/initialState.ts +11 -0
- package/src/store/user/selectors.ts +8 -0
- package/src/store/{global → user}/slices/common/action.test.ts +29 -81
- package/src/store/{global → user}/slices/common/action.ts +2 -20
- package/src/store/user/slices/common/initialState.ts +18 -0
- package/src/store/user/slices/common/selectors.ts +6 -0
- package/src/store/user/slices/preference/action.test.ts +41 -0
- package/src/store/user/slices/preference/action.ts +50 -0
- package/src/store/user/slices/preference/initialState.ts +33 -0
- package/src/store/user/slices/preference/selectors.ts +13 -0
- package/src/store/{global → user}/slices/settings/actions/general.test.ts +6 -6
- package/src/store/{global → user}/slices/settings/actions/general.ts +2 -2
- package/src/store/{global → user}/slices/settings/actions/index.ts +2 -2
- package/src/store/{global → user}/slices/settings/actions/llm.test.ts +11 -14
- package/src/store/{global → user}/slices/settings/actions/llm.ts +2 -2
- package/src/store/{global → user}/slices/settings/initialState.ts +2 -2
- package/src/store/{global → user}/slices/settings/selectors/modelConfig.test.ts +8 -8
- package/src/store/{global → user}/slices/settings/selectors/modelConfig.ts +12 -12
- package/src/store/{global → user}/slices/settings/selectors/modelProvider.test.ts +17 -17
- package/src/store/{global → user}/slices/settings/selectors/modelProvider.ts +19 -20
- package/src/store/{global → user}/slices/settings/selectors/selectors.test.ts +8 -8
- package/src/store/{global → user}/slices/settings/selectors/settings.ts +12 -12
- package/src/store/user/slices/settings/selectors/sync.ts +14 -0
- package/src/store/user/store.ts +33 -0
- package/src/tools/dalle/Render/ToolBar.tsx +3 -3
- package/src/utils/localStorage.ts +3 -1
- package/src/store/global/slices/common/initialState.ts +0 -42
- package/src/store/global/slices/common/selectors.ts +0 -6
- package/src/store/global/slices/preference/initialState.ts +0 -51
- package/src/store/global/slices/preference/selectors.ts +0 -18
- package/src/store/global/slices/settings/selectors/sync.ts +0 -14
- /package/src/store/{global → user}/slices/settings/reducers/customModelCard.test.ts +0 -0
- /package/src/store/{global → user}/slices/settings/reducers/customModelCard.ts +0 -0
- /package/src/store/{global → user}/slices/settings/selectors/__snapshots__/selectors.test.ts.snap +0 -0
- /package/src/store/{global → user}/slices/settings/selectors/index.ts +0 -0
package/src/services/models.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHeaderWithAuth } from '@/services/_auth';
|
|
2
|
-
import {
|
|
3
|
-
import { modelConfigSelectors } from '@/store/
|
|
2
|
+
import { useUserStore } from '@/store/user';
|
|
3
|
+
import { modelConfigSelectors } from '@/store/user/selectors';
|
|
4
4
|
import { ChatModelCard } from '@/types/llm';
|
|
5
5
|
|
|
6
6
|
import { API_ENDPOINTS } from './_url';
|
|
@@ -17,7 +17,7 @@ class ModelsService {
|
|
|
17
17
|
* Use browser agent runtime
|
|
18
18
|
*/
|
|
19
19
|
const enableFetchOnClient = modelConfigSelectors.isProviderFetchOnClient(provider)(
|
|
20
|
-
|
|
20
|
+
useUserStore.getState(),
|
|
21
21
|
);
|
|
22
22
|
if (enableFetchOnClient) {
|
|
23
23
|
const agentRuntime = await initializeWithClientStore(provider, {});
|
package/src/services/ollama.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { ListResponse, Ollama as OllamaBrowser, ProgressResponse } from 'ollama/
|
|
|
2
2
|
|
|
3
3
|
import { createErrorResponse } from '@/app/api/errorResponse';
|
|
4
4
|
import { ModelProvider } from '@/libs/agent-runtime';
|
|
5
|
-
import {
|
|
6
|
-
import { modelConfigSelectors } from '@/store/
|
|
5
|
+
import { useUserStore } from '@/store/user';
|
|
6
|
+
import { modelConfigSelectors } from '@/store/user/selectors';
|
|
7
7
|
import { ChatErrorType } from '@/types/fetch';
|
|
8
8
|
import { getMessageError } from '@/utils/fetch';
|
|
9
9
|
|
|
@@ -25,7 +25,7 @@ export class OllamaService {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
getHost = (): string => {
|
|
28
|
-
const config = modelConfigSelectors.ollamaConfig(
|
|
28
|
+
const config = modelConfigSelectors.ollamaConfig(useUserStore.getState());
|
|
29
29
|
|
|
30
30
|
return config.endpoint || DEFAULT_BASE_URL;
|
|
31
31
|
};
|
|
@@ -4,7 +4,7 @@ import { INBOX_SESSION_ID } from '@/const/session';
|
|
|
4
4
|
import { SessionModel } from '@/database/client/models/session';
|
|
5
5
|
import { SessionGroupModel } from '@/database/client/models/sessionGroup';
|
|
6
6
|
import { UserModel } from '@/database/client/models/user';
|
|
7
|
-
import {
|
|
7
|
+
import { useUserStore } from '@/store/user';
|
|
8
8
|
import { LobeAgentConfig } from '@/types/agent';
|
|
9
9
|
import {
|
|
10
10
|
ChatSessionList,
|
|
@@ -97,7 +97,7 @@ export class ClientService implements ISessionService {
|
|
|
97
97
|
|
|
98
98
|
async updateSessionConfig(activeId: string, config: DeepPartial<LobeAgentConfig>) {
|
|
99
99
|
if (activeId === INBOX_SESSION_ID) {
|
|
100
|
-
return
|
|
100
|
+
return useUserStore.getState().updateDefaultAgent({ config });
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
return SessionModel.updateConfig(activeId, config);
|
package/src/services/tool.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
pluginManifestSchema,
|
|
5
5
|
} from '@lobehub/chat-plugin-sdk';
|
|
6
6
|
|
|
7
|
-
import { globalHelpers } from '@/store/
|
|
7
|
+
import { globalHelpers } from '@/store/user/helpers';
|
|
8
8
|
import { OpenAIPluginManifest } from '@/types/openai/plugin';
|
|
9
9
|
|
|
10
10
|
import { API_ENDPOINTS } from './_url';
|
package/src/services/trace.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { API_ENDPOINTS } from '@/services/_url';
|
|
2
|
-
import {
|
|
3
|
-
import { preferenceSelectors } from '@/store/
|
|
2
|
+
import { useUserStore } from '@/store/user';
|
|
3
|
+
import { preferenceSelectors } from '@/store/user/selectors';
|
|
4
4
|
import { TraceEventBasePayload, TraceEventPayloads } from '@/types/trace';
|
|
5
5
|
|
|
6
6
|
class TraceService {
|
|
@@ -17,7 +17,7 @@ class TraceService {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
async traceEvent(data: TraceEventPayloads & TraceEventBasePayload) {
|
|
20
|
-
const enabled = preferenceSelectors.userAllowTrace(
|
|
20
|
+
const enabled = preferenceSelectors.userAllowTrace(useUserStore.getState());
|
|
21
21
|
|
|
22
22
|
if (!enabled) return;
|
|
23
23
|
|
|
@@ -3,8 +3,8 @@ import { describe, expect, it } from 'vitest';
|
|
|
3
3
|
import { INBOX_SESSION_ID } from '@/const/session';
|
|
4
4
|
import { DEFAULT_AGENT_CONFIG, DEFAUTT_AGENT_TTS_CONFIG } from '@/const/settings';
|
|
5
5
|
import { AgentStore } from '@/store/agent';
|
|
6
|
-
import {
|
|
7
|
-
import { settingsSelectors } from '@/store/
|
|
6
|
+
import { UserStore } from '@/store/user';
|
|
7
|
+
import { settingsSelectors } from '@/store/user/slices/settings/selectors';
|
|
8
8
|
import { LobeAgentConfig } from '@/types/agent';
|
|
9
9
|
|
|
10
10
|
import { agentSelectors } from './selectors';
|
|
@@ -6,8 +6,8 @@ import { INBOX_SESSION_ID } from '@/const/session';
|
|
|
6
6
|
import { useAgentStore } from '@/store/agent';
|
|
7
7
|
import { ChatStore } from '@/store/chat';
|
|
8
8
|
import { initialState } from '@/store/chat/initialState';
|
|
9
|
-
import { useGlobalStore } from '@/store/global';
|
|
10
9
|
import { useSessionStore } from '@/store/session';
|
|
10
|
+
import { useUserStore } from '@/store/user';
|
|
11
11
|
import { LobeAgentConfig } from '@/types/agent';
|
|
12
12
|
import { ChatMessage } from '@/types/message';
|
|
13
13
|
import { MetaData } from '@/types/meta';
|
|
@@ -5,10 +5,10 @@ import { DEFAULT_INBOX_AVATAR, DEFAULT_USER_AVATAR } from '@/const/meta';
|
|
|
5
5
|
import { INBOX_SESSION_ID } from '@/const/session';
|
|
6
6
|
import { useAgentStore } from '@/store/agent';
|
|
7
7
|
import { agentSelectors } from '@/store/agent/selectors';
|
|
8
|
-
import { useGlobalStore } from '@/store/global';
|
|
9
|
-
import { commonSelectors } from '@/store/global/selectors';
|
|
10
8
|
import { useSessionStore } from '@/store/session';
|
|
11
9
|
import { sessionMetaSelectors } from '@/store/session/selectors';
|
|
10
|
+
import { useUserStore } from '@/store/user';
|
|
11
|
+
import { commonSelectors } from '@/store/user/selectors';
|
|
12
12
|
import { ChatMessage } from '@/types/message';
|
|
13
13
|
import { MetaData } from '@/types/meta';
|
|
14
14
|
import { merge } from '@/utils/merge';
|
|
@@ -20,7 +20,7 @@ const getMeta = (message: ChatMessage) => {
|
|
|
20
20
|
switch (message.role) {
|
|
21
21
|
case 'user': {
|
|
22
22
|
return {
|
|
23
|
-
avatar: commonSelectors.userAvatar(
|
|
23
|
+
avatar: commonSelectors.userAvatar(useUserStore.getState()) || DEFAULT_USER_AVATAR,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import { act, renderHook } from '@testing-library/react';
|
|
1
|
+
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { withSWR } from '~test-utils';
|
|
3
4
|
|
|
4
|
-
import {
|
|
5
|
+
import { globalService } from '@/services/global';
|
|
6
|
+
import { useGlobalStore } from '@/store/global/index';
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
vi.mock('zustand/traditional');
|
|
9
|
+
|
|
10
|
+
vi.mock('@/utils/client/switchLang', () => ({
|
|
11
|
+
switchLang: vi.fn(),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
vi.mock('swr', async (importOriginal) => {
|
|
15
|
+
const modules = await importOriginal();
|
|
16
|
+
return {
|
|
17
|
+
...(modules as any),
|
|
18
|
+
mutate: vi.fn(),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
7
21
|
|
|
8
22
|
beforeEach(() => {
|
|
9
23
|
vi.clearAllMocks();
|
|
@@ -64,29 +78,67 @@ describe('createPreferenceSlice', () => {
|
|
|
64
78
|
});
|
|
65
79
|
});
|
|
66
80
|
|
|
67
|
-
describe('
|
|
68
|
-
it('should update
|
|
81
|
+
describe('updatePreference', () => {
|
|
82
|
+
it('should update preference', () => {
|
|
69
83
|
const { result } = renderHook(() => useGlobalStore());
|
|
70
|
-
const
|
|
84
|
+
const preference = { inputHeight: 200 };
|
|
71
85
|
|
|
72
86
|
act(() => {
|
|
73
|
-
result.current.
|
|
87
|
+
result.current.updatePreference(preference);
|
|
74
88
|
});
|
|
75
89
|
|
|
76
|
-
expect(result.current.preference.
|
|
90
|
+
expect(result.current.preference.inputHeight).toEqual(200);
|
|
77
91
|
});
|
|
78
92
|
});
|
|
79
93
|
|
|
80
|
-
describe('
|
|
81
|
-
it('should
|
|
94
|
+
describe('switchBackToChat', () => {
|
|
95
|
+
it('should switch back to chat', () => {
|
|
82
96
|
const { result } = renderHook(() => useGlobalStore());
|
|
83
|
-
const
|
|
97
|
+
const sessionId = 'session-id';
|
|
98
|
+
const router = { push: vi.fn() } as any;
|
|
84
99
|
|
|
85
100
|
act(() => {
|
|
86
|
-
|
|
101
|
+
useGlobalStore.setState({ router });
|
|
102
|
+
result.current.switchBackToChat(sessionId);
|
|
87
103
|
});
|
|
88
104
|
|
|
89
|
-
expect(
|
|
105
|
+
expect(router.push).toHaveBeenCalledWith('/chat?session=session-id');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('useCheckLatestVersion', () => {
|
|
110
|
+
it('should set hasNewVersion to false if there is no new version', async () => {
|
|
111
|
+
const latestVersion = '0.0.1';
|
|
112
|
+
|
|
113
|
+
vi.spyOn(globalService, 'getLatestVersion').mockResolvedValueOnce(latestVersion);
|
|
114
|
+
|
|
115
|
+
const { result } = renderHook(() => useGlobalStore().useCheckLatestVersion(), {
|
|
116
|
+
wrapper: withSWR,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await waitFor(() => {
|
|
120
|
+
expect(result.current.data).toBe(latestVersion);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(useGlobalStore.getState().hasNewVersion).toBeUndefined();
|
|
124
|
+
expect(useGlobalStore.getState().latestVersion).toBeUndefined();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should set hasNewVersion to true if there is a new version', async () => {
|
|
128
|
+
const latestVersion = '10000000.0.0';
|
|
129
|
+
|
|
130
|
+
vi.spyOn(globalService, 'getLatestVersion').mockResolvedValueOnce(latestVersion);
|
|
131
|
+
|
|
132
|
+
const { result } = renderHook(() => useGlobalStore().useCheckLatestVersion(), {
|
|
133
|
+
wrapper: withSWR,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await waitFor(() => {
|
|
137
|
+
expect(result.current.data).toBe(latestVersion);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(useGlobalStore.getState().hasNewVersion).toBe(true);
|
|
141
|
+
expect(useGlobalStore.getState().latestVersion).toBe(latestVersion);
|
|
90
142
|
});
|
|
91
143
|
});
|
|
92
144
|
});
|
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import { produce } from 'immer';
|
|
2
|
-
import {
|
|
2
|
+
import { gt } from 'semver';
|
|
3
|
+
import useSWR, { SWRResponse } from 'swr';
|
|
3
4
|
import type { StateCreator } from 'zustand/vanilla';
|
|
4
5
|
|
|
6
|
+
import { INBOX_SESSION_ID } from '@/const/session';
|
|
7
|
+
import { SESSION_CHAT_URL } from '@/const/url';
|
|
8
|
+
import { CURRENT_VERSION } from '@/const/version';
|
|
5
9
|
import { useClientDataSWR } from '@/libs/swr';
|
|
6
|
-
import
|
|
10
|
+
import { globalService } from '@/services/global';
|
|
11
|
+
import type { GlobalStore } from '@/store/global/index';
|
|
7
12
|
import { merge } from '@/utils/merge';
|
|
8
13
|
import { setNamespace } from '@/utils/storeDebug';
|
|
9
14
|
|
|
10
|
-
import type { GlobalPreference
|
|
15
|
+
import type { GlobalPreference } from './initialState';
|
|
11
16
|
|
|
12
17
|
const n = setNamespace('preference');
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* 设置操作
|
|
16
21
|
*/
|
|
17
|
-
export interface
|
|
22
|
+
export interface GlobalStoreAction {
|
|
23
|
+
switchBackToChat: (sessionId?: string) => void;
|
|
18
24
|
toggleChatSideBar: (visible?: boolean) => void;
|
|
19
25
|
toggleExpandSessionGroup: (id: string, expand: boolean) => void;
|
|
20
26
|
toggleMobileTopic: (visible?: boolean) => void;
|
|
21
27
|
toggleSystemRole: (visible?: boolean) => void;
|
|
22
|
-
updateGuideState: (guide: Partial<Guide>) => void;
|
|
23
28
|
updatePreference: (preference: Partial<GlobalPreference>, action?: any) => void;
|
|
24
|
-
|
|
29
|
+
useCheckLatestVersion: () => SWRResponse<string>;
|
|
30
|
+
useInitGlobalPreference: () => SWRResponse;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
export const
|
|
33
|
+
export const globalActionSlice: StateCreator<
|
|
28
34
|
GlobalStore,
|
|
29
35
|
[['zustand/devtools', never]],
|
|
30
36
|
[],
|
|
31
|
-
|
|
37
|
+
GlobalStoreAction
|
|
32
38
|
> = (set, get) => ({
|
|
39
|
+
switchBackToChat: (sessionId) => {
|
|
40
|
+
get().router?.push(SESSION_CHAT_URL(sessionId || INBOX_SESSION_ID, get().isMobile));
|
|
41
|
+
},
|
|
33
42
|
toggleChatSideBar: (newValue) => {
|
|
34
43
|
const showChatSideBar =
|
|
35
44
|
typeof newValue === 'boolean' ? newValue : !get().preference.showChatSideBar;
|
|
@@ -38,7 +47,7 @@ export const createPreferenceSlice: StateCreator<
|
|
|
38
47
|
},
|
|
39
48
|
toggleExpandSessionGroup: (id, expand) => {
|
|
40
49
|
const { preference } = get();
|
|
41
|
-
const nextExpandSessionGroup = produce(preference.expandSessionGroupKeys, (draft) => {
|
|
50
|
+
const nextExpandSessionGroup = produce(preference.expandSessionGroupKeys, (draft: string[]) => {
|
|
42
51
|
if (expand) {
|
|
43
52
|
if (draft.includes(id)) return;
|
|
44
53
|
draft.push(id);
|
|
@@ -61,11 +70,6 @@ export const createPreferenceSlice: StateCreator<
|
|
|
61
70
|
|
|
62
71
|
get().updatePreference({ showSystemRole }, n('toggleMobileTopic', newValue));
|
|
63
72
|
},
|
|
64
|
-
updateGuideState: (guide) => {
|
|
65
|
-
const { updatePreference } = get();
|
|
66
|
-
const nextGuide = merge(get().preference.guide, guide);
|
|
67
|
-
updatePreference({ guide: nextGuide });
|
|
68
|
-
},
|
|
69
73
|
updatePreference: (preference, action) => {
|
|
70
74
|
const nextPreference = merge(get().preference, preference);
|
|
71
75
|
|
|
@@ -74,9 +78,19 @@ export const createPreferenceSlice: StateCreator<
|
|
|
74
78
|
get().preferenceStorage.saveToLocalStorage(nextPreference);
|
|
75
79
|
},
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
useCheckLatestVersion: () =>
|
|
82
|
+
useSWR('checkLatestVersion', globalService.getLatestVersion, {
|
|
83
|
+
// check latest version every 30 minutes
|
|
84
|
+
focusThrottleInterval: 1000 * 60 * 30,
|
|
85
|
+
onSuccess: (data: string) => {
|
|
86
|
+
if (gt(data, CURRENT_VERSION))
|
|
87
|
+
set({ hasNewVersion: true, latestVersion: data }, false, n('checkLatestVersion'));
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
|
|
91
|
+
useInitGlobalPreference: () =>
|
|
78
92
|
useClientDataSWR<GlobalPreference>(
|
|
79
|
-
'
|
|
93
|
+
'initGlobalPreference',
|
|
80
94
|
() => get().preferenceStorage.getFromLocalStorage(),
|
|
81
95
|
{
|
|
82
96
|
onSuccess: (preference) => {
|
|
@@ -1,13 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { GlobalPreferenceState, initialPreferenceState } from './slices/preference/initialState';
|
|
3
|
-
import { GlobalSettingsState, initialSettingsState } from './slices/settings/initialState';
|
|
1
|
+
import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime';
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import { SessionDefaultGroup } from '@/types/session';
|
|
4
|
+
import { AsyncLocalStorage } from '@/utils/localStorage';
|
|
6
5
|
|
|
7
|
-
export
|
|
6
|
+
export enum SidebarTabKey {
|
|
7
|
+
Chat = 'chat',
|
|
8
|
+
Market = 'market',
|
|
9
|
+
Setting = 'settings',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum SettingsTabs {
|
|
13
|
+
About = 'about',
|
|
14
|
+
Agent = 'agent',
|
|
15
|
+
Common = 'common',
|
|
16
|
+
LLM = 'llm',
|
|
17
|
+
Sync = 'sync',
|
|
18
|
+
TTS = 'tts',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface GlobalPreference {
|
|
22
|
+
// which sessionGroup should expand
|
|
23
|
+
expandSessionGroupKeys: string[];
|
|
24
|
+
inputHeight: number;
|
|
25
|
+
mobileShowTopic?: boolean;
|
|
26
|
+
sessionsWidth: number;
|
|
27
|
+
showChatSideBar?: boolean;
|
|
28
|
+
showSessionPanel?: boolean;
|
|
29
|
+
showSystemRole?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface GlobalPreferenceState {
|
|
33
|
+
/**
|
|
34
|
+
* the user preference, which only store in local storage
|
|
35
|
+
*/
|
|
36
|
+
preference: GlobalPreference;
|
|
37
|
+
preferenceStorage: AsyncLocalStorage<GlobalPreference>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface GlobalCommonState {
|
|
41
|
+
hasNewVersion?: boolean;
|
|
42
|
+
isMobile?: boolean;
|
|
43
|
+
latestVersion?: string;
|
|
44
|
+
router?: AppRouterInstance;
|
|
45
|
+
sidebarKey: SidebarTabKey;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type GlobalState = GlobalCommonState & GlobalPreferenceState;
|
|
8
49
|
|
|
9
50
|
export const initialState: GlobalState = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
51
|
+
isMobile: false,
|
|
52
|
+
preference: {
|
|
53
|
+
expandSessionGroupKeys: [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default],
|
|
54
|
+
inputHeight: 200,
|
|
55
|
+
mobileShowTopic: false,
|
|
56
|
+
sessionsWidth: 320,
|
|
57
|
+
showChatSideBar: true,
|
|
58
|
+
showSessionPanel: true,
|
|
59
|
+
showSystemRole: false,
|
|
60
|
+
},
|
|
61
|
+
preferenceStorage: new AsyncLocalStorage('LOBE_GLOBAL_PREFERENCE'),
|
|
62
|
+
sidebarKey: SidebarTabKey.Chat,
|
|
13
63
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { GlobalStore } from '@/store/global';
|
|
2
|
+
import { SessionDefaultGroup } from '@/types/session';
|
|
3
|
+
|
|
4
|
+
const sessionGroupKeys = (s: GlobalStore): string[] =>
|
|
5
|
+
s.preference.expandSessionGroupKeys || [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default];
|
|
6
|
+
|
|
7
|
+
export const preferenceSelectors = {
|
|
8
|
+
sessionGroupKeys,
|
|
9
|
+
};
|
|
@@ -5,20 +5,16 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
5
5
|
|
|
6
6
|
import { isDev } from '@/utils/env';
|
|
7
7
|
|
|
8
|
+
import { type GlobalStoreAction, globalActionSlice } from './action';
|
|
8
9
|
import { type GlobalState, initialState } from './initialState';
|
|
9
|
-
import { type CommonAction, createCommonSlice } from './slices/common/action';
|
|
10
|
-
import { type PreferenceAction, createPreferenceSlice } from './slices/preference/action';
|
|
11
|
-
import { type SettingsAction, createSettingsSlice } from './slices/settings/actions';
|
|
12
10
|
|
|
13
11
|
// =============== 聚合 createStoreFn ============ //
|
|
14
12
|
|
|
15
|
-
export type GlobalStore =
|
|
13
|
+
export type GlobalStore = GlobalState & GlobalStoreAction;
|
|
16
14
|
|
|
17
15
|
const createStore: StateCreator<GlobalStore, [['zustand/devtools', never]]> = (...parameters) => ({
|
|
18
16
|
...initialState,
|
|
19
|
-
...
|
|
20
|
-
...createSettingsSlice(...parameters),
|
|
21
|
-
...createPreferenceSlice(...parameters),
|
|
17
|
+
...globalActionSlice(...parameters),
|
|
22
18
|
});
|
|
23
19
|
|
|
24
20
|
// =============== 实装 useStore ============ //
|
|
@@ -4,7 +4,7 @@ import useSWR, { SWRResponse } from 'swr';
|
|
|
4
4
|
import type { StateCreator } from 'zustand/vanilla';
|
|
5
5
|
|
|
6
6
|
import { marketService } from '@/services/market';
|
|
7
|
-
import { globalHelpers } from '@/store/
|
|
7
|
+
import { globalHelpers } from '@/store/user/helpers';
|
|
8
8
|
import { AgentsMarketItem, LobeChatAgentsMarketIndex } from '@/types/market';
|
|
9
9
|
|
|
10
10
|
import type { Store } from './store';
|
|
@@ -8,9 +8,9 @@ import { message } from '@/components/AntdStaticMethods';
|
|
|
8
8
|
import { DEFAULT_AGENT_LOBE_SESSION, INBOX_SESSION_ID } from '@/const/session';
|
|
9
9
|
import { useClientDataSWR } from '@/libs/swr';
|
|
10
10
|
import { sessionService } from '@/services/session';
|
|
11
|
-
import { useGlobalStore } from '@/store/global';
|
|
12
|
-
import { settingsSelectors } from '@/store/global/selectors';
|
|
13
11
|
import { SessionStore } from '@/store/session';
|
|
12
|
+
import { useUserStore } from '@/store/user';
|
|
13
|
+
import { settingsSelectors } from '@/store/user/selectors';
|
|
14
14
|
import { MetaData } from '@/types/meta';
|
|
15
15
|
import {
|
|
16
16
|
ChatSessionList,
|
|
@@ -111,7 +111,7 @@ export const createSessionSlice: StateCreator<
|
|
|
111
111
|
// merge the defaultAgent in settings
|
|
112
112
|
const defaultAgent = merge(
|
|
113
113
|
DEFAULT_AGENT_LOBE_SESSION,
|
|
114
|
-
settingsSelectors.defaultAgent(
|
|
114
|
+
settingsSelectors.defaultAgent(useUserStore.getState()),
|
|
115
115
|
);
|
|
116
116
|
|
|
117
117
|
const newSession: LobeAgentSession = merge(defaultAgent, agent);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { settingsSelectors } from './slices/settings/selectors';
|
|
2
|
-
import {
|
|
2
|
+
import { useUserStore } from './store';
|
|
3
3
|
|
|
4
|
-
const getCurrentLanguage = () => settingsSelectors.currentLanguage(
|
|
4
|
+
const getCurrentLanguage = () => settingsSelectors.currentLanguage(useUserStore.getState());
|
|
5
5
|
|
|
6
6
|
export const globalHelpers = {
|
|
7
7
|
getCurrentLanguage,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './store';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UserCommonState, initialCommonState } from './slices/common/initialState';
|
|
2
|
+
import { UserPreferenceState, initialPreferenceState } from './slices/preference/initialState';
|
|
3
|
+
import { UserSettingsState, initialSettingsState } from './slices/settings/initialState';
|
|
4
|
+
|
|
5
|
+
export type UserState = UserCommonState & UserSettingsState & UserPreferenceState;
|
|
6
|
+
|
|
7
|
+
export const initialState: UserState = {
|
|
8
|
+
...initialCommonState,
|
|
9
|
+
...initialSettingsState,
|
|
10
|
+
...initialPreferenceState,
|
|
11
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { commonSelectors } from './slices/common/selectors';
|
|
2
|
+
export { preferenceSelectors } from './slices/preference/selectors';
|
|
3
|
+
export {
|
|
4
|
+
modelConfigSelectors,
|
|
5
|
+
modelProviderSelectors,
|
|
6
|
+
settingsSelectors,
|
|
7
|
+
syncSettingsSelectors,
|
|
8
|
+
} from './slices/settings/selectors';
|