@lobehub/chat 0.161.21 → 0.161.23

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 (111) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/package.json +1 -1
  3. package/src/app/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +3 -3
  4. package/src/app/(main)/settings/common/features/Common.tsx +1 -1
  5. package/src/app/(main)/settings/common/features/Theme/ThemeSwatches/ThemeSwatchesNeutral.tsx +5 -5
  6. package/src/app/(main)/settings/common/features/Theme/ThemeSwatches/ThemeSwatchesPrimary.tsx +5 -5
  7. package/src/app/(main)/settings/common/features/Theme/index.tsx +5 -4
  8. package/src/app/(main)/settings/llm/Azure/index.tsx +4 -4
  9. package/src/app/(main)/settings/llm/Bedrock/index.tsx +5 -5
  10. package/src/app/(main)/settings/llm/Ollama/Checker.tsx +1 -1
  11. package/src/app/(main)/settings/llm/components/Checker.tsx +10 -6
  12. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +6 -5
  13. package/src/app/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +1 -1
  14. package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +1 -1
  15. package/src/app/(main)/settings/llm/components/ProviderModelList/Option.tsx +1 -1
  16. package/src/app/(main)/settings/llm/components/ProviderModelList/index.tsx +1 -1
  17. package/src/app/(main)/settings/llm/const.ts +2 -1
  18. package/src/const/settings/agent.ts +2 -2
  19. package/src/const/settings/common.ts +2 -2
  20. package/src/const/settings/index.ts +4 -3
  21. package/src/const/settings/llm.ts +2 -21
  22. package/src/const/settings/sync.ts +2 -2
  23. package/src/const/settings/systemAgent.ts +2 -2
  24. package/src/const/settings/tts.ts +2 -2
  25. package/src/database/client/core/db.ts +19 -0
  26. package/src/database/client/core/migrations/migrateSettingsToUser/type.ts +1 -1
  27. package/src/database/client/core/schemas.ts +3 -2
  28. package/src/database/client/models/__tests__/user.test.ts +5 -5
  29. package/src/database/client/models/user.ts +2 -3
  30. package/src/database/client/schemas/user.ts +10 -4
  31. package/src/features/AgentSetting/AgentMeta/index.tsx +3 -3
  32. package/src/features/AgentSetting/AgentTTS/index.tsx +2 -2
  33. package/src/features/ChatInput/STT/browser.tsx +2 -2
  34. package/src/features/ChatInput/STT/openai.tsx +2 -2
  35. package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +5 -5
  36. package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +5 -5
  37. package/src/features/Conversation/Error/APIKeyForm/index.tsx +1 -1
  38. package/src/features/Conversation/Error/AccessCodeForm.tsx +4 -4
  39. package/src/features/Conversation/Extras/TTS/index.tsx +2 -2
  40. package/src/features/Conversation/Plugins/Render/MarkdownType/index.tsx +2 -2
  41. package/src/features/Conversation/components/BubblesLoading.tsx +49 -41
  42. package/src/features/Conversation/components/ChatItem/index.tsx +2 -2
  43. package/src/features/PluginDevModal/LocalForm.tsx +2 -2
  44. package/src/features/PluginStore/index.tsx +6 -2
  45. package/src/features/User/UserPanel/LangButton.tsx +2 -2
  46. package/src/features/User/UserPanel/ThemeButton.tsx +2 -2
  47. package/src/hooks/_header.ts +6 -3
  48. package/src/hooks/useTTS.ts +2 -2
  49. package/src/layout/GlobalProvider/AppTheme.tsx +4 -4
  50. package/src/libs/agent-runtime/types/type.ts +3 -2
  51. package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +203 -0
  52. package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +103 -0
  53. package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +118 -0
  54. package/src/migrations/FromV6ToV7/index.ts +101 -0
  55. package/src/migrations/FromV6ToV7/migrations.test.ts +64 -0
  56. package/src/migrations/FromV6ToV7/types/v6.ts +61 -0
  57. package/src/migrations/FromV6ToV7/types/v7.ts +71 -0
  58. package/src/migrations/index.ts +9 -3
  59. package/src/services/__tests__/chat.test.ts +19 -19
  60. package/src/services/__tests__/share.test.ts +4 -4
  61. package/src/services/_auth.test.ts +10 -5
  62. package/src/services/_auth.ts +11 -7
  63. package/src/services/_header.ts +6 -3
  64. package/src/services/config.ts +2 -2
  65. package/src/services/ollama.ts +3 -3
  66. package/src/services/share.ts +3 -3
  67. package/src/services/user/client.test.ts +3 -3
  68. package/src/services/user/client.ts +3 -3
  69. package/src/services/user/type.ts +2 -2
  70. package/src/store/agent/store.ts +4 -9
  71. package/src/store/chat/store.ts +4 -8
  72. package/src/store/file/store.ts +3 -9
  73. package/src/store/global/store.ts +5 -8
  74. package/src/store/market/store.ts +5 -8
  75. package/src/store/middleware/createDevtools.ts +23 -0
  76. package/src/store/serverConfig/store.ts +5 -11
  77. package/src/store/session/store.ts +3 -1
  78. package/src/store/tool/store.ts +4 -9
  79. package/src/store/user/helpers.ts +3 -2
  80. package/src/store/user/selectors.ts +10 -2
  81. package/src/store/user/slices/common/action.test.ts +3 -3
  82. package/src/store/user/slices/common/action.ts +4 -4
  83. package/src/store/user/slices/modelList/action.test.ts +2 -2
  84. package/src/store/user/slices/modelList/action.ts +16 -4
  85. package/src/store/user/slices/modelList/selectors/index.ts +1 -0
  86. package/src/store/user/slices/modelList/selectors/keyVaults.ts +25 -0
  87. package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +1 -1
  88. package/src/store/user/slices/modelList/selectors/modelConfig.ts +1 -6
  89. package/src/store/user/slices/modelList/selectors/modelProvider.ts +1 -1
  90. package/src/store/user/slices/settings/action.test.ts +16 -14
  91. package/src/store/user/slices/settings/action.ts +14 -8
  92. package/src/store/user/slices/settings/initialState.ts +3 -3
  93. package/src/store/user/slices/settings/selectors/general.test.ts +45 -0
  94. package/src/store/user/slices/settings/selectors/general.ts +40 -0
  95. package/src/store/user/slices/settings/selectors/index.ts +1 -0
  96. package/src/store/user/slices/settings/selectors/settings.test.ts +0 -39
  97. package/src/store/user/slices/settings/selectors/settings.ts +11 -34
  98. package/src/store/user/store.ts +5 -8
  99. package/src/types/exportConfig.ts +2 -2
  100. package/src/types/serverConfig.ts +2 -2
  101. package/src/types/user/index.ts +2 -2
  102. package/src/types/{settings/base.ts → user/settings/general.ts} +4 -1
  103. package/src/types/user/settings/index.ts +32 -0
  104. package/src/types/user/settings/keyVaults.ts +36 -0
  105. package/src/types/user/settings/modelProvider.ts +34 -0
  106. package/src/types/{settings → user/settings}/sync.ts +1 -1
  107. package/src/types/{settings → user/settings}/systemAgent.ts +1 -1
  108. package/src/types/user/settings/tool.ts +5 -0
  109. package/src/types/{settings → user/settings}/tts.ts +1 -1
  110. package/src/types/settings/index.ts +0 -33
  111. package/src/types/settings/modelProvider.ts +0 -62
