@lobehub/chat 1.57.0 → 1.58.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 (114) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/docker-compose/local/docker-compose.yml +1 -0
  4. package/locales/ar/modelProvider.json +24 -0
  5. package/locales/ar/models.json +60 -0
  6. package/locales/ar/providers.json +12 -0
  7. package/locales/bg-BG/modelProvider.json +24 -0
  8. package/locales/bg-BG/models.json +60 -0
  9. package/locales/bg-BG/providers.json +12 -0
  10. package/locales/de-DE/modelProvider.json +24 -0
  11. package/locales/de-DE/models.json +60 -0
  12. package/locales/de-DE/providers.json +12 -0
  13. package/locales/en-US/modelProvider.json +24 -0
  14. package/locales/en-US/models.json +60 -0
  15. package/locales/en-US/providers.json +12 -0
  16. package/locales/es-ES/modelProvider.json +24 -0
  17. package/locales/es-ES/models.json +60 -0
  18. package/locales/es-ES/providers.json +12 -0
  19. package/locales/fa-IR/modelProvider.json +30 -0
  20. package/locales/fa-IR/models.json +60 -0
  21. package/locales/fa-IR/providers.json +12 -0
  22. package/locales/fr-FR/modelProvider.json +24 -0
  23. package/locales/fr-FR/models.json +60 -0
  24. package/locales/fr-FR/providers.json +12 -0
  25. package/locales/it-IT/modelProvider.json +24 -0
  26. package/locales/it-IT/models.json +60 -0
  27. package/locales/it-IT/providers.json +12 -0
  28. package/locales/ja-JP/modelProvider.json +24 -0
  29. package/locales/ja-JP/models.json +60 -0
  30. package/locales/ja-JP/providers.json +12 -0
  31. package/locales/ko-KR/modelProvider.json +24 -0
  32. package/locales/ko-KR/models.json +60 -0
  33. package/locales/ko-KR/providers.json +12 -0
  34. package/locales/nl-NL/modelProvider.json +24 -0
  35. package/locales/nl-NL/models.json +60 -0
  36. package/locales/nl-NL/providers.json +12 -0
  37. package/locales/pl-PL/modelProvider.json +24 -0
  38. package/locales/pl-PL/models.json +60 -0
  39. package/locales/pl-PL/providers.json +12 -0
  40. package/locales/pt-BR/modelProvider.json +24 -0
  41. package/locales/pt-BR/models.json +60 -0
  42. package/locales/pt-BR/providers.json +12 -0
  43. package/locales/ru-RU/modelProvider.json +24 -0
  44. package/locales/ru-RU/models.json +60 -0
  45. package/locales/ru-RU/providers.json +12 -0
  46. package/locales/tr-TR/modelProvider.json +30 -0
  47. package/locales/tr-TR/models.json +60 -0
  48. package/locales/tr-TR/providers.json +12 -0
  49. package/locales/vi-VN/modelProvider.json +24 -0
  50. package/locales/vi-VN/models.json +60 -0
  51. package/locales/vi-VN/providers.json +12 -0
  52. package/locales/zh-CN/modelProvider.json +24 -0
  53. package/locales/zh-CN/models.json +1112 -1052
  54. package/locales/zh-CN/providers.json +80 -68
  55. package/locales/zh-TW/modelProvider.json +24 -0
  56. package/locales/zh-TW/models.json +60 -0
  57. package/locales/zh-TW/providers.json +12 -0
  58. package/package.json +4 -2
  59. package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Files/FileItem/File.tsx +1 -1
  60. package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/index.tsx +19 -9
  61. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/index.tsx +1 -2
  62. package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Main.tsx +15 -1
  63. package/src/app/[variants]/(main)/chat/(workspace)/_layout/Mobile/ChatHeader/index.tsx +0 -2
  64. package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/index.tsx +1 -1
  65. package/src/app/[variants]/(main)/chat/settings/page.tsx +95 -5
  66. package/src/app/[variants]/(main)/settings/provider/(detail)/azureai/page.tsx +58 -0
  67. package/src/app/[variants]/(main)/settings/provider/features/CreateNewProvider/index.tsx +13 -2
  68. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +6 -8
  69. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/index.tsx +5 -6
  70. package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelConfigModal/index.tsx +4 -3
  71. package/src/app/[variants]/(main)/settings/provider/features/ModelList/ProviderSettingsContext.ts +2 -0
  72. package/src/app/[variants]/(main)/settings/provider/features/ModelList/index.tsx +6 -7
  73. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +1 -1
  74. package/src/config/aiModels/azureai.ts +18 -0
  75. package/src/config/aiModels/index.ts +3 -0
  76. package/src/config/modelProviders/azure.ts +2 -1
  77. package/src/config/modelProviders/azureai.ts +19 -0
  78. package/src/config/modelProviders/index.ts +3 -0
  79. package/src/database/server/models/aiProvider.ts +2 -0
  80. package/src/features/AgentSetting/AgentMeta/index.tsx +19 -9
  81. package/src/features/AgentSetting/AgentPrompt/index.tsx +32 -2
  82. package/src/features/AgentSetting/AgentSettings.tsx +4 -5
  83. package/src/features/AgentSetting/AgentSettingsProvider.tsx +17 -0
  84. package/src/features/AgentSetting/StoreUpdater.tsx +5 -2
  85. package/src/features/AgentSetting/index.tsx +1 -1
  86. package/src/features/AgentSetting/store/initialState.ts +2 -1
  87. package/src/hooks/useInterceptingRoutes.test.ts +1 -1
  88. package/src/hooks/useInterceptingRoutes.ts +1 -1
  89. package/src/layout/GlobalProvider/StoreInitialization.tsx +1 -1
  90. package/src/libs/agent-runtime/AgentRuntime.ts +13 -6
  91. package/src/libs/agent-runtime/azureai/index.ts +109 -0
  92. package/src/libs/agent-runtime/baichuan/index.test.ts +8 -250
  93. package/src/libs/agent-runtime/cloudflare/index.ts +22 -18
  94. package/src/libs/agent-runtime/index.ts +1 -0
  95. package/src/libs/agent-runtime/types/type.ts +1 -0
  96. package/src/libs/agent-runtime/utils/streams/__snapshots__/protocol.test.ts.snap +331 -0
  97. package/src/libs/agent-runtime/utils/streams/protocol.test.ts +137 -0
  98. package/src/libs/agent-runtime/utils/streams/protocol.ts +34 -0
  99. package/src/locales/default/modelProvider.ts +25 -0
  100. package/src/server/modules/AgentRuntime/index.ts +8 -1
  101. package/src/services/chat.ts +12 -3
  102. package/src/store/agent/slices/chat/action.test.ts +3 -3
  103. package/src/store/agent/slices/chat/action.ts +2 -5
  104. package/src/types/aiProvider.ts +1 -0
  105. package/src/types/user/settings/keyVaults.ts +1 -0
  106. package/src/app/[variants]/(main)/chat/settings/features/EditPage.tsx +0 -45
  107. package/src/features/AgentSetting/AgentSettingsStore.tsx +0 -14
  108. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Files/FileItem/Image.tsx +0 -0
  109. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Files/FileItem/index.tsx +0 -0
  110. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Files/FileItem/style.ts +0 -0
  111. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Files/index.tsx +0 -0
  112. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/InputArea/Container.tsx +0 -0
  113. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/InputArea/index.tsx +0 -0
  114. /package/src/{features → app/[variants]/(main)/chat/(workspace)/@conversation/features}/ChatInput/Mobile/Send.tsx +0 -0
