@lobehub/chat 0.150.8 → 0.150.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/docs/self-hosting/advanced/upstream-sync.mdx +74 -0
  3. package/docs/self-hosting/advanced/upstream-sync.zh-CN.mdx +71 -0
  4. package/docs/usage/providers/ollama.mdx +1 -1
  5. package/docs/usage/providers/ollama.zh-CN.mdx +1 -1
  6. package/package.json +1 -1
  7. package/src/app/chat/(desktop)/features/ChatHeader/HeaderAction.tsx +2 -2
  8. package/src/app/chat/(desktop)/features/ChatHeader/Tags.tsx +3 -3
  9. package/src/app/chat/(desktop)/features/ChatInput/Footer/DragUpload.tsx +3 -3
  10. package/src/app/chat/(desktop)/features/ChatInput/Footer/SendMore.tsx +3 -3
  11. package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +3 -3
  12. package/src/app/chat/(desktop)/features/ChatInput/TextArea.test.tsx +5 -5
  13. package/src/app/chat/(desktop)/features/ChatInput/TextArea.tsx +3 -3
  14. package/src/app/chat/(desktop)/features/SideBar/index.tsx +2 -2
  15. package/src/app/chat/(mobile)/features/SessionHeader.tsx +5 -5
  16. package/src/app/chat/(mobile)/mobile/ChatHeader/index.tsx +2 -2
  17. package/src/app/chat/_layout/Desktop/SessionHeader.tsx +2 -2
  18. package/src/app/chat/features/PluginTag/index.tsx +2 -2
  19. package/src/app/chat/features/SessionListContent/List/index.tsx +2 -2
  20. package/src/app/chat/features/ShareButton/ShareModal.tsx +3 -3
  21. package/src/app/chat/features/TelemetryNotification/index.tsx +6 -4
  22. package/src/app/chat/features/TopicListContent/Topic/index.tsx +2 -2
  23. package/src/app/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +3 -3
  24. package/src/app/settings/(mobile)/index.tsx +3 -3
  25. package/src/app/settings/about/Analytics.tsx +4 -4
  26. package/src/app/settings/about/page.tsx +3 -3
  27. package/src/app/settings/agent/Agent.tsx +4 -4
  28. package/src/app/settings/common/Common.tsx +4 -4
  29. package/src/app/settings/common/Theme.tsx +4 -4
  30. package/src/app/settings/features/SettingList/index.tsx +2 -2
  31. package/src/app/settings/features/ThemeSwatches/ThemeSwatchesNeutral.tsx +3 -3
  32. package/src/app/settings/features/ThemeSwatches/ThemeSwatchesPrimary.tsx +3 -3
  33. package/src/app/settings/hooks/useSyncSettings.ts +3 -3
  34. package/src/app/settings/llm/Azure/index.tsx +3 -3
  35. package/src/app/settings/llm/OpenAI/index.tsx +2 -2
  36. package/src/app/settings/llm/components/ProviderConfig/index.tsx +3 -3
  37. package/src/app/settings/llm/components/ProviderModelList/CustomModelOption.tsx +4 -4
  38. package/src/app/settings/llm/components/ProviderModelList/ModelConfigModal.tsx +4 -4
  39. package/src/app/settings/llm/components/ProviderModelList/ModelFetcher.tsx +6 -6
  40. package/src/app/settings/llm/components/ProviderModelList/Option.tsx +3 -3
  41. package/src/app/settings/llm/components/ProviderModelList/index.tsx +6 -6
  42. package/src/app/settings/sync/Alert.tsx +3 -3
  43. package/src/app/settings/sync/DeviceInfo/DeviceName.tsx +3 -3
  44. package/src/app/settings/sync/WebRTC/index.tsx +2 -2
  45. package/src/app/settings/tts/TTS/index.tsx +4 -4
  46. package/src/chains/__tests__/summaryAgentName.test.ts +2 -2
  47. package/src/chains/__tests__/summaryDescription.test.ts +2 -2
  48. package/src/chains/__tests__/summaryTags.test.ts +2 -2
  49. package/src/chains/__tests__/summaryTitle.test.ts +2 -2
  50. package/src/chains/summaryAgentName.ts +1 -1
  51. package/src/chains/summaryDescription.ts +1 -1
  52. package/src/chains/summaryTags.ts +1 -1
  53. package/src/chains/summaryTitle.ts +1 -1
  54. package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +3 -6
  55. package/src/features/AgentSetting/AgentMeta/index.tsx +3 -3
  56. package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
  57. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +4 -4
  58. package/src/features/AgentSetting/AgentTTS/index.tsx +3 -3
  59. package/src/features/AvatarWithUpload/index.tsx +3 -3
  60. package/src/features/ChatInput/ActionBar/FileUpload.tsx +3 -3
  61. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +4 -4
  62. package/src/features/ChatInput/ActionBar/Token/index.tsx +3 -3
  63. package/src/features/ChatInput/ActionBar/Tools/index.tsx +5 -5
  64. package/src/features/ChatInput/STT/browser.tsx +4 -4
  65. package/src/features/ChatInput/STT/index.tsx +3 -3
  66. package/src/features/ChatInput/STT/openai.tsx +4 -4
  67. package/src/features/ChatInput/useChatInput.ts +3 -3
  68. package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +3 -3
  69. package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +3 -3
  70. package/src/features/Conversation/Error/AccessCodeForm.tsx +3 -3
  71. package/src/features/Conversation/Error/InvalidAccessCode.tsx +3 -3
  72. package/src/features/Conversation/Extras/TTS/index.tsx +3 -3
  73. package/src/features/Conversation/Plugins/Render/MarkdownType/index.tsx +3 -3
  74. package/src/features/Conversation/components/ChatItem/index.tsx +3 -3
  75. package/src/features/ModelSwitchPanel/index.tsx +3 -6
  76. package/src/features/PluginDevModal/LocalForm.tsx +3 -3
  77. package/src/features/SyncStatusInspector/DisableSync.tsx +3 -3
  78. package/src/features/SyncStatusInspector/EnableSync.tsx +4 -4
  79. package/src/features/SyncStatusInspector/index.tsx +2 -2
  80. package/src/hooks/_header.ts +4 -4
  81. package/src/hooks/useSyncData.ts +3 -3
  82. package/src/hooks/useTTS.ts +4 -4
  83. package/src/layout/DefaultLayout/Desktop/SideBar/BottomActions.tsx +2 -2
  84. package/src/layout/DefaultLayout/Desktop/SideBar/TopActions.tsx +2 -2
  85. package/src/layout/DefaultLayout/Mobile/index.tsx +1 -1
  86. package/src/layout/GlobalProvider/AppTheme.tsx +4 -4
  87. package/src/layout/GlobalProvider/StoreInitialization.tsx +6 -1
  88. package/src/layout/GlobalProvider/index.tsx +5 -3
  89. package/src/server/globalConfig/index.ts +119 -0
  90. package/src/server/routers/config/index.ts +3 -112
  91. package/src/services/__tests__/chat.test.ts +17 -20
  92. package/src/services/__tests__/tool.test.ts +2 -2
  93. package/src/services/_auth.test.ts +2 -2
  94. package/src/services/_auth.ts +7 -7
  95. package/src/services/_header.ts +4 -4
  96. package/src/services/chat.ts +13 -13
  97. package/src/services/config.ts +4 -4
  98. package/src/services/models.ts +3 -3
  99. package/src/services/ollama.ts +3 -3
  100. package/src/services/session/client.ts +2 -2
  101. package/src/services/tool.ts +1 -1
  102. package/src/services/trace.ts +3 -3
  103. package/src/store/agent/slices/chat/selectors.test.ts +2 -2
  104. package/src/store/chat/slices/message/selectors.test.ts +1 -1
  105. package/src/store/chat/slices/message/selectors.ts +3 -3
  106. package/src/store/global/{slices/preference/action.test.ts → action.test.ts} +65 -13
  107. package/src/store/global/{slices/preference/action.ts → action.ts} +30 -16
  108. package/src/store/global/initialState.ts +58 -8
  109. package/src/store/global/selectors.ts +9 -8
  110. package/src/store/global/store.ts +3 -7
  111. package/src/store/market/action.ts +1 -1
  112. package/src/store/serverConfig/Provider.tsx +22 -0
  113. package/src/store/serverConfig/index.ts +3 -0
  114. package/src/store/serverConfig/selectors.test.ts +72 -0
  115. package/src/store/serverConfig/selectors.ts +11 -0
  116. package/src/store/serverConfig/store.test.ts +53 -0
  117. package/src/store/serverConfig/store.ts +61 -0
  118. package/src/store/session/slices/session/action.ts +3 -3
  119. package/src/store/{global → user}/helpers.ts +2 -2
  120. package/src/store/user/index.ts +1 -0
  121. package/src/store/user/initialState.ts +11 -0
  122. package/src/store/user/selectors.ts +8 -0
  123. package/src/store/{global → user}/slices/common/action.test.ts +29 -81
  124. package/src/store/{global → user}/slices/common/action.ts +2 -20
  125. package/src/store/user/slices/common/initialState.ts +18 -0
  126. package/src/store/user/slices/common/selectors.ts +6 -0
  127. package/src/store/user/slices/preference/action.test.ts +41 -0
  128. package/src/store/user/slices/preference/action.ts +50 -0
  129. package/src/store/user/slices/preference/initialState.ts +33 -0
  130. package/src/store/user/slices/preference/selectors.ts +13 -0
  131. package/src/store/{global → user}/slices/settings/actions/general.test.ts +6 -6
  132. package/src/store/{global → user}/slices/settings/actions/general.ts +2 -2
  133. package/src/store/{global → user}/slices/settings/actions/index.ts +2 -2
  134. package/src/store/{global → user}/slices/settings/actions/llm.test.ts +11 -14
  135. package/src/store/{global → user}/slices/settings/actions/llm.ts +2 -2
  136. package/src/store/{global → user}/slices/settings/initialState.ts +2 -2
  137. package/src/store/{global → user}/slices/settings/selectors/modelConfig.test.ts +8 -8
  138. package/src/store/{global → user}/slices/settings/selectors/modelConfig.ts +12 -12
  139. package/src/store/{global → user}/slices/settings/selectors/modelProvider.test.ts +17 -17
  140. package/src/store/{global → user}/slices/settings/selectors/modelProvider.ts +19 -20
  141. package/src/store/{global → user}/slices/settings/selectors/selectors.test.ts +8 -8
  142. package/src/store/{global → user}/slices/settings/selectors/settings.ts +12 -12
  143. package/src/store/user/slices/settings/selectors/sync.ts +14 -0
  144. package/src/store/user/store.ts +33 -0
  145. package/src/tools/dalle/Render/ToolBar.tsx +3 -3
  146. package/src/utils/localStorage.ts +3 -1
  147. package/src/store/featureFlags/Provider.tsx +0 -18
  148. package/src/store/featureFlags/index.ts +0 -3
  149. package/src/store/featureFlags/selectors.ts +0 -5
  150. package/src/store/featureFlags/store.ts +0 -42
  151. package/src/store/global/slices/common/initialState.ts +0 -42
  152. package/src/store/global/slices/common/selectors.ts +0 -8
  153. package/src/store/global/slices/preference/initialState.ts +0 -51
  154. package/src/store/global/slices/preference/selectors.ts +0 -18
  155. package/src/store/global/slices/settings/selectors/sync.ts +0 -14
  156. /package/src/server/{routers/config → globalConfig}/parseDefaultAgent.test.ts +0 -0
  157. /package/src/server/{routers/config → globalConfig}/parseDefaultAgent.ts +0 -0
  158. /package/src/store/{global → user}/slices/settings/reducers/customModelCard.test.ts +0 -0
  159. /package/src/store/{global → user}/slices/settings/reducers/customModelCard.ts +0 -0
  160. /package/src/store/{global → user}/slices/settings/selectors/__snapshots__/selectors.test.ts.snap +0 -0
  161. /package/src/store/{global → user}/slices/settings/selectors/index.ts +0 -0
@@ -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 },
@@ -17,7 +17,7 @@ import {
17
17
  ZeroOneProviderCard,
18
18
  ZhiPuProviderCard,
19
19
  } from '@/config/modelProviders';
20
- import { GlobalStore } from '@/store/global';
20
+ import { UserStore } from '@/store/user';
21
21
  import { ChatModelCard } from '@/types/llm';
22
22
  import { GlobalLLMConfig, GlobalLLMProviderKey } from '@/types/settings';
23
23
  import { setNamespace } from '@/utils/storeDebug';
@@ -57,7 +57,7 @@ export interface LLMSettingsAction {
57
57
  }
58
58
 
59
59
  export const llmSettingsSlice: StateCreator<
60
- GlobalStore,
60
+ UserStore,
61
61
  [['zustand/devtools', never]],
62
62
  [],
63
63
  LLMSettingsAction
@@ -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);
@@ -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,