@lobehub/chat 0.150.9 → 0.151.0
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/.env.example +3 -0
- package/CHANGELOG.md +50 -0
- package/Dockerfile +3 -0
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/docs/self-hosting/environment-variables/model-provider.mdx +9 -0
- package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +9 -0
- package/docs/usage/features/multi-ai-providers.mdx +1 -0
- package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -0
- package/locales/ar/error.json +2 -0
- package/locales/ar/modelProvider.json +12 -0
- package/locales/bg-BG/error.json +2 -0
- package/locales/bg-BG/modelProvider.json +12 -0
- package/locales/de-DE/error.json +2 -0
- package/locales/de-DE/modelProvider.json +12 -0
- package/locales/en-US/error.json +2 -0
- package/locales/en-US/modelProvider.json +12 -0
- package/locales/es-ES/error.json +2 -0
- package/locales/es-ES/modelProvider.json +12 -0
- package/locales/fr-FR/error.json +2 -0
- package/locales/fr-FR/modelProvider.json +12 -0
- package/locales/it-IT/error.json +2 -0
- package/locales/it-IT/modelProvider.json +12 -0
- package/locales/ja-JP/error.json +2 -0
- package/locales/ja-JP/modelProvider.json +12 -0
- package/locales/ko-KR/error.json +2 -0
- package/locales/ko-KR/modelProvider.json +12 -0
- package/locales/nl-NL/error.json +2 -0
- package/locales/nl-NL/modelProvider.json +12 -0
- package/locales/pl-PL/error.json +2 -0
- package/locales/pl-PL/modelProvider.json +12 -0
- package/locales/pt-BR/error.json +2 -0
- package/locales/pt-BR/modelProvider.json +12 -0
- package/locales/ru-RU/error.json +2 -0
- package/locales/ru-RU/modelProvider.json +12 -0
- package/locales/tr-TR/error.json +2 -0
- package/locales/tr-TR/modelProvider.json +12 -0
- package/locales/vi-VN/error.json +2 -0
- package/locales/vi-VN/modelProvider.json +12 -0
- package/locales/zh-CN/error.json +2 -0
- package/locales/zh-CN/modelProvider.json +12 -0
- package/locales/zh-TW/error.json +2 -0
- package/locales/zh-TW/modelProvider.json +12 -0
- package/package.json +1 -1
- package/src/app/api/chat/agentRuntime.test.ts +17 -0
- package/src/app/api/chat/agentRuntime.ts +7 -0
- package/src/app/api/chat/minimax/route.test.ts +24 -0
- package/src/app/api/chat/minimax/route.ts +5 -0
- package/src/app/api/errorResponse.test.ts +6 -0
- package/src/app/api/errorResponse.ts +3 -0
- 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/Minimax/index.tsx +26 -0
- 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/llm/index.tsx +2 -0
- 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/sync/components/SystemIcon.tsx +0 -1
- 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/components/ModelIcon/index.tsx +7 -17
- package/src/components/ModelProviderIcon/index.tsx +5 -0
- package/src/components/ModelTag/ModelIcon.tsx +1 -0
- package/src/config/modelProviders/index.ts +4 -0
- package/src/config/modelProviders/minimax.ts +30 -0
- package/src/config/server/provider.ts +9 -0
- package/src/const/settings/index.ts +6 -0
- 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/APIKeyForm/ProviderAvatar.tsx +5 -0
- package/src/features/Conversation/Error/AccessCodeForm.tsx +3 -3
- package/src/features/Conversation/Error/index.tsx +1 -0
- 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/libs/agent-runtime/AgentRuntime.ts +7 -0
- package/src/libs/agent-runtime/error.ts +3 -0
- package/src/libs/agent-runtime/index.ts +1 -0
- package/src/libs/agent-runtime/minimax/index.test.ts +261 -0
- package/src/libs/agent-runtime/minimax/index.ts +185 -0
- package/src/libs/agent-runtime/togetherai/type.ts +0 -1
- package/src/libs/agent-runtime/types/type.ts +1 -0
- package/src/locales/default/error.ts +3 -0
- package/src/locales/default/modelProvider.ts +12 -0
- package/src/migrations/FromV3ToV4/types/v3.ts +1 -0
- 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 +4 -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/types/settings/modelProvider.ts +1 -0
- 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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SWRResponse } from 'swr';
|
|
2
|
+
import type { StateCreator } from 'zustand/vanilla';
|
|
3
|
+
|
|
4
|
+
import { useClientDataSWR } from '@/libs/swr';
|
|
5
|
+
import type { UserStore } from '@/store/user';
|
|
6
|
+
import { merge } from '@/utils/merge';
|
|
7
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
8
|
+
|
|
9
|
+
import type { Guide, UserPreference } from './initialState';
|
|
10
|
+
|
|
11
|
+
const n = setNamespace('preference');
|
|
12
|
+
|
|
13
|
+
export interface PreferenceAction {
|
|
14
|
+
updateGuideState: (guide: Partial<Guide>) => void;
|
|
15
|
+
updatePreference: (preference: Partial<UserPreference>, action?: any) => void;
|
|
16
|
+
useInitPreference: () => SWRResponse;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const createPreferenceSlice: StateCreator<
|
|
20
|
+
UserStore,
|
|
21
|
+
[['zustand/devtools', never]],
|
|
22
|
+
[],
|
|
23
|
+
PreferenceAction
|
|
24
|
+
> = (set, get) => ({
|
|
25
|
+
updateGuideState: (guide) => {
|
|
26
|
+
const { updatePreference } = get();
|
|
27
|
+
const nextGuide = merge(get().preference.guide, guide);
|
|
28
|
+
updatePreference({ guide: nextGuide });
|
|
29
|
+
},
|
|
30
|
+
updatePreference: (preference, action) => {
|
|
31
|
+
const nextPreference = merge(get().preference, preference);
|
|
32
|
+
|
|
33
|
+
set({ preference: nextPreference }, false, action || n('updatePreference'));
|
|
34
|
+
|
|
35
|
+
get().preferenceStorage.saveToLocalStorage(nextPreference);
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
useInitPreference: () =>
|
|
39
|
+
useClientDataSWR<UserPreference>(
|
|
40
|
+
'initUserPreference',
|
|
41
|
+
() => get().preferenceStorage.getFromLocalStorage(),
|
|
42
|
+
{
|
|
43
|
+
onSuccess: (preference) => {
|
|
44
|
+
if (preference) {
|
|
45
|
+
set({ preference }, false, n('initPreference'));
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
),
|
|
50
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from '@/utils/localStorage';
|
|
2
|
+
|
|
3
|
+
export interface Guide {
|
|
4
|
+
// Topic 引导
|
|
5
|
+
topic?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface UserPreference {
|
|
9
|
+
guide?: Guide;
|
|
10
|
+
hideSyncAlert?: boolean;
|
|
11
|
+
telemetry: boolean | null;
|
|
12
|
+
/**
|
|
13
|
+
* whether to use cmd + enter to send message
|
|
14
|
+
*/
|
|
15
|
+
useCmdEnterToSend?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UserPreferenceState {
|
|
19
|
+
/**
|
|
20
|
+
* the user preference, which only store in local storage
|
|
21
|
+
*/
|
|
22
|
+
preference: UserPreference;
|
|
23
|
+
preferenceStorage: AsyncLocalStorage<UserPreference>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const initialPreferenceState: UserPreferenceState = {
|
|
27
|
+
preference: {
|
|
28
|
+
guide: {},
|
|
29
|
+
telemetry: null,
|
|
30
|
+
useCmdEnterToSend: false,
|
|
31
|
+
},
|
|
32
|
+
preferenceStorage: new AsyncLocalStorage('LOBE_PREFERENCE'),
|
|
33
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UserStore } from '@/store/user';
|
|
2
|
+
|
|
3
|
+
const useCmdEnterToSend = (s: UserStore): boolean => s.preference.useCmdEnterToSend || false;
|
|
4
|
+
|
|
5
|
+
const userAllowTrace = (s: UserStore) => s.preference.telemetry;
|
|
6
|
+
|
|
7
|
+
const hideSyncAlert = (s: UserStore) => s.preference.hideSyncAlert;
|
|
8
|
+
|
|
9
|
+
export const preferenceSelectors = {
|
|
10
|
+
hideSyncAlert,
|
|
11
|
+
useCmdEnterToSend,
|
|
12
|
+
userAllowTrace,
|
|
13
|
+
};
|
|
@@ -5,7 +5,7 @@ import { withSWR } from '~test-utils';
|
|
|
5
5
|
|
|
6
6
|
import { DEFAULT_AGENT, DEFAULT_SETTINGS } from '@/const/settings';
|
|
7
7
|
import { userService } from '@/services/user';
|
|
8
|
-
import {
|
|
8
|
+
import { useUserStore } from '@/store/user';
|
|
9
9
|
import { LobeAgentSettings } from '@/types/session';
|
|
10
10
|
import { GlobalSettings } from '@/types/settings';
|
|
11
11
|
|
|
@@ -20,7 +20,7 @@ vi.mock('@/services/user', () => ({
|
|
|
20
20
|
describe('SettingsAction', () => {
|
|
21
21
|
describe('importAppSettings', () => {
|
|
22
22
|
it('should import app settings', async () => {
|
|
23
|
-
const { result } = renderHook(() =>
|
|
23
|
+
const { result } = renderHook(() => useUserStore());
|
|
24
24
|
const newSettings: GlobalSettings = {
|
|
25
25
|
...DEFAULT_SETTINGS,
|
|
26
26
|
themeMode: 'dark',
|
|
@@ -51,7 +51,7 @@ describe('SettingsAction', () => {
|
|
|
51
51
|
|
|
52
52
|
describe('resetSettings', () => {
|
|
53
53
|
it('should reset settings to default', async () => {
|
|
54
|
-
const { result } = renderHook(() =>
|
|
54
|
+
const { result } = renderHook(() => useUserStore());
|
|
55
55
|
|
|
56
56
|
// Perform the action
|
|
57
57
|
await act(async () => {
|
|
@@ -68,7 +68,7 @@ describe('SettingsAction', () => {
|
|
|
68
68
|
|
|
69
69
|
describe('setSettings', () => {
|
|
70
70
|
it('should set partial settings', async () => {
|
|
71
|
-
const { result } = renderHook(() =>
|
|
71
|
+
const { result } = renderHook(() => useUserStore());
|
|
72
72
|
const partialSettings: Partial<GlobalSettings> = { themeMode: 'dark' };
|
|
73
73
|
|
|
74
74
|
// Perform the action
|
|
@@ -83,7 +83,7 @@ describe('SettingsAction', () => {
|
|
|
83
83
|
|
|
84
84
|
describe('switchThemeMode', () => {
|
|
85
85
|
it('should switch theme mode', async () => {
|
|
86
|
-
const { result } = renderHook(() =>
|
|
86
|
+
const { result } = renderHook(() => useUserStore());
|
|
87
87
|
const themeMode = 'light';
|
|
88
88
|
|
|
89
89
|
// Perform the action
|
|
@@ -98,7 +98,7 @@ describe('SettingsAction', () => {
|
|
|
98
98
|
|
|
99
99
|
describe('updateDefaultAgent', () => {
|
|
100
100
|
it('should update default agent settings', async () => {
|
|
101
|
-
const { result } = renderHook(() =>
|
|
101
|
+
const { result } = renderHook(() => useUserStore());
|
|
102
102
|
const updatedAgent: Partial<LobeAgentSettings> = {
|
|
103
103
|
meta: { title: 'docs' },
|
|
104
104
|
};
|
|
@@ -4,7 +4,7 @@ import { DeepPartial } from 'utility-types';
|
|
|
4
4
|
import type { StateCreator } from 'zustand/vanilla';
|
|
5
5
|
|
|
6
6
|
import { userService } from '@/services/user';
|
|
7
|
-
import type {
|
|
7
|
+
import type { UserStore } from '@/store/user';
|
|
8
8
|
import { LobeAgentSettings } from '@/types/session';
|
|
9
9
|
import { GlobalSettings } from '@/types/settings';
|
|
10
10
|
import { difference } from '@/utils/difference';
|
|
@@ -19,7 +19,7 @@ export interface GeneralSettingsAction {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export const generalSettingsSlice: StateCreator<
|
|
22
|
-
|
|
22
|
+
UserStore,
|
|
23
23
|
[['zustand/devtools', never]],
|
|
24
24
|
[],
|
|
25
25
|
GeneralSettingsAction
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StateCreator } from 'zustand/vanilla';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { UserStore } from '@/store/user';
|
|
4
4
|
|
|
5
5
|
import { GeneralSettingsAction, generalSettingsSlice } from './general';
|
|
6
6
|
import { LLMSettingsAction, llmSettingsSlice } from './llm';
|
|
@@ -8,7 +8,7 @@ import { LLMSettingsAction, llmSettingsSlice } from './llm';
|
|
|
8
8
|
export interface SettingsAction extends LLMSettingsAction, GeneralSettingsAction {}
|
|
9
9
|
|
|
10
10
|
export const createSettingsSlice: StateCreator<
|
|
11
|
-
|
|
11
|
+
UserStore,
|
|
12
12
|
[['zustand/devtools', never]],
|
|
13
13
|
[],
|
|
14
14
|
SettingsAction
|
|
@@ -2,16 +2,13 @@ import { act, renderHook } from '@testing-library/react';
|
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
3
|
|
|
4
4
|
import { userService } from '@/services/user';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
GlobalSettingsState,
|
|
8
|
-
initialSettingsState,
|
|
9
|
-
} from '@/store/global/slices/settings/initialState';
|
|
5
|
+
import { UserStore, useUserStore } from '@/store/user';
|
|
6
|
+
import { UserSettingsState, initialSettingsState } from '@/store/user/slices/settings/initialState';
|
|
10
7
|
import {
|
|
11
8
|
modelConfigSelectors,
|
|
12
9
|
modelProviderSelectors,
|
|
13
10
|
settingsSelectors,
|
|
14
|
-
} from '@/store/
|
|
11
|
+
} from '@/store/user/slices/settings/selectors';
|
|
15
12
|
import { GeneralModelProviderConfig } from '@/types/settings';
|
|
16
13
|
import { merge } from '@/utils/merge';
|
|
17
14
|
|
|
@@ -28,7 +25,7 @@ vi.mock('@/services/user', () => ({
|
|
|
28
25
|
describe('LLMSettingsSliceAction', () => {
|
|
29
26
|
describe('setModelProviderConfig', () => {
|
|
30
27
|
it('should set OpenAI configuration', async () => {
|
|
31
|
-
const { result } = renderHook(() =>
|
|
28
|
+
const { result } = renderHook(() => useUserStore());
|
|
32
29
|
const openAIConfig: Partial<GeneralModelProviderConfig> = { apiKey: 'test-key' };
|
|
33
30
|
|
|
34
31
|
// Perform the action
|
|
@@ -47,7 +44,7 @@ describe('LLMSettingsSliceAction', () => {
|
|
|
47
44
|
|
|
48
45
|
describe('dispatchCustomModelCards', () => {
|
|
49
46
|
it('should return early when prevState does not exist', async () => {
|
|
50
|
-
const { result } = renderHook(() =>
|
|
47
|
+
const { result } = renderHook(() => useUserStore());
|
|
51
48
|
const provider = 'openai';
|
|
52
49
|
const payload: CustomModelCardDispatch = { type: 'add', modelCard: { id: 'test-id' } };
|
|
53
50
|
|
|
@@ -66,10 +63,10 @@ describe('LLMSettingsSliceAction', () => {
|
|
|
66
63
|
|
|
67
64
|
describe('refreshDefaultModelProviderList', () => {
|
|
68
65
|
it('default', async () => {
|
|
69
|
-
const { result } = renderHook(() =>
|
|
66
|
+
const { result } = renderHook(() => useUserStore());
|
|
70
67
|
|
|
71
68
|
act(() => {
|
|
72
|
-
|
|
69
|
+
useUserStore.setState({
|
|
73
70
|
serverConfig: {
|
|
74
71
|
languageModel: {
|
|
75
72
|
azure: { serverModelCards: [{ id: 'abc', deploymentName: 'abc' }] },
|
|
@@ -91,9 +88,9 @@ describe('LLMSettingsSliceAction', () => {
|
|
|
91
88
|
|
|
92
89
|
describe('refreshModelProviderList', () => {
|
|
93
90
|
it('visible', async () => {
|
|
94
|
-
const { result } = renderHook(() =>
|
|
91
|
+
const { result } = renderHook(() => useUserStore());
|
|
95
92
|
act(() => {
|
|
96
|
-
|
|
93
|
+
useUserStore.setState({
|
|
97
94
|
settings: {
|
|
98
95
|
languageModel: {
|
|
99
96
|
ollama: { enabledModels: ['llava'] },
|
|
@@ -118,10 +115,10 @@ describe('LLMSettingsSliceAction', () => {
|
|
|
118
115
|
});
|
|
119
116
|
|
|
120
117
|
it('modelProviderListForModelSelect should return only enabled providers', () => {
|
|
121
|
-
const { result } = renderHook(() =>
|
|
118
|
+
const { result } = renderHook(() => useUserStore());
|
|
122
119
|
|
|
123
120
|
act(() => {
|
|
124
|
-
|
|
121
|
+
useUserStore.setState({
|
|
125
122
|
settings: {
|
|
126
123
|
languageModel: {
|
|
127
124
|
perplexity: { enabled: true },
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
BedrockProviderCard,
|
|
8
8
|
GoogleProviderCard,
|
|
9
9
|
GroqProviderCard,
|
|
10
|
+
MinimaxProviderCard,
|
|
10
11
|
MistralProviderCard,
|
|
11
12
|
MoonshotProviderCard,
|
|
12
13
|
OllamaProviderCard,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
ZeroOneProviderCard,
|
|
18
19
|
ZhiPuProviderCard,
|
|
19
20
|
} from '@/config/modelProviders';
|
|
20
|
-
import {
|
|
21
|
+
import { UserStore } from '@/store/user';
|
|
21
22
|
import { ChatModelCard } from '@/types/llm';
|
|
22
23
|
import { GlobalLLMConfig, GlobalLLMProviderKey } from '@/types/settings';
|
|
23
24
|
import { setNamespace } from '@/utils/storeDebug';
|
|
@@ -57,7 +58,7 @@ export interface LLMSettingsAction {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export const llmSettingsSlice: StateCreator<
|
|
60
|
-
|
|
61
|
+
UserStore,
|
|
61
62
|
[['zustand/devtools', never]],
|
|
62
63
|
[],
|
|
63
64
|
LLMSettingsAction
|
|
@@ -109,6 +110,7 @@ export const llmSettingsSlice: StateCreator<
|
|
|
109
110
|
},
|
|
110
111
|
BedrockProviderCard,
|
|
111
112
|
PerplexityProviderCard,
|
|
113
|
+
MinimaxProviderCard,
|
|
112
114
|
MistralProviderCard,
|
|
113
115
|
GroqProviderCard,
|
|
114
116
|
MoonshotProviderCard,
|
|
@@ -6,7 +6,7 @@ import { ModelProviderCard } from '@/types/llm';
|
|
|
6
6
|
import { GlobalServerConfig } from '@/types/serverConfig';
|
|
7
7
|
import { GlobalSettings } from '@/types/settings';
|
|
8
8
|
|
|
9
|
-
export interface
|
|
9
|
+
export interface UserSettingsState {
|
|
10
10
|
avatar?: string;
|
|
11
11
|
defaultModelProviderList: ModelProviderCard[];
|
|
12
12
|
defaultSettings: GlobalSettings;
|
|
@@ -17,7 +17,7 @@ export interface GlobalSettingsState {
|
|
|
17
17
|
userId?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export const initialSettingsState:
|
|
20
|
+
export const initialSettingsState: UserSettingsState = {
|
|
21
21
|
defaultModelProviderList: DEFAULT_MODEL_PROVIDER_LIST,
|
|
22
22
|
defaultSettings: DEFAULT_SETTINGS,
|
|
23
23
|
modelProviderList: DEFAULT_MODEL_PROVIDER_LIST,
|
|
@@ -2,8 +2,8 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
|
|
3
3
|
import { merge } from '@/utils/merge';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { UserStore, useUserStore } from '../../../store';
|
|
6
|
+
import { UserSettingsState, initialSettingsState } from '../initialState';
|
|
7
7
|
import { modelConfigSelectors } from './modelConfig';
|
|
8
8
|
|
|
9
9
|
describe('modelConfigSelectors', () => {
|
|
@@ -15,7 +15,7 @@ describe('modelConfigSelectors', () => {
|
|
|
15
15
|
ollama: { enabled: true },
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
|
-
} as
|
|
18
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
19
19
|
|
|
20
20
|
expect(modelConfigSelectors.isProviderEnabled('ollama')(s)).toBe(true);
|
|
21
21
|
});
|
|
@@ -27,7 +27,7 @@ describe('modelConfigSelectors', () => {
|
|
|
27
27
|
perplexity: { enabled: false },
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
|
-
} as
|
|
30
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
31
31
|
|
|
32
32
|
expect(modelConfigSelectors.isProviderEnabled('perplexity')(s)).toBe(false);
|
|
33
33
|
});
|
|
@@ -46,7 +46,7 @@ describe('modelConfigSelectors', () => {
|
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
|
-
} as
|
|
49
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
50
50
|
|
|
51
51
|
const customModelCard = modelConfigSelectors.getCustomModelCard({
|
|
52
52
|
id: 'custom-model-2',
|
|
@@ -65,7 +65,7 @@ describe('modelConfigSelectors', () => {
|
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
67
|
},
|
|
68
|
-
} as
|
|
68
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
69
69
|
|
|
70
70
|
const customModelCard = modelConfigSelectors.getCustomModelCard({
|
|
71
71
|
id: 'nonexistent-model',
|
|
@@ -93,7 +93,7 @@ describe('modelConfigSelectors', () => {
|
|
|
93
93
|
id: 'custom-model-2',
|
|
94
94
|
provider: 'perplexity',
|
|
95
95
|
},
|
|
96
|
-
} as
|
|
96
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
97
97
|
|
|
98
98
|
const currentEditingModelCard = modelConfigSelectors.currentEditingCustomModelCard(s);
|
|
99
99
|
|
|
@@ -112,7 +112,7 @@ describe('modelConfigSelectors', () => {
|
|
|
112
112
|
},
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
|
-
} as
|
|
115
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
116
116
|
|
|
117
117
|
const currentEditingModelCard = modelConfigSelectors.currentEditingCustomModelCard(s);
|
|
118
118
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { GlobalLLMProviderKey } from '@/types/settings';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { UserStore } from '../../../store';
|
|
4
4
|
import { currentLLMSettings, getProviderConfigById } from './settings';
|
|
5
5
|
|
|
6
|
-
const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s:
|
|
6
|
+
const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: UserStore) =>
|
|
7
7
|
getProviderConfigById(provider)(s)?.enabled || false;
|
|
8
8
|
|
|
9
|
-
const isProviderEndpointNotEmpty = (provider: GlobalLLMProviderKey | string) => (s:
|
|
9
|
+
const isProviderEndpointNotEmpty = (provider: GlobalLLMProviderKey | string) => (s: UserStore) =>
|
|
10
10
|
!!getProviderConfigById(provider)(s)?.endpoint;
|
|
11
11
|
|
|
12
|
-
const isProviderFetchOnClient = (provider: GlobalLLMProviderKey | string) => (s:
|
|
12
|
+
const isProviderFetchOnClient = (provider: GlobalLLMProviderKey | string) => (s: UserStore) => {
|
|
13
13
|
const config = getProviderConfigById(provider)(s);
|
|
14
14
|
if (typeof config?.fetchOnClient !== 'undefined') return config?.fetchOnClient;
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ const isProviderFetchOnClient = (provider: GlobalLLMProviderKey | string) => (s:
|
|
|
18
18
|
|
|
19
19
|
const getCustomModelCard =
|
|
20
20
|
({ id, provider }: { id?: string; provider?: string }) =>
|
|
21
|
-
(s:
|
|
21
|
+
(s: UserStore) => {
|
|
22
22
|
if (!provider) return;
|
|
23
23
|
|
|
24
24
|
const config = getProviderConfigById(provider)(s);
|
|
@@ -26,7 +26,7 @@ const getCustomModelCard =
|
|
|
26
26
|
return config?.customModelCards?.find((m) => m.id === id);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const currentEditingCustomModelCard = (s:
|
|
29
|
+
const currentEditingCustomModelCard = (s: UserStore) => {
|
|
30
30
|
if (!s.editingCustomCardModel) return;
|
|
31
31
|
const { id, provider } = s.editingCustomCardModel;
|
|
32
32
|
|
|
@@ -35,16 +35,16 @@ const currentEditingCustomModelCard = (s: GlobalStore) => {
|
|
|
35
35
|
|
|
36
36
|
const isAutoFetchModelsEnabled =
|
|
37
37
|
(provider: GlobalLLMProviderKey) =>
|
|
38
|
-
(s:
|
|
38
|
+
(s: UserStore): boolean => {
|
|
39
39
|
return getProviderConfigById(provider)(s)?.autoFetchModelLists || false;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const openAIConfig = (s:
|
|
43
|
-
const bedrockConfig = (s:
|
|
44
|
-
const ollamaConfig = (s:
|
|
45
|
-
const azureConfig = (s:
|
|
42
|
+
const openAIConfig = (s: UserStore) => currentLLMSettings(s).openai;
|
|
43
|
+
const bedrockConfig = (s: UserStore) => currentLLMSettings(s).bedrock;
|
|
44
|
+
const ollamaConfig = (s: UserStore) => currentLLMSettings(s).ollama;
|
|
45
|
+
const azureConfig = (s: UserStore) => currentLLMSettings(s).azure;
|
|
46
46
|
|
|
47
|
-
const isAzureEnabled = (s:
|
|
47
|
+
const isAzureEnabled = (s: UserStore) => currentLLMSettings(s).azure.enabled;
|
|
48
48
|
|
|
49
49
|
export const modelConfigSelectors = {
|
|
50
50
|
azureConfig,
|
|
@@ -2,21 +2,21 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
|
|
3
3
|
import { merge } from '@/utils/merge';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { UserStore, useUserStore } from '../../../store';
|
|
6
|
+
import { UserSettingsState, initialSettingsState } from '../initialState';
|
|
7
7
|
import { getDefaultModeProviderById, modelProviderSelectors } from './modelProvider';
|
|
8
8
|
|
|
9
9
|
describe('modelProviderSelectors', () => {
|
|
10
10
|
describe('getDefaultModeProviderById', () => {
|
|
11
11
|
it('should return the correct ModelProviderCard when provider ID matches', () => {
|
|
12
|
-
const s = merge(initialSettingsState, {}) as unknown as
|
|
12
|
+
const s = merge(initialSettingsState, {}) as unknown as UserStore;
|
|
13
13
|
|
|
14
14
|
const result = getDefaultModeProviderById('openai')(s);
|
|
15
15
|
expect(result).not.toBeUndefined();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
it('should return undefined when provider ID does not exist', () => {
|
|
19
|
-
const s = merge(initialSettingsState, {}) as unknown as
|
|
19
|
+
const s = merge(initialSettingsState, {}) as unknown as UserStore;
|
|
20
20
|
const result = getDefaultModeProviderById('nonExistingProvider')(s);
|
|
21
21
|
expect(result).toBeUndefined();
|
|
22
22
|
});
|
|
@@ -32,7 +32,7 @@ describe('modelProviderSelectors', () => {
|
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
|
-
} as
|
|
35
|
+
} as UserSettingsState) as unknown as UserStore;
|
|
36
36
|
|
|
37
37
|
const modelCards = modelProviderSelectors.getModelCardsById('perplexity')(s);
|
|
38
38
|
|
|
@@ -46,14 +46,14 @@ describe('modelProviderSelectors', () => {
|
|
|
46
46
|
|
|
47
47
|
describe('defaultEnabledProviderModels', () => {
|
|
48
48
|
it('should return enabled models for a given provider', () => {
|
|
49
|
-
const s = merge(initialSettingsState, {}) as unknown as
|
|
49
|
+
const s = merge(initialSettingsState, {}) as unknown as UserStore;
|
|
50
50
|
|
|
51
51
|
const result = modelProviderSelectors.getDefaultEnabledModelsById('openai')(s);
|
|
52
52
|
expect(result).toEqual(['gpt-3.5-turbo', 'gpt-4-turbo']);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it('should return undefined for a non-existing provider', () => {
|
|
56
|
-
const s = merge(initialSettingsState, {}) as unknown as
|
|
56
|
+
const s = merge(initialSettingsState, {}) as unknown as UserStore;
|
|
57
57
|
|
|
58
58
|
const result = modelProviderSelectors.getDefaultEnabledModelsById('nonExistingProvider')(s);
|
|
59
59
|
expect(result).toBeUndefined();
|
|
@@ -62,14 +62,14 @@ describe('modelProviderSelectors', () => {
|
|
|
62
62
|
describe('modelEnabledVision', () => {
|
|
63
63
|
it('should return true if the model has vision ability', () => {
|
|
64
64
|
const hasAbility = modelProviderSelectors.isModelEnabledVision('gpt-4-vision-preview')(
|
|
65
|
-
|
|
65
|
+
useUserStore.getState(),
|
|
66
66
|
);
|
|
67
67
|
expect(hasAbility).toBeTruthy();
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it('should return false if the model does not have vision ability', () => {
|
|
71
71
|
const hasAbility = modelProviderSelectors.isModelEnabledVision('some-other-model')(
|
|
72
|
-
|
|
72
|
+
useUserStore.getState(),
|
|
73
73
|
);
|
|
74
74
|
|
|
75
75
|
expect(hasAbility).toBeFalsy();
|
|
@@ -77,7 +77,7 @@ describe('modelProviderSelectors', () => {
|
|
|
77
77
|
|
|
78
78
|
it('should return false if the model include vision in id', () => {
|
|
79
79
|
const hasAbility = modelProviderSelectors.isModelEnabledVision('some-other-model-vision')(
|
|
80
|
-
|
|
80
|
+
useUserStore.getState(),
|
|
81
81
|
);
|
|
82
82
|
|
|
83
83
|
expect(hasAbility).toBeTruthy();
|
|
@@ -87,14 +87,14 @@ describe('modelProviderSelectors', () => {
|
|
|
87
87
|
describe('modelEnabledFiles', () => {
|
|
88
88
|
it('should return false if the model does not have file ability', () => {
|
|
89
89
|
const enabledFiles = modelProviderSelectors.isModelEnabledFiles('gpt-4-vision-preview')(
|
|
90
|
-
|
|
90
|
+
useUserStore.getState(),
|
|
91
91
|
);
|
|
92
92
|
expect(enabledFiles).toBeFalsy();
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
it.skip('should return true if the model has file ability', () => {
|
|
96
96
|
const enabledFiles = modelProviderSelectors.isModelEnabledFiles('gpt-4-all')(
|
|
97
|
-
|
|
97
|
+
useUserStore.getState(),
|
|
98
98
|
);
|
|
99
99
|
expect(enabledFiles).toBeTruthy();
|
|
100
100
|
});
|
|
@@ -103,14 +103,14 @@ describe('modelProviderSelectors', () => {
|
|
|
103
103
|
describe('modelHasMaxToken', () => {
|
|
104
104
|
it('should return true if the model is in the list of models that show tokens', () => {
|
|
105
105
|
const show = modelProviderSelectors.isModelHasMaxToken('gpt-3.5-turbo')(
|
|
106
|
-
|
|
106
|
+
useUserStore.getState(),
|
|
107
107
|
);
|
|
108
108
|
expect(show).toBeTruthy();
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
it('should return false if the model is not in the list of models that show tokens', () => {
|
|
112
112
|
const show = modelProviderSelectors.isModelHasMaxToken('some-other-model')(
|
|
113
|
-
|
|
113
|
+
useUserStore.getState(),
|
|
114
114
|
);
|
|
115
115
|
expect(show).toBe(false);
|
|
116
116
|
});
|
|
@@ -119,7 +119,7 @@ describe('modelProviderSelectors', () => {
|
|
|
119
119
|
describe('modelMaxToken', () => {
|
|
120
120
|
it('should return the correct token count for a model with specified tokens', () => {
|
|
121
121
|
const model1Tokens = modelProviderSelectors.modelMaxToken('gpt-3.5-turbo')(
|
|
122
|
-
|
|
122
|
+
useUserStore.getState(),
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
expect(model1Tokens).toEqual(16385);
|
|
@@ -128,7 +128,7 @@ describe('modelProviderSelectors', () => {
|
|
|
128
128
|
it('should return 0 for a model without a specified token count', () => {
|
|
129
129
|
// 测试未指定tokens属性的模型的tokens值,期望为0
|
|
130
130
|
const tokens = modelProviderSelectors.modelMaxToken('chat-bison-001')(
|
|
131
|
-
|
|
131
|
+
useUserStore.getState(),
|
|
132
132
|
);
|
|
133
133
|
expect(tokens).toEqual(0);
|
|
134
134
|
});
|
|
@@ -136,7 +136,7 @@ describe('modelProviderSelectors', () => {
|
|
|
136
136
|
it('should return 0 for a non-existing model', () => {
|
|
137
137
|
// 测试一个不存在的模型的tokens值,期望为0
|
|
138
138
|
const tokens = modelProviderSelectors.modelMaxToken('nonExistingModel')(
|
|
139
|
-
|
|
139
|
+
useUserStore.getState(),
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
expect(tokens).toEqual(0);
|