@@ -1,7 +1,97 @@
1
- import EditPage from './features/EditPage';
1
+ 'use client';
2
2
 
3
- const Page = () => {
4
- return <EditPage />;
5
- };
3
+ import { TabsNav } from '@lobehub/ui';
4
+ import isEqual from 'fast-deep-equal';
5
+ import { memo, useState } from 'react';
6
+ import { useTranslation } from 'react-i18next';
6
7
 
7
- export default Page;
8
+ import PageTitle from '@/components/PageTitle';
9
+ import { INBOX_SESSION_ID } from '@/const/session';
10
+ import { AgentSettingsProvider } from '@/features/AgentSetting';
11
+ import AgentChat from '@/features/AgentSetting/AgentChat';
12
+ import AgentMeta from '@/features/AgentSetting/AgentMeta';
13
+ import AgentModal from '@/features/AgentSetting/AgentModal';
14
+ import AgentPlugin from '@/features/AgentSetting/AgentPlugin';
15
+ import AgentPrompt from '@/features/AgentSetting/AgentPrompt';
16
+ import AgentTTS from '@/features/AgentSetting/AgentTTS';
17
+ import { useAgentStore } from '@/store/agent';
18
+ import { agentSelectors } from '@/store/agent/selectors';
19
+ import { ChatSettingsTabs } from '@/store/global/initialState';
20
+ import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
21
+ import { useSessionStore } from '@/store/session';
22
+ import { sessionMetaSelectors } from '@/store/session/selectors';
23
+
24
+ const EditPage = memo(() => {
25
+ const { t } = useTranslation('setting');
26
+ const [tab, setTab] = useState(ChatSettingsTabs.Prompt);
27
+
28
+ const [id, updateAgentMeta, title] = useSessionStore((s) => [
29
+ s.activeId,
30
+ s.updateSessionMeta,
31
+ sessionMetaSelectors.currentAgentTitle(s),
32
+ ]);
33
+ const [useFetchAgentConfig, updateAgentConfig] = useAgentStore((s) => [
34
+ s.useFetchAgentConfig,
35
+ s.updateAgentConfig,
36
+ ]);
37
+
38
+ const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
39
+ const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
40
+
41
+ const { isLoading } = useFetchAgentConfig(id);
42
+ const { enablePlugins } = useServerConfigStore(featureFlagsSelectors);
43
+
44
+ return (
45
+ <>
46
+ <PageTitle title={t('header.sessionWithName', { name: title })} />
47
+
48
+ <TabsNav
49
+ items={[
50
+ {
51
+ key: ChatSettingsTabs.Prompt,
52
+ label: t('settingAgent.prompt.title'),
53
+ },
54
+ (id !== INBOX_SESSION_ID && {
55
+ key: ChatSettingsTabs.Meta,
56
+ label: t('settingAgent.title'),
57
+ }) as any,
58
+ {
59
+ key: ChatSettingsTabs.Chat,
60
+ label: t('settingChat.title'),
61
+ },
62
+ {
63
+ key: ChatSettingsTabs.Modal,
64
+ label: t('settingModel.title'),
65
+ },
66
+ {
67
+ key: ChatSettingsTabs.TTS,
68
+ label: t('settingTTS.title'),
69
+ },
70
+ (enablePlugins && {
71
+ key: ChatSettingsTabs.Plugin,
72
+ label: t('settingPlugin.title'),
73
+ }) as any,
74
+ ]}
75
+ onChange={(value) => setTab(value as ChatSettingsTabs)}
76
+ variant={'compact'}
77
+ />
78
+ <AgentSettingsProvider
79
+ config={config}
80
+ id={id}
81
+ loading={isLoading}
82
+ meta={meta}
83
+ onConfigChange={updateAgentConfig}
84
+ onMetaChange={updateAgentMeta}
85
+ >
86
+ {tab === ChatSettingsTabs.Prompt && <AgentPrompt modal />}
87
+ {tab === ChatSettingsTabs.Meta && <AgentMeta />}
88
+ {tab === ChatSettingsTabs.Chat && <AgentChat />}
89
+ {tab === ChatSettingsTabs.Modal && <AgentModal />}
90
+ {tab === ChatSettingsTabs.TTS && <AgentTTS />}
91
+ {tab === ChatSettingsTabs.Plugin && <AgentPlugin />}
92
+ </AgentSettingsProvider>
93
+ </>
94
+ );
95
+ });
96
+
97
+ export default EditPage;
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+
3
+ import { useTranslation } from 'react-i18next';
4
+
5
+ import { FormInput, FormPassword } from '@/components/FormInput';
6
+ import { AzureAIProviderCard } from '@/config/modelProviders';
7
+ import { ModelProvider } from '@/libs/agent-runtime';
8
+ import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
9
+
10
+ import { KeyVaultsConfigKey, LLMProviderApiTokenKey, LLMProviderBaseUrlKey } from '../../const';
11
+ import { SkeletonInput } from '../../features/ProviderConfig';
12
+ import { ProviderItem } from '../../type';
13
+ import ProviderDetail from '../[id]';
14
+
15
+ const providerKey = ModelProvider.AzureAI;
16
+
17
+ const useProviderCard = (): ProviderItem => {
18
+ const { t } = useTranslation('modelProvider');
19
+
20
+ const isLoading = useAiInfraStore(aiProviderSelectors.isAiProviderConfigLoading(providerKey));
21
+
22
+ return {
23
+ ...AzureAIProviderCard,
24
+ apiKeyItems: [
25
+ {
26
+ children: isLoading ? (
27
+ <SkeletonInput />
28
+ ) : (
29
+ <FormPassword
30
+ autoComplete={'new-password'}
31
+ placeholder={t('azureai.token.placeholder')}
32
+ />
33
+ ),
34
+ desc: t('azureai.token.desc'),
35
+ label: t('azureai.token.title'),
36
+ name: [KeyVaultsConfigKey, LLMProviderApiTokenKey],
37
+ },
38
+ {
39
+ children: isLoading ? (
40
+ <SkeletonInput />
41
+ ) : (
42
+ <FormInput allowClear placeholder={t('azureai.endpoint.placeholder')} />
43
+ ),
44
+ desc: t('azureai.endpoint.desc'),
45
+ label: t('azureai.endpoint.title'),
46
+ name: [KeyVaultsConfigKey, LLMProviderBaseUrlKey],
47
+ },
48
+ ],
49
+ };
50
+ };
51
+
52
+ const Page = () => {
53
+ const card = useProviderCard();
54
+
55
+ return <ProviderDetail {...card} />;
56
+ };
57
+
58
+ export default Page;
@@ -1,6 +1,7 @@
1
+ import { ProviderIcon } from '@lobehub/icons';
1
2
  import { FormModal, Icon } from '@lobehub/ui';
