@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
@@ -5,7 +5,7 @@ import { ChatModelCard, ModelProviderCard } from '@/types/llm';
5
5
  import { ServerModelProviderConfig } from '@/types/serverConfig';
6
6
  import { GlobalLLMProviderKey } from '@/types/settings';
7
7
 
8
- import { GlobalStore } from '../../../store';
8
+ import { UserStore } from '../../../store';
9
9
  import { currentSettings, getProviderConfigById } from './settings';
10
10
 
11
11
  /**
@@ -13,7 +13,7 @@ import { currentSettings, getProviderConfigById } from './settings';
13
13
  */
14
14
  const serverProviderModelCards =
15
15
  (provider: GlobalLLMProviderKey) =>
16
- (s: GlobalStore): ChatModelCard[] | undefined => {
16
+ (s: UserStore): ChatModelCard[] | undefined => {
17
17
  const config = s.serverConfig.languageModel?.[provider] as
18
18
  | ServerModelProviderConfig
19
19
  | undefined;
@@ -25,7 +25,7 @@ const serverProviderModelCards =
25
25
 
26
26
  const remoteProviderModelCards =
27
27
  (provider: GlobalLLMProviderKey) =>
28
- (s: GlobalStore): ChatModelCard[] | undefined => {
28
+ (s: UserStore): ChatModelCard[] | undefined => {
29
29
  const cards = currentSettings(s).languageModel?.[provider]?.remoteModelCards as
30
30
  | ChatModelCard[]
31
31
  | undefined;
@@ -35,7 +35,7 @@ const remoteProviderModelCards =
35
35
  return cards;
36
36
  };
37
37
 
38
- const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =>
38
+ const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: UserStore) =>
39
39
  getProviderConfigById(provider)(s)?.enabled || false;
40
40
 
41
41
  // Default Model Provider List
@@ -43,10 +43,9 @@ const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =
43
43
  /**
44
44
  * define all the model list of providers
45
45
  */
46
- const defaultModelProviderList = (s: GlobalStore): ModelProviderCard[] =>
47
- s.defaultModelProviderList;
46
+ const defaultModelProviderList = (s: UserStore): ModelProviderCard[] => s.defaultModelProviderList;
48
47
 
49
- export const getDefaultModeProviderById = (provider: string) => (s: GlobalStore) =>
48
+ export const getDefaultModeProviderById = (provider: string) => (s: UserStore) =>
50
49
  defaultModelProviderList(s).find((s) => s.id === provider);
51
50
 
52
51
  /**
@@ -54,7 +53,7 @@ export const getDefaultModeProviderById = (provider: string) => (s: GlobalStore)
54
53
  * it's a default enabled model list by Lobe Chat
55
54
  * e.g. openai is ['gpt-3.5-turbo','gpt-4-turbo']
56
55
  */
57
- const getDefaultEnabledModelsById = (provider: string) => (s: GlobalStore) => {
56
+ const getDefaultEnabledModelsById = (provider: string) => (s: UserStore) => {
58
57
  const modelProvider = getDefaultModeProviderById(provider)(s);
59
58
 
60
59
  if (modelProvider) return filterEnabledModels(modelProvider);
@@ -62,7 +61,7 @@ const getDefaultEnabledModelsById = (provider: string) => (s: GlobalStore) => {
62
61
  return undefined;
63
62
  };
64
63
 
65
- const getDefaultModelCardById = (id: string) => (s: GlobalStore) => {
64
+ const getDefaultModelCardById = (id: string) => (s: UserStore) => {
66
65
  const list = defaultModelProviderList(s);
67
66
 
68
67
  return list.flatMap((i) => i.chatModels).find((m) => m.id === id);
@@ -72,7 +71,7 @@ const getDefaultModelCardById = (id: string) => (s: GlobalStore) => {
72
71
 
73
72
  const getModelCardsById =
74
73
  (provider: string) =>
75
- (s: GlobalStore): ChatModelCard[] => {
74
+ (s: UserStore): ChatModelCard[] => {
76
75
  const builtinCards = getDefaultModeProviderById(provider)(s)?.chatModels || [];
77
76
 
78
77
  const userCards = (getProviderConfigById(provider)(s)?.customModelCards || []).map((model) => ({
@@ -83,15 +82,15 @@ const getModelCardsById =
83
82
  return uniqBy([...userCards, ...builtinCards], 'id');
84
83
  };
85
84
 
86
- const getEnableModelsById = (provider: string) => (s: GlobalStore) => {
85
+ const getEnableModelsById = (provider: string) => (s: UserStore) => {
87
86
  if (!getProviderConfigById(provider)(s)?.enabledModels) return;
88
87
 
89
88
  return getProviderConfigById(provider)(s)?.enabledModels?.filter(Boolean);
90
89
  };
91
90
 
92
- const modelProviderList = (s: GlobalStore): ModelProviderCard[] => s.modelProviderList;
91
+ const modelProviderList = (s: UserStore): ModelProviderCard[] => s.modelProviderList;
93
92
 
94
- const modelProviderListForModelSelect = (s: GlobalStore): ModelProviderCard[] =>
93
+ const modelProviderListForModelSelect = (s: UserStore): ModelProviderCard[] =>
95
94
  modelProviderList(s)
96
95
  .filter((s) => s.enabled)
97
96
  .map((provider) => ({
@@ -99,29 +98,29 @@ const modelProviderListForModelSelect = (s: GlobalStore): ModelProviderCard[] =>
99
98
  chatModels: provider.chatModels.filter((model) => model.enabled),
100
99
  }));
101
100
 
102
- const getModelCardById = (id: string) => (s: GlobalStore) => {
101
+ const getModelCardById = (id: string) => (s: UserStore) => {
103
102
  const list = modelProviderList(s);
104
103
 
105
104
  return list.flatMap((i) => i.chatModels).find((m) => m.id === id);
106
105
  };
107
106
 
108
- const isModelEnabledFunctionCall = (id: string) => (s: GlobalStore) =>
107
+ const isModelEnabledFunctionCall = (id: string) => (s: UserStore) =>
109
108
  getModelCardById(id)(s)?.functionCall || false;
110
109
 
111
110
  // vision model white list, these models will change the content from string to array
112
111
  // refs: https://github.com/lobehub/lobe-chat/issues/790
113
- const isModelEnabledVision = (id: string) => (s: GlobalStore) =>
112
+ const isModelEnabledVision = (id: string) => (s: UserStore) =>
114
113
  getModelCardById(id)(s)?.vision || id.includes('vision');
115
114
 
116
- const isModelEnabledFiles = (id: string) => (s: GlobalStore) => getModelCardById(id)(s)?.files;
115
+ const isModelEnabledFiles = (id: string) => (s: UserStore) => getModelCardById(id)(s)?.files;
117
116
 
118
- const isModelEnabledUpload = (id: string) => (s: GlobalStore) =>
117
+ const isModelEnabledUpload = (id: string) => (s: UserStore) =>
119
118
  isModelEnabledVision(id)(s) || isModelEnabledFiles(id)(s);
120
119
 
121
- const isModelHasMaxToken = (id: string) => (s: GlobalStore) =>
120
+ const isModelHasMaxToken = (id: string) => (s: UserStore) =>
122
121
  typeof getModelCardById(id)(s)?.tokens !== 'undefined';
123
122
 
124
- const modelMaxToken = (id: string) => (s: GlobalStore) => getModelCardById(id)(s)?.tokens || 0;
123
+ const modelMaxToken = (id: string) => (s: UserStore) => getModelCardById(id)(s)?.tokens || 0;
125
124
 
126
125
  export const modelProviderSelectors = {
127
126
  defaultModelProviderList,
@@ -1,4 +1,4 @@
1
- import { GlobalStore } from '../../../store';
1
+ import { UserStore } from '../../../store';
2
2
  import { settingsSelectors } from './settings';
3
3
 
4
4
  describe('settingsSelectors', () => {
@@ -48,7 +48,7 @@ describe('settingsSelectors', () => {
48
48
  },
49
49
  },
50
50
  },
51
- } as unknown as GlobalStore;
51
+ } as unknown as UserStore;
52
52
 
53
53
  const result = settingsSelectors.currentSettings(s);
54
54
 
@@ -71,7 +71,7 @@ describe('settingsSelectors', () => {
71
71
  },
72
72
  },
73
73
  },
74
- } as unknown as GlobalStore;
74
+ } as unknown as UserStore;
75
75
 
76
76
  const result = settingsSelectors.defaultAgent(s);
77
77
 
@@ -90,7 +90,7 @@ describe('settingsSelectors', () => {
90
90
  },
91
91
  },
92
92
  },
93
- } as unknown as GlobalStore;
93
+ } as unknown as UserStore;
94
94
 
95
95
  const result = settingsSelectors.defaultAgentMeta(s);
96
96
 
@@ -109,7 +109,7 @@ describe('settingsSelectors', () => {
109
109
  },
110
110
  },
111
111
  },
112
- } as unknown as GlobalStore;
112
+ } as unknown as UserStore;
113
113
 
114
114
  const result = settingsSelectors.currentTTS(s);
115
115
 
@@ -123,7 +123,7 @@ describe('settingsSelectors', () => {
123
123
  settings: {
124
124
  language: 'fr',
125
125
  },
126
- } as unknown as GlobalStore;
126
+ } as unknown as UserStore;
127
127
 
128
128
  const result = settingsSelectors.currentLanguage(s);
129
129
 
@@ -142,7 +142,7 @@ describe('settingsSelectors', () => {
142
142
  },
143
143
  },
144
144
  },
145
- } as unknown as GlobalStore;
145
+ } as unknown as UserStore;
146
146
 
147
147
  const result = settingsSelectors.dalleConfig(s);
148
148
 
@@ -160,7 +160,7 @@ describe('settingsSelectors', () => {
160
160
  },
161
161
  },
162
162
  },
