@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
@@ -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
  ]);
@@ -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,18 +0,0 @@
1
- 'use client';
2
-
3
- import { ReactNode, memo } from 'react';
4
-
5
- import { IFeatureFlags } from '@/config/featureFlags';
6
-
7
- import { Provider, createFeatureFlagsStore } from './store';
8
-
9
- interface GlobalStoreProviderProps {
10
- children: ReactNode;
11
- featureFlags?: Partial<IFeatureFlags>;
12
- }
13
-
14
- export const FeatureFlagStoreProvider = memo<GlobalStoreProviderProps>(
15
- ({ children, featureFlags }) => (
16
- <Provider createStore={() => createFeatureFlagsStore(featureFlags)}>{children}</Provider>
17
- ),
18
- );
@@ -1,3 +0,0 @@
1
- export { FeatureFlagStoreProvider } from './Provider';
2
- export { featureFlagsSelectors } from './selectors';
3
- export { useFeatureFlagStore } from './store';
@@ -1,5 +0,0 @@
1
- import { mapFeatureFlagsEnvToState } from '@/config/featureFlags';
2
-
3
- import { FeatureFlagStore } from './store';
4
-
5
- export const featureFlagsSelectors = (s: FeatureFlagStore) => mapFeatureFlagsEnvToState(s);
@@ -1,42 +0,0 @@
1
- import { StoreApi } from 'zustand';
2
- import { createContext } from 'zustand-utils';
3
- import { devtools } from 'zustand/middleware';
4
- import { shallow } from 'zustand/shallow';
5
- import { createWithEqualityFn } from 'zustand/traditional';
6
- import { StateCreator } from 'zustand/vanilla';
7
-
8
- import { DEFAULT_FEATURE_FLAGS, IFeatureFlags } from '@/config/featureFlags';
9
- import { isDev } from '@/utils/env';
10
- import { StoreApiWithSelector } from '@/utils/zustand';
11
-
12
- // =============== 聚合 createStoreFn ============ //
13
-
14
- export type FeatureFlagStore = IFeatureFlags;
15
-
16
- const createStore: (
17
- initState: Partial<FeatureFlagStore>,
18
- ) => StateCreator<FeatureFlagStore, [['zustand/devtools', never]]> = (runtimeState) => () => ({
19
- ...DEFAULT_FEATURE_FLAGS,
20
- ...runtimeState,
21
- });
22
-
23
- // =============== 实装 useStore ============ //
24
-
25
- let store: StoreApi<FeatureFlagStore>;
26
-
27
- export const createFeatureFlagsStore = (initState?: Partial<FeatureFlagStore>) => {
28
- // make sure there is only one store
29
- if (!store) {
30
- store = createWithEqualityFn<FeatureFlagStore>()(
31
- devtools(createStore(initState || {}), {
32
- name: 'LobeChat_FeatureFlags' + (isDev ? '_DEV' : ''),
33
- }),
34
- shallow,
35
- );
36
- }
37
-
38
- return store;
39
- };
40
-
41
- export const { useStore: useFeatureFlagStore, Provider } =
42
- createContext<StoreApiWithSelector<FeatureFlagStore>>();
@@ -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,8 +0,0 @@
1
- import { GlobalStore } from '@/store/global';
2
-
3
- export const commonSelectors = {
4
- enabledOAuthSSO: (s: GlobalStore) => s.serverConfig.enabledOAuthSSO,
5
- enabledTelemetryChat: (s: GlobalStore) => s.serverConfig.telemetry.langfuse || false,
6
- userAvatar: (s: GlobalStore) => s.avatar || '',
7
- userId: (s: GlobalStore) => s.userId,
8
- };
@@ -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
- };