@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.
Files changed (202) hide show
  1. package/.env.example +3 -0
  2. package/CHANGELOG.md +50 -0
  3. package/Dockerfile +3 -0
  4. package/README.md +1 -0
  5. package/README.zh-CN.md +1 -0
  6. package/docs/self-hosting/environment-variables/model-provider.mdx +9 -0
  7. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +9 -0
  8. package/docs/usage/features/multi-ai-providers.mdx +1 -0
  9. package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -0
  10. package/locales/ar/error.json +2 -0
  11. package/locales/ar/modelProvider.json +12 -0
  12. package/locales/bg-BG/error.json +2 -0
  13. package/locales/bg-BG/modelProvider.json +12 -0
  14. package/locales/de-DE/error.json +2 -0
  15. package/locales/de-DE/modelProvider.json +12 -0
  16. package/locales/en-US/error.json +2 -0
  17. package/locales/en-US/modelProvider.json +12 -0
  18. package/locales/es-ES/error.json +2 -0
  19. package/locales/es-ES/modelProvider.json +12 -0
  20. package/locales/fr-FR/error.json +2 -0
  21. package/locales/fr-FR/modelProvider.json +12 -0
  22. package/locales/it-IT/error.json +2 -0
  23. package/locales/it-IT/modelProvider.json +12 -0
  24. package/locales/ja-JP/error.json +2 -0
  25. package/locales/ja-JP/modelProvider.json +12 -0
  26. package/locales/ko-KR/error.json +2 -0
  27. package/locales/ko-KR/modelProvider.json +12 -0
  28. package/locales/nl-NL/error.json +2 -0
  29. package/locales/nl-NL/modelProvider.json +12 -0
  30. package/locales/pl-PL/error.json +2 -0
  31. package/locales/pl-PL/modelProvider.json +12 -0
  32. package/locales/pt-BR/error.json +2 -0
  33. package/locales/pt-BR/modelProvider.json +12 -0
  34. package/locales/ru-RU/error.json +2 -0
  35. package/locales/ru-RU/modelProvider.json +12 -0
  36. package/locales/tr-TR/error.json +2 -0
  37. package/locales/tr-TR/modelProvider.json +12 -0
  38. package/locales/vi-VN/error.json +2 -0
  39. package/locales/vi-VN/modelProvider.json +12 -0
  40. package/locales/zh-CN/error.json +2 -0
  41. package/locales/zh-CN/modelProvider.json +12 -0
  42. package/locales/zh-TW/error.json +2 -0
  43. package/locales/zh-TW/modelProvider.json +12 -0
  44. package/package.json +1 -1
  45. package/src/app/api/chat/agentRuntime.test.ts +17 -0
  46. package/src/app/api/chat/agentRuntime.ts +7 -0
  47. package/src/app/api/chat/minimax/route.test.ts +24 -0
  48. package/src/app/api/chat/minimax/route.ts +5 -0
  49. package/src/app/api/errorResponse.test.ts +6 -0
  50. package/src/app/api/errorResponse.ts +3 -0
  51. package/src/app/chat/(desktop)/features/ChatHeader/Tags.tsx +3 -3
  52. package/src/app/chat/(desktop)/features/ChatInput/Footer/DragUpload.tsx +3 -3
  53. package/src/app/chat/(desktop)/features/ChatInput/Footer/SendMore.tsx +3 -3
  54. package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +3 -3
  55. package/src/app/chat/(desktop)/features/ChatInput/TextArea.test.tsx +5 -5
  56. package/src/app/chat/(desktop)/features/ChatInput/TextArea.tsx +3 -3
  57. package/src/app/chat/(mobile)/features/SessionHeader.tsx +3 -3
  58. package/src/app/chat/features/ShareButton/ShareModal.tsx +3 -3
  59. package/src/app/chat/features/TelemetryNotification/index.tsx +2 -2
  60. package/src/app/chat/features/TopicListContent/Topic/index.tsx +2 -2
  61. package/src/app/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +3 -3
  62. package/src/app/settings/(mobile)/index.tsx +3 -3
  63. package/src/app/settings/about/Analytics.tsx +4 -4
  64. package/src/app/settings/agent/Agent.tsx +4 -4
  65. package/src/app/settings/common/Common.tsx +4 -4
  66. package/src/app/settings/common/Theme.tsx +4 -4
  67. package/src/app/settings/features/ThemeSwatches/ThemeSwatchesNeutral.tsx +3 -3
  68. package/src/app/settings/features/ThemeSwatches/ThemeSwatchesPrimary.tsx +3 -3
  69. package/src/app/settings/hooks/useSyncSettings.ts +3 -3
  70. package/src/app/settings/llm/Azure/index.tsx +3 -3
  71. package/src/app/settings/llm/Minimax/index.tsx +26 -0
  72. package/src/app/settings/llm/components/ProviderConfig/index.tsx +3 -3
  73. package/src/app/settings/llm/components/ProviderModelList/CustomModelOption.tsx +4 -4
  74. package/src/app/settings/llm/components/ProviderModelList/ModelConfigModal.tsx +4 -4
  75. package/src/app/settings/llm/components/ProviderModelList/ModelFetcher.tsx +6 -6
  76. package/src/app/settings/llm/components/ProviderModelList/Option.tsx +3 -3
  77. package/src/app/settings/llm/components/ProviderModelList/index.tsx +6 -6
  78. package/src/app/settings/llm/index.tsx +2 -0
  79. package/src/app/settings/sync/Alert.tsx +3 -3
  80. package/src/app/settings/sync/DeviceInfo/DeviceName.tsx +3 -3
  81. package/src/app/settings/sync/WebRTC/index.tsx +2 -2
  82. package/src/app/settings/sync/components/SystemIcon.tsx +0 -1
  83. package/src/app/settings/tts/TTS/index.tsx +4 -4
  84. package/src/chains/__tests__/summaryAgentName.test.ts +2 -2
  85. package/src/chains/__tests__/summaryDescription.test.ts +2 -2
  86. package/src/chains/__tests__/summaryTags.test.ts +2 -2
  87. package/src/chains/__tests__/summaryTitle.test.ts +2 -2
  88. package/src/chains/summaryAgentName.ts +1 -1
  89. package/src/chains/summaryDescription.ts +1 -1
  90. package/src/chains/summaryTags.ts +1 -1
  91. package/src/chains/summaryTitle.ts +1 -1
  92. package/src/components/ModelIcon/index.tsx +7 -17
  93. package/src/components/ModelProviderIcon/index.tsx +5 -0
  94. package/src/components/ModelTag/ModelIcon.tsx +1 -0
  95. package/src/config/modelProviders/index.ts +4 -0
  96. package/src/config/modelProviders/minimax.ts +30 -0
  97. package/src/config/server/provider.ts +9 -0
  98. package/src/const/settings/index.ts +6 -0
  99. package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +3 -6
  100. package/src/features/AgentSetting/AgentMeta/index.tsx +3 -3
  101. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +4 -4
  102. package/src/features/AgentSetting/AgentTTS/index.tsx +3 -3
  103. package/src/features/AvatarWithUpload/index.tsx +3 -3
  104. package/src/features/ChatInput/ActionBar/FileUpload.tsx +3 -3
  105. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +4 -4
  106. package/src/features/ChatInput/ActionBar/Token/index.tsx +3 -3
  107. package/src/features/ChatInput/ActionBar/Tools/index.tsx +3 -3
  108. package/src/features/ChatInput/STT/browser.tsx +4 -4
  109. package/src/features/ChatInput/STT/index.tsx +3 -3
  110. package/src/features/ChatInput/STT/openai.tsx +4 -4
  111. package/src/features/ChatInput/useChatInput.ts +3 -3
  112. package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +3 -3
  113. package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +3 -3
  114. package/src/features/Conversation/Error/APIKeyForm/ProviderAvatar.tsx +5 -0
  115. package/src/features/Conversation/Error/AccessCodeForm.tsx +3 -3
  116. package/src/features/Conversation/Error/index.tsx +1 -0
  117. package/src/features/Conversation/Extras/TTS/index.tsx +3 -3
  118. package/src/features/Conversation/Plugins/Render/MarkdownType/index.tsx +3 -3
  119. package/src/features/Conversation/components/ChatItem/index.tsx +3 -3
  120. package/src/features/ModelSwitchPanel/index.tsx +3 -6
  121. package/src/features/PluginDevModal/LocalForm.tsx +3 -3
  122. package/src/features/SyncStatusInspector/DisableSync.tsx +3 -3
  123. package/src/features/SyncStatusInspector/EnableSync.tsx +4 -4
  124. package/src/features/SyncStatusInspector/index.tsx +2 -2
  125. package/src/hooks/_header.ts +4 -4
  126. package/src/hooks/useSyncData.ts +3 -3
  127. package/src/hooks/useTTS.ts +4 -4
  128. package/src/layout/DefaultLayout/Desktop/SideBar/BottomActions.tsx +2 -2
  129. package/src/layout/DefaultLayout/Desktop/SideBar/TopActions.tsx +2 -2
  130. package/src/layout/DefaultLayout/Mobile/index.tsx +1 -1
  131. package/src/layout/GlobalProvider/AppTheme.tsx +4 -4
  132. package/src/layout/GlobalProvider/StoreInitialization.tsx +6 -1
  133. package/src/libs/agent-runtime/AgentRuntime.ts +7 -0
  134. package/src/libs/agent-runtime/error.ts +3 -0
  135. package/src/libs/agent-runtime/index.ts +1 -0
  136. package/src/libs/agent-runtime/minimax/index.test.ts +261 -0
  137. package/src/libs/agent-runtime/minimax/index.ts +185 -0
  138. package/src/libs/agent-runtime/togetherai/type.ts +0 -1
  139. package/src/libs/agent-runtime/types/type.ts +1 -0
  140. package/src/locales/default/error.ts +3 -0
  141. package/src/locales/default/modelProvider.ts +12 -0
  142. package/src/migrations/FromV3ToV4/types/v3.ts +1 -0
  143. package/src/services/__tests__/chat.test.ts +17 -20
  144. package/src/services/__tests__/tool.test.ts +2 -2
  145. package/src/services/_auth.test.ts +2 -2
  146. package/src/services/_auth.ts +7 -7
  147. package/src/services/_header.ts +4 -4
  148. package/src/services/chat.ts +13 -13
  149. package/src/services/config.ts +4 -4
  150. package/src/services/models.ts +3 -3
  151. package/src/services/ollama.ts +3 -3
  152. package/src/services/session/client.ts +2 -2
  153. package/src/services/tool.ts +1 -1
  154. package/src/services/trace.ts +3 -3
  155. package/src/store/agent/slices/chat/selectors.test.ts +2 -2
  156. package/src/store/chat/slices/message/selectors.test.ts +1 -1
  157. package/src/store/chat/slices/message/selectors.ts +3 -3
  158. package/src/store/global/{slices/preference/action.test.ts → action.test.ts} +65 -13
  159. package/src/store/global/{slices/preference/action.ts → action.ts} +30 -16
  160. package/src/store/global/initialState.ts +58 -8
  161. package/src/store/global/selectors.ts +9 -8
  162. package/src/store/global/store.ts +3 -7
  163. package/src/store/market/action.ts +1 -1
  164. package/src/store/session/slices/session/action.ts +3 -3
  165. package/src/store/{global → user}/helpers.ts +2 -2
  166. package/src/store/user/index.ts +1 -0
  167. package/src/store/user/initialState.ts +11 -0
  168. package/src/store/user/selectors.ts +8 -0
  169. package/src/store/{global → user}/slices/common/action.test.ts +29 -81
  170. package/src/store/{global → user}/slices/common/action.ts +2 -20
  171. package/src/store/user/slices/common/initialState.ts +18 -0
  172. package/src/store/user/slices/common/selectors.ts +6 -0
  173. package/src/store/user/slices/preference/action.test.ts +41 -0
  174. package/src/store/user/slices/preference/action.ts +50 -0
  175. package/src/store/user/slices/preference/initialState.ts +33 -0
  176. package/src/store/user/slices/preference/selectors.ts +13 -0
  177. package/src/store/{global → user}/slices/settings/actions/general.test.ts +6 -6
  178. package/src/store/{global → user}/slices/settings/actions/general.ts +2 -2
  179. package/src/store/{global → user}/slices/settings/actions/index.ts +2 -2
  180. package/src/store/{global → user}/slices/settings/actions/llm.test.ts +11 -14
  181. package/src/store/{global → user}/slices/settings/actions/llm.ts +4 -2
  182. package/src/store/{global → user}/slices/settings/initialState.ts +2 -2
  183. package/src/store/{global → user}/slices/settings/selectors/modelConfig.test.ts +8 -8
  184. package/src/store/{global → user}/slices/settings/selectors/modelConfig.ts +12 -12
  185. package/src/store/{global → user}/slices/settings/selectors/modelProvider.test.ts +17 -17
  186. package/src/store/{global → user}/slices/settings/selectors/modelProvider.ts +19 -20
  187. package/src/store/{global → user}/slices/settings/selectors/selectors.test.ts +8 -8
  188. package/src/store/{global → user}/slices/settings/selectors/settings.ts +12 -12
  189. package/src/store/user/slices/settings/selectors/sync.ts +14 -0
  190. package/src/store/user/store.ts +33 -0
  191. package/src/tools/dalle/Render/ToolBar.tsx +3 -3
  192. package/src/types/settings/modelProvider.ts +1 -0
  193. package/src/utils/localStorage.ts +3 -1
  194. package/src/store/global/slices/common/initialState.ts +0 -42
  195. package/src/store/global/slices/common/selectors.ts +0 -6
  196. package/src/store/global/slices/preference/initialState.ts +0 -51
  197. package/src/store/global/slices/preference/selectors.ts +0 -18
  198. package/src/store/global/slices/settings/selectors/sync.ts +0 -14
  199. /package/src/store/{global → user}/slices/settings/reducers/customModelCard.test.ts +0 -0
  200. /package/src/store/{global → user}/slices/settings/reducers/customModelCard.ts +0 -0
  201. /package/src/store/{global → user}/slices/settings/selectors/__snapshots__/selectors.test.ts.snap +0 -0
  202. /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 { useGlobalStore } from '@/store/global';
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(() => useGlobalStore());
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(() => useGlobalStore());
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(() => useGlobalStore());
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(() => useGlobalStore());
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(() => useGlobalStore());
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 { GlobalStore } from '@/store/global';
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
- GlobalStore,
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 { GlobalStore } from '@/store/global';
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
- GlobalStore,
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 { GlobalStore, useGlobalStore } from '@/store/global';
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/global/slices/settings/selectors';
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(() => useGlobalStore());
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(() => useGlobalStore());
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(() => useGlobalStore());
66
+ const { result } = renderHook(() => useUserStore());
70
67
 