2
3
  import type { FormItemProps } from '@lobehub/ui/es/Form/components/FormItem';
3
- import { App, Input, Radio } from 'antd';
4
+ import { App, Input, Select } from 'antd';
4
5
  import { BrainIcon } from 'lucide-react';
5
6
  import { useRouter } from 'next/navigation';
6
7
  import { memo, useState } from 'react';
@@ -87,15 +88,25 @@ const CreateNewProvider = memo<CreateNewProviderProps>(({ onClose, open }) => {
87
88
  const configItems: FormItemProps[] = [
88
89
  {
89
90
  children: (
90
- <Radio.Group
91
+ <Select
92
+ optionRender={({ label, value }) => (
93
+ <Flexbox align={'center'} gap={8} horizontal>
94
+ <ProviderIcon provider={value as string} size={18} />
95
+ {label}
96
+ </Flexbox>
97
+ )}
91
98
  options={[
92
99
  { label: 'OpenAI', value: 'openai' },
93
100
  { label: 'Anthropic', value: 'anthropic' },
94
101
  { label: 'Ollama', value: 'ollama' },
102
+ // { label: 'Azure AI', value: 'azureai' },
95
103
  ]}
104
+ placeholder={t('createNewAiProvider.sdkType.placeholder')}
105
+ variant={'filled'}
96
106
  />
97
107
  ),
98
108
  label: t('createNewAiProvider.sdkType.title'),
109
+ minWidth: 400,
99
110
  name: 'sdkType',
100
111
  rules: [{ message: t('createNewAiProvider.sdkType.required'), required: true }],
101
112
  },
@@ -11,12 +11,12 @@ interface ModelConfigFormProps {
11
11
  idEditable?: boolean;
12
12
  initialValues?: ChatModelCard;
13
13
  onFormInstanceReady: (instance: FormInstance) => void;
14
- showAzureDeployName?: boolean;
14
+ showDeployName?: boolean;
15
15
  type?: AiModelType;
16
16
  }
17
17
 
18
18
  const ModelConfigForm = memo<ModelConfigFormProps>(
19
- ({ showAzureDeployName, idEditable = true, onFormInstanceReady, initialValues }) => {
19
+ ({ showDeployName, idEditable = true, onFormInstanceReady, initialValues }) => {
20
20
  const { t } = useTranslation('modelProvider');
21
21
 
22
22
  const [formInstance] = Form.useForm();
@@ -55,15 +55,13 @@ const ModelConfigForm = memo<ModelConfigFormProps>(
55
55
  placeholder={t('providerModels.item.modelConfig.id.placeholder')}
56
56
  />
57
57
  </Form.Item>
58
- {showAzureDeployName && (
58
+ {showDeployName && (
59
59
  <Form.Item
60
- extra={t('providerModels.item.modelConfig.azureDeployName.extra')}
61
- label={t('providerModels.item.modelConfig.azureDeployName.title')}
60
+ extra={t('providerModels.item.modelConfig.deployName.extra')}
61
+ label={t('providerModels.item.modelConfig.deployName.title')}
62
62
  name={['config', 'deploymentName']}
63
63
  >
64
- <Input
65
- placeholder={t('providerModels.item.modelConfig.azureDeployName.placeholder')}
66
- />
64
+ <Input placeholder={t('providerModels.item.modelConfig.deployName.placeholder')} />
67
65
  </Form.Item>
68
66
  )}
69
67
  <Form.Item
@@ -1,11 +1,11 @@
1
1
  import { Modal } from '@lobehub/ui';
2
2
  import { Button, FormInstance } from 'antd';
3
- import { memo, useState } from 'react';
3
+ import { memo, use, useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- import { ModelProvider } from '@/libs/agent-runtime';
7
6
  import { useAiInfraStore } from '@/store/aiInfra';
8
7
 
8
+ import { ProviderSettingsContext } from '../ProviderSettingsContext';
9
9
  import ModelConfigForm from './Form';
10
10
 
11
11
  interface ModelConfigModalProps {
@@ -26,6 +26,8 @@ const ModelConfigModal = memo<ModelConfigModalProps>(({ open, setOpen }) => {
26
26
  setOpen(false);
27
27
  };
28
28
 
29
+ const { showDeployName } = use(ProviderSettingsContext);
30
+
29
31
  return (
30
32
  <Modal
31
33
  destroyOnClose
@@ -65,10 +67,7 @@ const ModelConfigModal = memo<ModelConfigModalProps>(({ open, setOpen }) => {
65
67
  title={t('providerModels.createNew.title')}
66
68
  zIndex={1251} // Select is 1150
67
69
  >
68
- <ModelConfigForm
69
- onFormInstanceReady={setFormInstance}
70
- showAzureDeployName={editingProvider === ModelProvider.Azure}
71
- />
70
+ <ModelConfigForm onFormInstanceReady={setFormInstance} showDeployName={showDeployName} />
72
71
  </Modal>
73
72
  );
74
73
  });
@@ -1,13 +1,13 @@
1
1
  import { Modal } from '@lobehub/ui';
2
2
  import { Button, FormInstance } from 'antd';
3
3
  import isEqual from 'fast-deep-equal';
4
- import { memo, useState } from 'react';
4
+ import { memo, use, useState } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
- import { ModelProvider } from '@/libs/agent-runtime';
8
7
  import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
9
8
 
10
9
  import ModelConfigForm from '../CreateNewModelModal/Form';
10
+ import { ProviderSettingsContext } from '../ProviderSettingsContext';
11
11
 
12
12
  interface ModelConfigModalProps {
13
13
  id: string;
@@ -28,6 +28,7 @@ const ModelConfigModal = memo<ModelConfigModalProps>(({ id, open, setOpen }) =>
28
28
  const closeModal = () => {
29
29
  setOpen(false);
30
30
  };
31
+ const { showDeployName } = use(ProviderSettingsContext);
31
32
 
32
33
  return (
33
34
  <Modal
@@ -66,7 +67,7 @@ const ModelConfigModal = memo<ModelConfigModalProps>(({ id, open, setOpen }) =>
66
67
  idEditable={false}
67
68
  initialValues={model}
68
69
  onFormInstanceReady={setFormInstance}
69
- showAzureDeployName={editingProvider === ModelProvider.Azure || editingProvider === ModelProvider.Doubao}
70
+ showDeployName={showDeployName}
70
71
  type={model?.type}
71
72
  />
72
73
  </Modal>
@@ -2,7 +2,9 @@ import { createContext } from 'react';
2
2
 
3
3
  export interface ProviderSettingsContextValue {
4
4
  modelEditable?: boolean;
5
+ sdkType?: string;
5
6
  showAddNewModel?: boolean;
7
+ showDeployName?: boolean;
6
8
  showModelFetcher?: boolean;
7
9
  }
8
10
 
@@ -3,7 +3,6 @@
3
3
  import { Suspense, memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
- import { ProviderSettingsContext } from '@/app/[variants]/(main)/settings/provider/features/ModelList/ProviderSettingsContext';
7
6
  import { useIsMobile } from '@/hooks/useIsMobile';
8
7
  import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
9
8
 
@@ -11,6 +10,7 @@ import DisabledModels from './DisabledModels';
11
10
  import EmptyModels from './EmptyModels';
12
11
  import EnabledModelList from './EnabledModelList';
13
12
  import ModelTitle from './ModelTitle';
13
+ import { ProviderSettingsContext, ProviderSettingsContextValue } from './ProviderSettingsContext';
14
14
  import SearchResult from './SearchResult';
15
15
  import SkeletonList from './SkeletonList';
16
16
 
@@ -41,19 +41,18 @@ const Content = memo<ContentProps>(({ id }) => {
41
41
  );
42
42
  });
43
43
 
44
- interface ModelListProps {
44
+ interface ModelListProps extends ProviderSettingsContextValue {
45
45
  id: string;
46
- modelEditable?: boolean;
47
- showAddNewModel?: boolean;
48
- showModelFetcher?: boolean;
49
46
  }
50
47
 
51
48
  const ModelList = memo<ModelListProps>(
52
- ({ id, showModelFetcher, showAddNewModel, modelEditable = true }) => {
49
+ ({ id, showModelFetcher, sdkType, showAddNewModel, showDeployName, modelEditable = true }) => {
53
50
  const mobile = useIsMobile();
54
51
 
55
52
  return (
56
- <ProviderSettingsContext value={{ modelEditable, showAddNewModel, showModelFetcher }}>
53
+ <ProviderSettingsContext
54
+ value={{ modelEditable, sdkType, showAddNewModel, showDeployName, showModelFetcher }}
55
+ >
57
56
  <Flexbox gap={16} paddingInline={mobile ? 12 : 0}>
58
57
  <ModelTitle
59
58
  provider={id}
@@ -127,7 +127,7 @@ const ProviderConfig = memo<ProviderConfigProps>(
127
127
  defaultShowBrowserRequest,
128
128
  disableBrowserRequest,
129
129
  showChecker = true,
130
- } = settings;
130
+ } = settings || {};
131
131
  const { t } = useTranslation('modelProvider');
132
132
  const [form] = Form.useForm();
133
133
  const { cx, styles, theme } = useStyles();
@@ -0,0 +1,18 @@
1
+ import { AIChatModelCard } from '@/types/aiModel';
2
+
3
+ const azureChatModels: AIChatModelCard[] = [
4
+ {
5
+ abilities: {
6
+ reasoning: true,
7
+ },
8
+ contextWindowTokens: 128_000,
9
+ displayName: 'DeepSeek R1',
10
+ id: 'DeepSeek-R1',
11
+ maxOutput: 4096,
12
+ type: 'chat',
13
+ },
14
+ ];
15
+
16
+ export const allModels = [...azureChatModels];
17
+
18
+ export default allModels;
@@ -4,6 +4,7 @@ import { default as ai21 } from './ai21';
4
4
  import { default as ai360 } from './ai360';
5
5
  import { default as anthropic } from './anthropic';
6
6
  import { default as azure } from './azure';
7
+ import { default as azureai } from './azureai';
7
8
  import { default as baichuan } from './baichuan';
8
9
  import { default as bedrock } from './bedrock';
9
10
  import { default as cloudflare } from './cloudflare';
@@ -68,6 +69,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({
68
69
  ai360,
69
70
  anthropic,
70
71
  azure,
72
+ azureai,
71
73
  baichuan,
72
74
  bedrock,
73
75
  cloudflare,
@@ -113,6 +115,7 @@ export { default as ai21 } from './ai21';
113
115
  export { default as ai360 } from './ai360';
114
116
  export { default as anthropic } from './anthropic';
115
117
  export { default as azure } from './azure';
118
+ export { default as azureai } from './azureai';
116
119
  export { default as baichuan } from './baichuan';
117
120
  export { default as bedrock } from './bedrock';
118
121
  export { default as cloudflare } from './cloudflare';
@@ -58,10 +58,11 @@ const Azure: ModelProviderCard = {
58
58
  'Azure 提供多种先进的AI模型,包括GPT-3.5和最新的GPT-4系列,支持多种数据类型和复杂任务,致力于安全、可靠和可持续的AI解决方案。',
59
59
  id: 'azure',
60
60
  modelsUrl: 'https://learn.microsoft.com/azure/ai-services/openai/concepts/models',
61
- name: 'Azure',
61
+ name: 'Azure OpenAI',
62
62
  settings: {
63
63
  defaultShowBrowserRequest: true,
64
64
  sdkType: 'azure',
65
+ showDeployName: true,
65
66
  },
66
67
  url: 'https://azure.microsoft.com',
67
68
  };
@@ -0,0 +1,19 @@
1
+ import { ModelProviderCard } from '@/types/llm';
2
+
3
+ // ref: https://learn.microsoft.com/azure/ai-services/openai/concepts/models
4
+ const Azure: ModelProviderCard = {
5
+ chatModels: [],
6
+ description:
7
+ 'Azure 提供多种先进的AI模型,包括GPT-3.5和最新的GPT-4系列,支持多种数据类型和复杂任务,致力于安全、可靠和可持续的AI解决方案。',
8
+ id: 'azureai',
9
+ modelsUrl: 'https://ai.azure.com/explore/models',
10
+ name: 'Azure AI',
11
+ settings: {
12
+ defaultShowBrowserRequest: true,
13
+ sdkType: 'azureai',
14
+ showDeployName: true,
15
+ },
16
+ url: 'https://ai.azure.com',
17
+ };
18
+
19
+ export default Azure;
@@ -4,6 +4,7 @@ import Ai21Provider from './ai21';
4
4
  import Ai360Provider from './ai360';
5
5
  import AnthropicProvider from './anthropic';
6
6
  import AzureProvider from './azure';
7
+ import AzureAIProvider from './azureai';
7
8
  import BaichuanProvider from './baichuan';
8
9
  import BedrockProvider from './bedrock';
9
10
  import CloudflareProvider from './cloudflare';
@@ -92,6 +93,7 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [
92
93
  export const DEFAULT_MODEL_PROVIDER_LIST = [
93
94
  OpenAIProvider,
94
95
  { ...AzureProvider, chatModels: [] },
96
+ AzureAIProvider,
95
97
  OllamaProvider,
96
98
  VLLMProvider,
97
99
  AnthropicProvider,
@@ -148,6 +150,7 @@ export { default as Ai21ProviderCard } from './ai21';
148
150
  export { default as Ai360ProviderCard } from './ai360';
149
151
  export { default as AnthropicProviderCard } from './anthropic';
150
152
  export { default as AzureProviderCard } from './azure';
153
+ export { default as AzureAIProviderCard } from './azureai';
151
154
  export { default as BaichuanProviderCard } from './baichuan';
152
155
  export { default as BedrockProviderCard } from './bedrock';
153
156
  export { default as CloudflareProviderCard } from './cloudflare';
@@ -1,4 +1,5 @@
1
1
  import { and, asc, desc, eq } from 'drizzle-orm/expressions';
2
+ import { isEmpty } from 'lodash-es';
2
3
 
3
4
  import { LobeChatDatabase } from '@/database/type';
4
5
  import { ModelProvider } from '@/libs/agent-runtime';
@@ -207,6 +208,7 @@ export class AiProviderModel {
207
208
  ...result,
208
209
  fetchOnClient: typeof result.fetchOnClient === 'boolean' ? result.fetchOnClient : undefined,
209
210
  keyVaults,
211
+ settings: isEmpty(result.settings) ? undefined : result.settings,
210
212
  } as AiProviderDetailItem;
211
213
  };
212
214
 
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Form, type FormItemProps, Icon, type ItemGroup, Tooltip } from '@lobehub/ui';
4
- import { Button } from 'antd';
4
+ import { Button, Skeleton } from 'antd';
5
5
  import isEqual from 'fast-deep-equal';
6
6
  import { isString } from 'lodash-es';
7
7
  import { Wand2 } from 'lucide-react';
@@ -27,7 +27,11 @@ const AgentMeta = memo(() => {
27
27
  s.autocompleteMeta,
28
28
  s.autocompleteAllMeta,
29
29
  ]);
30
- const [isInbox, loading] = useStore((s) => [s.id === INBOX_SESSION_ID, s.autocompleteLoading]);
30
+ const [isInbox, isIniting, autocompleteLoading] = useStore((s) => [
31
+ s.id === INBOX_SESSION_ID,
32
+ s.loading,
33
+ s.autocompleteLoading,
34
+ ]);
31
35
  const meta = useStore((s) => s.meta, isEqual);
32
36
 
33
37
  if (isInbox) return;
@@ -59,10 +63,12 @@ const AgentMeta = memo(() => {
59
63
  const autocompleteItems: FormItemProps[] = basic.map((item) => {
60
64
  const AutoGenerate = item.Render;
61
65
  return {
62
- children: (
66
+ children: isIniting ? (
67
+ <Skeleton.Button active block size={'small'} />
68
+ ) : (
63
69
  <AutoGenerate
64
70
  canAutoGenerate={hasSystemRole}
65
- loading={loading[item.key as keyof SessionLoadingState]}
71
+ loading={autocompleteLoading[item.key as keyof SessionLoadingState]}
66
72
  onChange={item.onChange}
67
73
  onGenerate={() => {
68
74
  autocompleteMeta(item.key as keyof typeof meta);
@@ -78,11 +84,13 @@ const AgentMeta = memo(() => {
78
84
  const metaData: ItemGroup = {
79
85
  children: [
80
86
  {
81
- children: (
87
+ children: isIniting ? (
88
+ <Skeleton.Button active block size={'small'} />
89
+ ) : (
82
90
  <AutoGenerateAvatar
83
91
  background={meta.backgroundColor}
84
92
  canAutoGenerate={hasSystemRole}
85
- loading={loading['avatar']}
93
+ loading={autocompleteLoading['avatar']}
86
94
  onChange={(avatar) => updateMeta({ avatar })}
87
95
  onGenerate={() => autocompleteMeta('avatar')}
88
96
  value={meta.avatar}
@@ -92,7 +100,9 @@ const AgentMeta = memo(() => {
92
100
  minWidth: undefined,
93
101
  },
94
102
  {
95
- children: (
103
+ children: isIniting ? (
104
+ <Skeleton.Button active block size={'small'} />
105
+ ) : (
96
106
  <BackgroundSwatches
97
107
  backgroundColor={meta.backgroundColor}
98
108
  onChange={(backgroundColor) => updateMeta({ backgroundColor })}
@@ -103,7 +113,7 @@ const AgentMeta = memo(() => {
103
113
  },
104
114
  ...autocompleteItems,
105
115
  ],
106
- extra: (
116
+ extra: !isIniting && (
107
117
  <Tooltip
108
118
  title={
109
119
  !hasSystemRole
@@ -114,7 +124,7 @@ const AgentMeta = memo(() => {
114
124
  <Button
115
125
  disabled={!hasSystemRole}
116
126
  icon={<Icon icon={Wand2} />}
117
- loading={Object.values(loading).some((i) => !!i)}
127
+ loading={Object.values(autocompleteLoading).some((i) => !!i)}
118
128
  onClick={(e: any) => {
119
129
  e.stopPropagation();
120
130
 
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { EditableMessage, Form } from '@lobehub/ui';
4
- import { Button } from 'antd';
4
+ import { Button, Skeleton } from 'antd';
5
5
  import { createStyles } from 'antd-style';
6
6
  import { memo, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
@@ -40,7 +40,37 @@ const AgentPrompt = memo<{ modal?: boolean }>(({ modal }) => {
40
40
  const { t } = useTranslation('setting');
41
41
  const { styles } = useStyles();
42
42
  const [editing, setEditing] = useState(false);
43
- const [systemRole, updateConfig] = useStore((s) => [s.config.systemRole, s.setAgentConfig]);
43
+ const [loading, systemRole, updateConfig] = useStore((s) => [
44
+ s.loading,
45
+ s.config.systemRole,
46
+ s.setAgentConfig,
47
+ ]);
48
+
49
+ if (loading) {
50
+ return (
51
+ <div className={styles.wrapper}>
52
+ <Flexbox className={styles.container} padding={4}>
53
+ <Flexbox horizontal justify={'space-between'} paddingBlock={8} paddingInline={12}>
54
+ <h1 style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 4 }}>
55
+ {t('settingAgent.prompt.title')}
56
+ </h1>
57
+ </Flexbox>
58
+ <Flexbox
59
+ align={'center'}
60
+ className={styles.content}
61
+ flex={1}
62
+ gap={16}
63
+ horizontal
64
+ justify={'space-between'}
65
+ padding={12}
66
+ wrap={'wrap'}
67
+ >
68
+ <Skeleton active style={{ paddingTop: 12 }} title={false} />
69
+ </Flexbox>
70
+ </Flexbox>
71
+ </div>
72
+ );
73
+ }
44
74
 
45
75
  const content = (
46
76
  <EditableMessage
@@ -5,23 +5,22 @@ import AgentMeta from './AgentMeta';
5
5
  import AgentModal from './AgentModal';
6
6
  import AgentPlugin from './AgentPlugin';
7
7
  import AgentPrompt from './AgentPrompt';
8
+ import { AgentSettingsProvider } from './AgentSettingsProvider';
8
9
  import AgentTTS from './AgentTTS';
9
- import StoreUpdater, { StoreUpdaterProps } from './StoreUpdater';
10
- import { Provider, createStore } from './store';
10
+ import { StoreUpdaterProps } from './StoreUpdater';
11
11
 
12
12
  type AgentSettingsProps = StoreUpdaterProps;
13
13
 
14
14
  export const AgentSettings = (props: AgentSettingsProps) => {
15
15
  const { enablePlugins } = useServerConfigStore(featureFlagsSelectors);
16
16
  return (
17
- <Provider createStore={createStore}>
18
- <StoreUpdater {...props} />
17
+ <AgentSettingsProvider {...props}>
19
18
  <AgentPrompt />
20
19
  <AgentMeta />
21
20
  <AgentChat />
22
21
  <AgentModal />
23
22
  <AgentTTS />
24
23
  {enablePlugins && <AgentPlugin />}
25
- </Provider>
24
+ </AgentSettingsProvider>
26
25
  );
27
26
  };
@@ -0,0 +1,17 @@
1
+ import { ReactNode, memo } from 'react';
2
+
3
+ import StoreUpdater, { StoreUpdaterProps } from './StoreUpdater';
4
+ import { Provider, createStore } from './store';
5
+
6
+ interface AgentSettingsProps extends StoreUpdaterProps {
7
+ children: ReactNode;
8
+ }
9
+
10
+ export const AgentSettingsProvider = memo<AgentSettingsProps>(({ children, ...props }) => {
11
+ return (
12
+ <Provider createStore={createStore}>
13
+ <StoreUpdater {...props} />
14
+ {children}
15
+ </Provider>
16
+ );
17
+ });