163
- } as unknown as GlobalStore;
163
+ } as unknown as UserStore;
164
164
 
165
165
  const result = settingsSelectors.isDalleAutoGenerating(s);
166
166
 
@@ -6,33 +6,33 @@ import { GeneralModelProviderConfig, GlobalLLMProviderKey, GlobalSettings } from
6
6
  import { isOnServerSide } from '@/utils/env';
7
7
  import { merge } from '@/utils/merge';
8
8
 
9
- import { GlobalStore } from '../../../store';
9
+ import { UserStore } from '../../../store';
10
10
 
11
- export const currentSettings = (s: GlobalStore): GlobalSettings =>
11
+ export const currentSettings = (s: UserStore): GlobalSettings =>
12
12
  merge(s.defaultSettings, s.settings);
13
13
 
14
- export const currentLLMSettings = (s: GlobalStore) => currentSettings(s).languageModel;
14
+ export const currentLLMSettings = (s: UserStore) => currentSettings(s).languageModel;
15
15
 
16
- export const getProviderConfigById = (provider: string) => (s: GlobalStore) =>
16
+ export const getProviderConfigById = (provider: string) => (s: UserStore) =>
17
17
  currentLLMSettings(s)[provider as GlobalLLMProviderKey] as GeneralModelProviderConfig | undefined;