71
68
  act(() => {
72
- useGlobalStore.setState({
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(() => useGlobalStore());
91
+ const { result } = renderHook(() => useUserStore());
95
92
  act(() => {
96
- useGlobalStore.setState({
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(() => useGlobalStore());
118
+ const { result } = renderHook(() => useUserStore());
122
119
 
123
120
  act(() => {
124
- useGlobalStore.setState({
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 { GlobalStore } from '@/store/global';
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
- GlobalStore,
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 GlobalSettingsState {
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: GlobalSettingsState = {
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 { GlobalStore, useGlobalStore } from '../../../store';
6
- import { GlobalSettingsState, initialSettingsState } from '../initialState';
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 { GlobalStore } from '../../../store';
3
+ import { UserStore } from '../../../store';
4
4
  import { currentLLMSettings, getProviderConfigById } from './settings';
5
5
 
6
- const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =>
6
+ const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: UserStore) =>
7
7
  getProviderConfigById(provider)(s)?.enabled || false;
8
8
 
9
- const isProviderEndpointNotEmpty = (provider: GlobalLLMProviderKey | string) => (s: GlobalStore) =>
9
+ const isProviderEndpointNotEmpty = (provider: GlobalLLMProviderKey | string) => (s: UserStore) =>
10
10
  !!getProviderConfigById(provider)(s)?.endpoint;
11
11
 
12
- const isProviderFetchOnClient = (provider: GlobalLLMProviderKey | string) => (s: GlobalStore) => {
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: GlobalStore) => {
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: GlobalStore) => {
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: GlobalStore): boolean => {
38
+ (s: UserStore): boolean => {
39
39
  return getProviderConfigById(provider)(s)?.autoFetchModelLists || false;
40
40
  };
41
41
 
42
- const openAIConfig = (s: GlobalStore) => currentLLMSettings(s).openai;
43
- const bedrockConfig = (s: GlobalStore) => currentLLMSettings(s).bedrock;
44
- const ollamaConfig = (s: GlobalStore) => currentLLMSettings(s).ollama;
45
- const azureConfig = (s: GlobalStore) => currentLLMSettings(s).azure;
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: GlobalStore) => currentLLMSettings(s).azure.enabled;
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 { GlobalStore, useGlobalStore } from '../../../store';
6
- import { GlobalSettingsState, initialSettingsState } from '../initialState';
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 GlobalStore;
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 GlobalStore;
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 GlobalSettingsState) as unknown as GlobalStore;
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 GlobalStore;
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 GlobalStore;
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
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
- useGlobalStore.getState(),
139
+ useUserStore.getState(),
140
140
  );
141
141
 
142
142
  expect(tokens).toEqual(0);