@@ -76,10 +76,11 @@ export const dbSchemaV7 = {
76
76
  plugins:
77
77
  '&identifier, id, type, manifest.type, manifest.meta.title, manifest.meta.description, manifest.meta.author, createdAt, updatedAt',
78
78
  };
79
+
79
80
  // ************************************** //
80
- // ******* Version 9 - 2024-03-14 ******* //
81
+ // ******* Version 9 - 2024-05-11 ******* //
81
82
  // ************************************** //
82
- // - Added id to `plugins` table
83
+ // - Added tool_call_id to `messages` table
83
84
  export const dbSchemaV9 = {
84
85
  ...dbSchemaV7,
85
86
  messages:
@@ -1,7 +1,5 @@
1
1
  import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
2
 
3
- import { GlobalSettings } from '@/types/settings';
4
-
5
3
  import { UserModel } from '../user';
6
4
 
7
5
  describe('UserModel', () => {
@@ -51,17 +49,19 @@ describe('UserModel', () => {
51
49
  it('should update user settings', async () => {
52
50
  await UserModel.create(userData);
53
51
 
54
- await UserModel.updateSettings({ themeMode: 'dark' });
52
+ await UserModel.updateSettings({ general: { themeMode: 'dark' } });
55
53
 
56
54
  const userInDb = await UserModel.getUser();
57
55
 
58
- expect(userInDb).toHaveProperty('settings', { themeMode: 'dark' });
56
+ expect(userInDb).toHaveProperty('settings', {
57
+ general: { themeMode: 'dark' },
58
+ });
59
59
  });
60
60
 
61
61
  it('should reset user settings', async () => {
62
62
  await UserModel.create(userData);
63
63
 
64
- await UserModel.updateSettings({ themeMode: 'dark' });
64
+ await UserModel.updateSettings({ general: { themeMode: 'dark' } });
65
65
 
66
66
  await UserModel.resetSettings();
67
67
 
@@ -2,10 +2,9 @@ import { DeepPartial } from 'utility-types';
2
2
 
3
3
  import { BaseModel } from '@/database/client/core';
4
4
  import { LobeAgentConfig } from '@/types/agent';
5
- import { GlobalSettings } from '@/types/settings';
6
5
  import { uuid } from '@/utils/uuid';
7
6
 
8
- import { DB_User, DB_UserSchema } from '../schemas/user';
7
+ import { DB_Settings, DB_User, DB_UserSchema } from '../schemas/user';
9
8
 
10
9
  class _UserModel extends BaseModel {
11
10
  constructor() {
@@ -42,7 +41,7 @@ class _UserModel extends BaseModel {
42
41
 
43
42
  // **************** Update *************** //
44
43
 
45
- async updateSettings(settings: DeepPartial<GlobalSettings>) {
44
+ async updateSettings(settings: DeepPartial<DB_Settings>) {
46
45
  const user = await this.getUser();
47
46
 
48
47
  return this.update(user.id, { settings: settings as any });
@@ -3,16 +3,22 @@ import { z } from 'zod';
3
3
  import { AgentSchema } from '@/database/client/schemas/session';
4
4
  import { LobeMetaDataSchema } from '@/types/meta';
5
5
 
6
+ const generalSechma = z.object({
7
+ fontSize: z.number().default(14),
8
+ language: z.string(),
9
+ neutralColor: z.string().optional(),
10
+ password: z.string(),
11
+ themeMode: z.string(),
12
+ });
13
+
6
14
  const settingsSchema = z.object({
7
15
  defaultAgent: z.object({
8
16
  config: AgentSchema,
9
17
  meta: LobeMetaDataSchema,
10
18
  }),
11
- fontSize: z.number().default(14),
12
- language: z.string(),
19
+ general: generalSechma.partial().optional(),
20
+ keyVaults: z.any().optional(),
13
21
  languageModel: z.any().optional(),
14
- password: z.string(),
15
- themeMode: z.string(),
16
22
  tts: z.object({
17
23
  openAI: z.object({
18
24
  sttModel: z.string(),
@@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next';
11
11
 
12
12
  import { FORM_STYLE } from '@/const/layoutTokens';
13
13
  import { useUserStore } from '@/store/user';
14
- import { settingsSelectors } from '@/store/user/selectors';
14
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
15
15
 
16
16
  import { useStore } from '../store';
17
17
  import { SessionLoadingState } from '../store/initialState';
@@ -30,7 +30,7 @@ const AgentMeta = memo(() => {
30
30
  s.autocompleteMeta,
31
31
  s.autocompleteAllMeta,
32
32
  ]);
33
- const locale = useUserStore(settingsSelectors.currentLanguage);
33
+ const locale = useUserStore(userGeneralSettingsSelectors.currentLanguage);
34
34
  const loading = useStore((s) => s.autocompleteLoading);
35
35
  const meta = useStore((s) => s.meta, isEqual);
36
36
 
@@ -132,4 +132,4 @@ const AgentMeta = memo(() => {
132
132
  return <Form items={[metaData]} itemsType={'group'} variant={'pure'} {...FORM_STYLE} />;
133
133
  });
134
134
 
135
- export default AgentMeta;
135
+ export default AgentMeta;
@@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
10
10
 
11
11
  import { FORM_STYLE } from '@/const/layoutTokens';
12
12
  import { useUserStore } from '@/store/user';
13
- import { settingsSelectors } from '@/store/user/selectors';
13
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
14
14
 
15
15
  import { useStore } from '../store';
16
16
  import { useAgentSyncSettings } from '../useSyncAgemtSettings';
@@ -24,7 +24,7 @@ const AgentTTS = memo(() => {
24
24
  const { t } = useTranslation('setting');
25
25
  const [form] = Form.useForm();
26
26
  const voiceList = useUserStore((s) => {
27
- const locale = settingsSelectors.currentLanguage(s);
27
+ const locale = userGeneralSettingsSelectors.currentLanguage(s);
28
28
  return (all?: boolean) => new VoiceList(all ? undefined : locale);
29
29
  });
30
30
  const [showAllLocaleVoice, ttsService, updateConfig] = useStore((s) => [
@@ -9,7 +9,7 @@ import { agentSelectors } from '@/store/agent/slices/chat';
9
9
  import { useChatStore } from '@/store/chat';
10
10
  import { chatSelectors } from '@/store/chat/selectors';
11
11
  import { useUserStore } from '@/store/user';
12
- import { settingsSelectors } from '@/store/user/selectors';
12
+ import { settingsSelectors, userGeneralSettingsSelectors } from '@/store/user/selectors';
13
13
  import { ChatMessageError } from '@/types/message';
14
14
  import { getMessageError } from '@/utils/fetch';
15
15
 
@@ -22,7 +22,7 @@ interface STTConfig extends SWRConfiguration {
22
22
  const useBrowserSTT = (config: STTConfig) => {
23
23
  const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
24
24
  const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
25
- const locale = useUserStore(settingsSelectors.currentLanguage);
25
+ const locale = useUserStore(userGeneralSettingsSelectors.currentLanguage);
26
26
 
27
27
  const autoStop = ttsSettings.sttAutoStop;
28
28
  const sttLocale =
@@ -12,7 +12,7 @@ import { agentSelectors } from '@/store/agent/selectors';
12
12
  import { useChatStore } from '@/store/chat';
13
13
  import { chatSelectors } from '@/store/chat/slices/message/selectors';
14
14
  import { useUserStore } from '@/store/user';
15
- import { settingsSelectors } from '@/store/user/selectors';
15
+ import { settingsSelectors, userGeneralSettingsSelectors } from '@/store/user/selectors';
16
16
  import { ChatMessageError } from '@/types/message';
17
17
  import { getMessageError } from '@/utils/fetch';
18
18
 
@@ -25,7 +25,7 @@ interface STTConfig extends SWRConfiguration {
25
25
  const useOpenaiSTT = (config: STTConfig) => {
26
26
  const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
27
27
  const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
28
- const locale = useUserStore(settingsSelectors.currentLanguage);
28
+ const locale = useUserStore(userGeneralSettingsSelectors.currentLanguage);
29
29
 
30
30
  const autoStop = ttsSettings.sttAutoStop;
31
31
  const sttLocale =
@@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
8
8
 
9
9
  import { ModelProvider } from '@/libs/agent-runtime';
10
10
  import { useUserStore } from '@/store/user';
11
- import { modelConfigSelectors } from '@/store/user/selectors';
11
+ import { keyVaultsConfigSelectors } from '@/store/user/selectors';
12
12
 
13
13
  import { FormAction } from '../style';
14
14
 
@@ -17,10 +17,10 @@ const BedrockForm = memo(() => {
17
17
  const [showRegion, setShow] = useState(false);
18
18
 
19
19
  const [accessKeyId, secretAccessKey, region, setConfig] = useUserStore((s) => [
20
- modelConfigSelectors.bedrockConfig(s).accessKeyId,
21
- modelConfigSelectors.bedrockConfig(s).secretAccessKey,
22
- modelConfigSelectors.bedrockConfig(s).region,
23
- s.setModelProviderConfig,
20
+ keyVaultsConfigSelectors.bedrockConfig(s).accessKeyId,
21
+ keyVaultsConfigSelectors.bedrockConfig(s).secretAccessKey,
22
+ keyVaultsConfigSelectors.bedrockConfig(s).region,
23
+ s.updateKeyVaultConfig,
24
24
  ]);
25
25
 
26
26
  const theme = useTheme();
@@ -5,8 +5,8 @@ import { ReactNode, memo, useState } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { useUserStore } from '@/store/user';
8
- import { settingsSelectors } from '@/store/user/selectors';
9
- import { GlobalLLMProviderKey } from '@/types/settings';
8
+ import { keyVaultsConfigSelectors } from '@/store/user/selectors';
9
+ import { GlobalLLMProviderKey } from '@/types/user/settings';
10
10
 
11
11
  import { FormAction } from '../style';
12
12
 
@@ -24,9 +24,9 @@ const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
24
24
  const [showProxy, setShow] = useState(false);
25
25
 
26
26
  const [apiKey, proxyUrl, setConfig] = useUserStore((s) => [
27
- settingsSelectors.providerConfig(provider)(s)?.apiKey,
28
- settingsSelectors.providerConfig(provider)(s)?.endpoint,
29
- s.setModelProviderConfig,
27
+ keyVaultsConfigSelectors.getVaultByProvider(provider)(s)?.apiKey,
28
+ keyVaultsConfigSelectors.getVaultByProvider(provider)(s)?.baseURL,
29
+ s.updateKeyVaultConfig,
30
30
  ]);
31
31
 
32
32
  return (
@@ -5,7 +5,7 @@ import { Center, Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { ModelProvider } from '@/libs/agent-runtime';
7
7
  import { useChatStore } from '@/store/chat';
8
- import { GlobalLLMProviderKey } from '@/types/settings';
8
+ import { GlobalLLMProviderKey } from '@/types/user/settings';
9
9
 
10
10
  import BedrockForm from './Bedrock';
11
11
  import ProviderApiKeyForm from './ProviderApiKeyForm';
@@ -15,9 +15,9 @@ interface AccessCodeFormProps {
15
15
 
16
16
  const AccessCodeForm = memo<AccessCodeFormProps>(({ id }) => {
17
17
  const { t } = useTranslation('error');
18
- const [password, setSettings] = useUserStore((s) => [
19
- settingsSelectors.currentSettings(s).password,
20
- s.setSettings,
18
+ const [password, updateKeyVaults] = useUserStore((s) => [
19
+ settingsSelectors.password(s),
20
+ s.updateKeyVaults,
21
21
  ]);
22
22
  const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
23
23
 
@@ -31,7 +31,7 @@ const AccessCodeForm = memo<AccessCodeFormProps>(({ id }) => {
31
31
  <Input.Password
32
32
  autoComplete={'new-password'}
33
33
  onChange={(e) => {
34
- setSettings({ password: e.target.value });
34
+ updateKeyVaults({ password: e.target.value });
35
35
  }}
36
36
  placeholder={t('unlock.password.placeholder')}
37
37
  type={'block'}
@@ -4,7 +4,7 @@ import { Md5 } from 'ts-md5';
4
4
  import { useAgentStore } from '@/store/agent';
5
5
  import { agentSelectors } from '@/store/agent/slices/chat';
6
6
  import { useUserStore } from '@/store/user';
7
- import { settingsSelectors } from '@/store/user/selectors';
7
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
8
8
 
9
9
  import FilePlayer from './FilePlayer';
10
10
  import InitPlayer, { TTSProps } from './InitPlayer';
@@ -12,7 +12,7 @@ import InitPlayer, { TTSProps } from './InitPlayer';
12
12
  const TTS = memo<TTSProps>(
13
13
  (props) => {
14
14
  const { file, voice, content, contentMd5 } = props;
15
- const lang = useUserStore(settingsSelectors.currentLanguage);
15
+ const lang = useUserStore(userGeneralSettingsSelectors.currentLanguage);
16
16
  const currentVoice = useAgentStore(agentSelectors.currentAgentTTSVoice(lang));
17
17
 
18
18
  const md5 = useMemo(() => Md5.hashStr(content).toString(), [content]);
@@ -2,7 +2,7 @@ import { Markdown } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
 
4
4
  import { useUserStore } from '@/store/user';
5
- import { settingsSelectors } from '@/store/user/selectors';
5
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
6
6
 
7
7
  import Loading from '../Loading';
8
8
 
@@ -12,7 +12,7 @@ export interface PluginMarkdownTypeProps {
12
12
  }
13
13
 
14
14
  const PluginMarkdownType = memo<PluginMarkdownTypeProps>(({ content, loading }) => {
15
- const fontSize = useUserStore((s) => settingsSelectors.currentSettings(s).fontSize);
15
+ const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize);
16
16
  if (loading) return <Loading />;
17
17
 
18
18
  return (
@@ -1,52 +1,60 @@
1
- import { useTheme } from 'antd-style';
1
+ import { css, cx, useTheme } from 'antd-style';
2
+ import { Center } from 'react-layout-kit';
3
+
4
+ const container = css`
5
+ circle {
6
+ animation: bubble 1.5s cubic-bezier(0.05, 0.2, 0.35, 1) infinite;
7
+ }
8
+
9
+ circle:nth-child(2) {
10
+ animation-delay: 0.3s;
11
+ }
12
+
13
+ circle:nth-child(3) {
14
+ animation-delay: 0.6s;
15
+ }
16
+
17
+ @keyframes bubble {
18
+ 0% {
19
+ opacity: 1;
20
+
21
+ /* transform: translateY(0); */
22
+ }
23
+
24
+ 25% {
25
+ opacity: 0.5;
26
+
27
+ /* transform: translateY(-4px); */
28
+ }
29
+
30
+ 75% {
31
+ opacity: 0.25;
32
+
33
+ /* transform: translateY(4px); */
34
+ }
35
+
36
+ to {
37
+ opacity: 1;
38
+
39
+ /* transform: translateY(0); */
40
+ }
41
+ }
42
+ `;
2
43
 
3
44
  const Svg = () => (
4
- <svg viewBox="0 0 32 24" xmlns="http://www.w3.org/2000/svg">
5
- <circle cx="0" cy="12" r="0" transform="translate(8 0)">
6
- <animate
7
- attributeName="r"
8
- begin="0"
9
- calcMode="spline"
10
- dur="1.2s"
11
- keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
12
- keyTimes="0;0.2;0.7;1"
13
- repeatCount="indefinite"
14
- values="0; 4; 0; 0"
15
- />
16
- </circle>
17
- <circle cx="0" cy="12" r="0" transform="translate(16 0)">
18
- <animate
19
- attributeName="r"
20
- begin="0.3"
21
- calcMode="spline"
22
- dur="1.2s"
23
- keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
24
- keyTimes="0;0.2;0.7;1"
25
- repeatCount="indefinite"
26
- values="0; 4; 0; 0"
27
- />
28
- </circle>
29
- <circle cx="0" cy="12" r="0" transform="translate(24 0)">
30
- <animate
31
- attributeName="r"
32
- begin="0.6"
33
- calcMode="spline"
34
- dur="1.2s"
35
- keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
36
- keyTimes="0;0.2;0.7;1"
37
- repeatCount="indefinite"
38
- values="0; 4; 0; 0"
39
- />
40
- </circle>
45
+ <svg className={cx(container)} viewBox="0 0 60 32" xmlns="http://www.w3.org/2000/svg">
46
+ <circle cx="7" cy="16" r="6"></circle>
47
+ <circle cx="30" cy="16" r="6"></circle>
48
+ <circle cx="53" cy="16" r="6"></circle>
41
49
  </svg>
42
50
  );
43
51
 
44
52
  const BubblesLoading = () => {
45
- const { colorTextTertiary } = useTheme();
53
+ const theme = useTheme();
46
54
  return (
47
- <div style={{ fill: colorTextTertiary, height: 24, width: 32 }}>
55
+ <Center style={{ fill: theme.colorTextSecondary, height: 24, width: 32 }}>
48
56
  <Svg />
49
- </div>
57
+ </Center>
50
58
  );
51
59
  };
52
60
 
@@ -11,7 +11,7 @@ import { chatSelectors } from '@/store/chat/selectors';
11
11
  import { useSessionStore } from '@/store/session';
12
12
  import { sessionMetaSelectors } from '@/store/session/selectors';
13
13
  import { useUserStore } from '@/store/user';
14
- import { settingsSelectors } from '@/store/user/selectors';
14
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
15
15
  import { ChatMessage } from '@/types/message';
16
16
 
17
17
  import ErrorMessageExtra, { getErrorAlertConfig } from '../../Error';
@@ -38,7 +38,7 @@ export interface ChatListItemProps {
38
38
  }
39
39
 
40
40
  const Item = memo<ChatListItemProps>(({ index, id }) => {
41
- const fontSize = useUserStore((s) => settingsSelectors.currentSettings(s).fontSize);
41
+ const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize);
42
42
  const { t } = useTranslation('common');
43
43
  const { styles, cx } = useStyles();
44
44
  const [type = 'chat'] = useAgentStore((s) => {
@@ -7,13 +7,13 @@ import { useTranslation } from 'react-i18next';
7
7
  import { useToolStore } from '@/store/tool';
8
8
  import { pluginSelectors } from '@/store/tool/selectors';
9
9
  import { useUserStore } from '@/store/user';
10
- import { settingsSelectors } from '@/store/user/selectors';
10
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
11
11
 
12
12
  const EmojiPicker = dynamic(() => import('@lobehub/ui/es/EmojiPicker'), { ssr: false });
13
13
 
14
14
  const LocalForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form, mode }) => {
15
15
  const isEditMode = mode === 'edit';
16
- const locale = useUserStore(settingsSelectors.currentLanguage);
16
+ const locale = useUserStore(userGeneralSettingsSelectors.currentLanguage);
17
17
  const { t } = useTranslation('plugin');
18
18
 
19
19
  const pluginIds = useToolStore(pluginSelectors.storeAndInstallPluginsIdList);
@@ -31,7 +31,11 @@ export const PluginStore = memo<PluginStoreProps>(({ setOpen, open }) => {
31
31
  title={t('store.title')}
32
32
  width={800}
33
33
  >
34
- <Flexbox gap={mobile ? 8 : 16} width={'100%'}>
34
+ <Flexbox
35
+ gap={ mobile ? 8 : 16 }
36
+ style={{ maxHeight: mobile ? '-webkit-fill-available' : 'inherit' }}
37
+ width={'100%'}
38
+ >
35
39
  <Segmented
36
40
  block
37
41
  onChange={(v) => {
@@ -50,4 +54,4 @@ export const PluginStore = memo<PluginStoreProps>(({ setOpen, open }) => {
50
54
  );
51
55
  });
52
56
 
53
- export default PluginStore;
57
+ export default PluginStore;
@@ -8,12 +8,12 @@ import { useTranslation } from 'react-i18next';
8
8
  import Menu, { type MenuProps } from '@/components/Menu';
9
9
  import { localeOptions } from '@/locales/resources';
10
10
  import { useUserStore } from '@/store/user';
11
- import { settingsSelectors } from '@/store/user/selectors';
11
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
12
12
 
13
13
  const LangButton = memo(() => {
14
14
  const theme = useTheme();
15
15
  const [language, switchLocale] = useUserStore((s) => [
16
- settingsSelectors.currentSettings(s).language,
16
+ userGeneralSettingsSelectors.language(s),
17
17
  s.switchLocale,
18
18
  ]);
19
19
 
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
7
7
 
8
8
  import Menu, { type MenuProps } from '@/components/Menu';
9
9
  import { useUserStore } from '@/store/user';
10
- import { settingsSelectors } from '@/store/user/selectors';
10
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
11
11
 
12
12
  const themeIcons = {
13
13
  auto: Monitor,
@@ -18,7 +18,7 @@ const themeIcons = {
18
18
  const ThemeButton = memo(() => {
19
19
  const theme = useTheme();
20
20
  const [themeMode, switchThemeMode] = useUserStore((s) => [
21
- settingsSelectors.currentSettings(s).themeMode,
21
+ userGeneralSettingsSelectors.currentThemeMode(s),
22
22
  s.switchThemeMode,
23
23
  ]);
24
24
 
@@ -1,14 +1,17 @@
1
1
  import { LOBE_CHAT_ACCESS_CODE, OPENAI_API_KEY_HEADER_KEY, OPENAI_END_POINT } from '@/const/fetch';
2
2
  import { useUserStore } from '@/store/user';
3
- import { modelConfigSelectors, settingsSelectors } from '@/store/user/selectors';
3
+ import {
4
+ keyVaultsConfigSelectors,
5
+ settingsSelectors,
6
+ } from '@/store/user/selectors';
4
7
 
5
8
  // TODO: Need to be removed after tts refactor
6
9
  // eslint-disable-next-line no-undef
7
10
  export const createHeaderWithOpenAI = (header?: HeadersInit): HeadersInit => {
8
- const openai = modelConfigSelectors.openAIConfig(useUserStore.getState());
11
+ const openai = keyVaultsConfigSelectors.openAIConfig(useUserStore.getState());
9
12
 
10
13
  const apiKey = openai.apiKey || '';
11
- const endpoint = openai.endpoint || '';
14
+ const endpoint = openai.baseURL || '';
12
15
 
13
16
  // eslint-disable-next-line no-undef
14
17
  return {
@@ -14,7 +14,7 @@ import { API_ENDPOINTS } from '@/services/_url';
14
14
  import { useAgentStore } from '@/store/agent';
15
15
  import { agentSelectors } from '@/store/agent/slices/chat';
16
16
  import { useUserStore } from '@/store/user';
17
- import { settingsSelectors } from '@/store/user/selectors';
17
+ import { settingsSelectors, userGeneralSettingsSelectors } from '@/store/user/selectors';
18
18
  import { TTSServer } from '@/types/agent';
19
19
 
20
20
  interface TTSConfig extends TTSOptions {
@@ -26,7 +26,7 @@ interface TTSConfig extends TTSOptions {
26
26
  export const useTTS = (content: string, config?: TTSConfig) => {
27
27
  const ttsSettings = useUserStore(settingsSelectors.currentTTS, isEqual);
28
28
  const ttsAgentSettings = useAgentStore(agentSelectors.currentAgentTTS, isEqual);
29
- const lang = useUserStore(settingsSelectors.currentLanguage);
29
+ const lang = useUserStore(userGeneralSettingsSelectors.currentLanguage);
30
30
  const voice = useAgentStore(agentSelectors.currentAgentTTSVoice(lang));
31
31
  let useSelectedTTS;
32
32
  let options: any = {};
@@ -14,7 +14,7 @@ import {
14
14
  LOBE_THEME_PRIMARY_COLOR,
15
15
  } from '@/const/theme';
16
16
  import { useUserStore } from '@/store/user';
17
- import { settingsSelectors } from '@/store/user/selectors';
17
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
18
18
  import { GlobalStyle } from '@/styles';
19
19
  import { setCookie } from '@/utils/cookie';
20
20
 
@@ -86,11 +86,11 @@ const AppTheme = memo<AppThemeProps>(
86
86
  // console.debug('server:appearance', defaultAppearance);
87
87
  // console.debug('server:primaryColor', defaultPrimaryColor);
88
88
  // console.debug('server:neutralColor', defaultNeutralColor);
89
- const themeMode = useUserStore(settingsSelectors.currentThemeMode);
89
+ const themeMode = useUserStore(userGeneralSettingsSelectors.currentThemeMode);
90
90
  const { styles, cx } = useStyles();
91
91
  const [primaryColor, neutralColor] = useUserStore((s) => [
92
- settingsSelectors.currentSettings(s).primaryColor,
93
- settingsSelectors.currentSettings(s).neutralColor,
92
+ userGeneralSettingsSelectors.primaryColor(s),
93
+ userGeneralSettingsSelectors.neutralColor(s),
94
94
  ]);
95
95
 
96
96
  useEffect(() => {
@@ -25,7 +25,6 @@ export enum ModelProvider {
25
25
  Anthropic = 'anthropic',
26
26
  Azure = 'azure',
27
27
  Bedrock = 'bedrock',
28
- ChatGLM = 'chatglm',
29
28
  DeepSeek = 'deepseek',
30
29
  Google = 'google',
31
30
  Groq = 'groq',
@@ -37,7 +36,9 @@ export enum ModelProvider {
37
36
  OpenRouter = 'openrouter',
38
37
  Perplexity = 'perplexity',
39
38
  TogetherAI = 'togetherai',
40
- Tongyi = 'tongyi',
39
+ // Tongyi = 'tongyi',
41
40
  ZeroOne = 'zeroone',
42
41
  ZhiPu = 'zhipu',
43
42
  }
43
+
44
+ export type ModelProviderKey = Lowercase<keyof typeof ModelProvider>;