18
18
 
19
- const password = (s: GlobalStore) => currentSettings(s).password;
19
+ const password = (s: UserStore) => currentSettings(s).password;
20
20
 
21
- const currentTTS = (s: GlobalStore) => merge(DEFAULT_TTS_CONFIG, currentSettings(s).tts);
21
+ const currentTTS = (s: UserStore) => merge(DEFAULT_TTS_CONFIG, currentSettings(s).tts);
22
22
 
23
- const defaultAgent = (s: GlobalStore) => merge(DEFAULT_AGENT, currentSettings(s).defaultAgent);
23
+ const defaultAgent = (s: UserStore) => merge(DEFAULT_AGENT, currentSettings(s).defaultAgent);
24
24
 
25
- const defaultAgentMeta = (s: GlobalStore) => merge(DEFAULT_AGENT_META, defaultAgent(s).meta);
25
+ const defaultAgentMeta = (s: UserStore) => merge(DEFAULT_AGENT_META, defaultAgent(s).meta);
26
26
 
27
27
  // TODO: Maybe we can also export settings difference
28
- const exportSettings = (s: GlobalStore) => {
28
+ const exportSettings = (s: UserStore) => {
29
29
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
30
  const { password: _, ...settings } = currentSettings(s);
31
31
 
32
32
  return settings as GlobalSettings;
33
33
  };
34
34
 
35
- const currentLanguage = (s: GlobalStore) => {
35
+ const currentLanguage = (s: UserStore) => {
36
36
  const locale = currentSettings(s).language;
37
37
 
38
38
  if (locale === 'auto') {
@@ -44,8 +44,8 @@ const currentLanguage = (s: GlobalStore) => {
44
44
  return locale;
45
45
  };
46
46
 
47
- const dalleConfig = (s: GlobalStore) => currentSettings(s).tool?.dalle || {};
48
- const isDalleAutoGenerating = (s: GlobalStore) => currentSettings(s).tool?.dalle?.autoGenerate;
47
+ const dalleConfig = (s: UserStore) => currentSettings(s).tool?.dalle || {};
48
+ const isDalleAutoGenerating = (s: UserStore) => currentSettings(s).tool?.dalle?.autoGenerate;
49
49
 
50
50
  export const settingsSelectors = {
51
51
  currentLanguage,
@@ -0,0 +1,14 @@
1
+ import { UserStore } from '../../../store';
2
+ import { currentSettings } from './settings';
3
+
4
+ const webrtcConfig = (s: UserStore) => currentSettings(s).sync.webrtc;
5
+ const webrtcChannelName = (s: UserStore) => webrtcConfig(s).channelName;
6
+ const enableWebRTC = (s: UserStore) => webrtcConfig(s).enabled;
7
+ const deviceName = (s: UserStore) => currentSettings(s).sync.deviceName;
8
+
9
+ export const syncSettingsSelectors = {
10
+ deviceName,
11
+ enableWebRTC,
12
+ webrtcChannelName,
13
+ webrtcConfig,
14
+ };
@@ -0,0 +1,33 @@
1
+ import { devtools, subscribeWithSelector } from 'zustand/middleware';
2
+ import { shallow } from 'zustand/shallow';
3
+ import { createWithEqualityFn } from 'zustand/traditional';
4
+ import { StateCreator } from 'zustand/vanilla';
5
+
6
+ import { isDev } from '@/utils/env';
7
+
8
+ import { type UserState, 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
+
13
+ // =============== 聚合 createStoreFn ============ //
14
+
15
+ export type UserStore = CommonAction & UserState & SettingsAction & PreferenceAction;
16
+
17
+ const createStore: StateCreator<UserStore, [['zustand/devtools', never]]> = (...parameters) => ({
18
+ ...initialState,
19
+ ...createCommonSlice(...parameters),
20
+ ...createSettingsSlice(...parameters),
21
+ ...createPreferenceSlice(...parameters),
22
+ });
23
+
24
+ // =============== 实装 useStore ============ //
25
+
26
+ export const useUserStore = createWithEqualityFn<UserStore>()(
27
+ subscribeWithSelector(
28
+ devtools(createStore, {
29
+ name: 'LobeChat_User' + (isDev ? '_DEV' : ''),
30
+ }),
31
+ ),
32
+ shallow,
33
+ );
@@ -5,8 +5,8 @@ import { Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { useChatStore } from '@/store/chat';
7
7
  import { chatToolSelectors } from '@/store/chat/selectors';
8
- import { useGlobalStore } from '@/store/global';
9
- import { settingsSelectors } from '@/store/global/selectors';
8
+ import { useUserStore } from '@/store/user';
9
+ import { settingsSelectors } from '@/store/user/selectors';
10
10
  import { DallEImageItem } from '@/types/tool/dalle';
11
11
 
12
12
  interface ToolBarProps {
@@ -19,7 +19,7 @@ const ToolBar = memo<ToolBarProps>(({ content, messageId }) => {
19
19
  const generateImageFromPrompts = useChatStore((s) => s.generateImageFromPrompts);
20
20
  const isLoading = useChatStore(chatToolSelectors.isGeneratingDallEImage);
21
21
 
22
- const [isAutoGenerate, setSettings] = useGlobalStore((s) => [
22
+ const [isAutoGenerate, setSettings] = useUserStore((s) => [
23
23
  settingsSelectors.isDalleAutoGenerating(s),
24
24
  s.setSettings,
25
25
  ]);
@@ -46,6 +46,7 @@ export interface GlobalLLMConfig {
46
46
  bedrock: AWSBedrockConfig;
47
47
  google: GeneralModelProviderConfig;
48
48
  groq: GeneralModelProviderConfig;
49
+ minimax: GeneralModelProviderConfig;
49
50
  mistral: GeneralModelProviderConfig;
50
51
  moonshot: GeneralModelProviderConfig;
51
52
  ollama: GeneralModelProviderConfig;
@@ -1,6 +1,8 @@
1
1
  const PREV_KEY = 'LOBE_GLOBAL';
2
2
 
3
- type StorageKey = 'LOBE_PREFERENCE';
3
+ // LOBE_PREFERENCE for userStore
4
+ // LOBE_GLOBAL_PREFERENCE for globalStore
5
+ type StorageKey = 'LOBE_PREFERENCE' | 'LOBE_GLOBAL_PREFERENCE';
4
6
 
5
7
  export class AsyncLocalStorage<State> {
6
8
  private storageKey: StorageKey;
@@ -1,42 +0,0 @@
1
- import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime';
2
-
3
- import { PeerSyncStatus, SyncAwarenessState } from '@/types/sync';
4
-
5
- export enum SidebarTabKey {
6
- Chat = 'chat',
7
- Market = 'market',
8
- Setting = 'settings',
9
- }
10
-
11
- export enum SettingsTabs {
12
- About = 'about',
13
- Agent = 'agent',
14
- Common = 'common',
15
- LLM = 'llm',
16
- Sync = 'sync',
17
- TTS = 'tts',
18
- }
19
-
20
- export interface Guide {
21
- // Topic 引导
22
- topic?: boolean;
23
- }
24
-
25
- export interface GlobalCommonState {
26
- hasNewVersion?: boolean;
27
- isMobile?: boolean;
28
- latestVersion?: string;
29
- router?: AppRouterInstance;
30
- sidebarKey: SidebarTabKey;
31
- syncAwareness: SyncAwarenessState[];
32
- syncEnabled: boolean;
33
- syncStatus: PeerSyncStatus;
34
- }
35
-
36
- export const initialCommonState: GlobalCommonState = {
37
- isMobile: false,
38
- sidebarKey: SidebarTabKey.Chat,
39
- syncAwareness: [],
40
- syncEnabled: false,
41
- syncStatus: PeerSyncStatus.Disabled,
42
- };
@@ -1,6 +0,0 @@
1
- import { GlobalStore } from '@/store/global';
2
-
3
- export const commonSelectors = {
4
- userAvatar: (s: GlobalStore) => s.avatar || '',
5
- userId: (s: GlobalStore) => s.userId,
6
- };
@@ -1,51 +0,0 @@
1
- import { SessionDefaultGroup, SessionGroupId } from '@/types/session';
2
- import { AsyncLocalStorage } from '@/utils/localStorage';
3
-
4
- export interface Guide {
5
- // Topic 引导
6
- topic?: boolean;
7
- }
8
-
9
- export interface GlobalPreference {
10
- // which sessionGroup should expand
11
- expandSessionGroupKeys: SessionGroupId[];
12
- guide?: Guide;
13
- hideSyncAlert?: boolean;
14
- inputHeight: number;
15
- mobileShowTopic?: boolean;
16
-
17
- sessionsWidth: number;
18
- showChatSideBar?: boolean;
19
- showSessionPanel?: boolean;
20
- showSystemRole?: boolean;
21
- telemetry: boolean | null;
22
-
23
- /**
24
- * whether to use cmd + enter to send message
25
- */
26
- useCmdEnterToSend?: boolean;
27
- }
28
-
29
- export interface GlobalPreferenceState {
30
- /**
31
- * the user preference, which only store in local storage
32
- */
33
- preference: GlobalPreference;
34
- preferenceStorage: AsyncLocalStorage<GlobalPreference>;
35
- }
36
-
37
- export const initialPreferenceState: GlobalPreferenceState = {
38
- preference: {
39
- expandSessionGroupKeys: [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default],
40
- guide: {},
41
- inputHeight: 200,
42
- mobileShowTopic: false,
43
- sessionsWidth: 320,
44
- showChatSideBar: true,
45
- showSessionPanel: true,
46
- showSystemRole: false,
47
- telemetry: null,
48
- useCmdEnterToSend: false,
49
- },
50
- preferenceStorage: new AsyncLocalStorage('LOBE_PREFERENCE'),
51
- };
@@ -1,18 +0,0 @@
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
- const useCmdEnterToSend = (s: GlobalStore): boolean => s.preference.useCmdEnterToSend || false;
8
-
9
- const userAllowTrace = (s: GlobalStore) => s.preference.telemetry;
10
-
11
- const hideSyncAlert = (s: GlobalStore) => s.preference.hideSyncAlert;
12
-
13
- export const preferenceSelectors = {
14
- hideSyncAlert,
15
- sessionGroupKeys,
16
- useCmdEnterToSend,
17
- userAllowTrace,
18
- };
@@ -1,14 +0,0 @@
1
- import { GlobalStore } from '../../../store';
2
- import { currentSettings } from './settings';
3
-
4
- const webrtcConfig = (s: GlobalStore) => currentSettings(s).sync.webrtc;
5
- const webrtcChannelName = (s: GlobalStore) => webrtcConfig(s).channelName;
6
- const enableWebRTC = (s: GlobalStore) => webrtcConfig(s).enabled;
7
- const deviceName = (s: GlobalStore) => currentSettings(s).sync.deviceName;
8
-
9
- export const syncSettingsSelectors = {
10
- deviceName,
11
- enableWebRTC,
12
- webrtcChannelName,
13
- webrtcConfig,
14
- };