@lobehub/lobehub 2.0.0-next.2 → 2.0.0-next.4
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.
- package/CHANGELOG.md +67 -0
- package/changelog/v1.json +18 -0
- package/locales/ar/models.json +9 -0
- package/locales/bg-BG/models.json +9 -0
- package/locales/de-DE/models.json +9 -0
- package/locales/en-US/models.json +9 -0
- package/locales/es-ES/models.json +9 -0
- package/locales/fa-IR/models.json +9 -0
- package/locales/fr-FR/models.json +9 -0
- package/locales/it-IT/models.json +9 -0
- package/locales/ja-JP/models.json +9 -0
- package/locales/ko-KR/models.json +9 -0
- package/locales/nl-NL/models.json +9 -0
- package/locales/pl-PL/models.json +9 -0
- package/locales/pt-BR/models.json +9 -0
- package/locales/ru-RU/models.json +9 -0
- package/locales/tr-TR/models.json +9 -0
- package/locales/vi-VN/models.json +9 -0
- package/locales/zh-CN/models.json +9 -0
- package/locales/zh-TW/models.json +9 -0
- package/package.json +1 -1
- package/packages/const/src/models.ts +13 -0
- package/packages/model-bank/src/aiModels/azure.ts +155 -0
- package/packages/model-bank/src/aiModels/bedrock.ts +44 -0
- package/packages/model-runtime/src/core/parameterResolver.ts +3 -0
- package/packages/model-runtime/src/providers/azureOpenai/index.ts +2 -1
- package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +0 -3
- package/src/libs/next-auth/sso-providers/index.ts +0 -2
- package/src/libs/oidc-provider/provider.ts +1 -1
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Azure/index.tsx +0 -93
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Bedrock/index.tsx +0 -70
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +0 -39
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Github/index.tsx +0 -52
- package/src/app/[variants]/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +0 -52
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Ollama/index.tsx +0 -20
- package/src/app/[variants]/(main)/settings/llm/ProviderList/OpenAI/index.tsx +0 -17
- package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +0 -132
- package/src/app/[variants]/(main)/settings/llm/components/Checker.tsx +0 -118
- package/src/app/[variants]/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -303
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +0 -98
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/Form.tsx +0 -104
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +0 -77
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -105
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/Option.tsx +0 -68
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/index.tsx +0 -146
- package/src/app/[variants]/(main)/settings/llm/const.ts +0 -20
- package/src/app/[variants]/(main)/settings/llm/features/Footer.tsx +0 -35
- package/src/app/[variants]/(main)/settings/llm/index.tsx +0 -30
- package/src/app/[variants]/(main)/settings/llm/type.ts +0 -5
- package/src/libs/next-auth/sso-providers/azure-ad.ts +0 -33
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { Input } from '@lobehub/ui';
|
|
2
|
-
import { Checkbox, Form, FormInstance } from 'antd';
|
|
3
|
-
import { memo, useEffect } from 'react';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
|
-
|
|
6
|
-
import MaxTokenSlider from '@/components/MaxTokenSlider';
|
|
7
|
-
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
8
|
-
import { ChatModelCard } from '@/types/llm';
|
|
9
|
-
|
|
10
|
-
interface ModelConfigFormProps {
|
|
11
|
-
initialValues?: ChatModelCard;
|
|
12
|
-
onFormInstanceReady: (instance: FormInstance) => void;
|
|
13
|
-
showAzureDeployName?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const ModelConfigForm = memo<ModelConfigFormProps>(
|
|
17
|
-
({ showAzureDeployName, onFormInstanceReady, initialValues }) => {
|
|
18
|
-
const { t } = useTranslation('setting');
|
|
19
|
-
|
|
20
|
-
const [formInstance] = Form.useForm();
|
|
21
|
-
|
|
22
|
-
const isMobile = useIsMobile();
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
onFormInstanceReady(formInstance);
|
|
26
|
-
}, []);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div
|
|
30
|
-
onClick={(e) => {
|
|
31
|
-
e.stopPropagation();
|
|
32
|
-
}}
|
|
33
|
-
onKeyDown={(e) => {
|
|
34
|
-
e.stopPropagation();
|
|
35
|
-
}}
|
|
36
|
-
>
|
|
37
|
-
<Form
|
|
38
|
-
colon={false}
|
|
39
|
-
form={formInstance}
|
|
40
|
-
initialValues={initialValues}
|
|
41
|
-
labelCol={{ span: 4 }}
|
|
42
|
-
style={{ marginTop: 16 }}
|
|
43
|
-
wrapperCol={isMobile ? { span: 18 } : { offset: 1, span: 18 }}
|
|
44
|
-
>
|
|
45
|
-
<Form.Item
|
|
46
|
-
extra={t('llm.customModelCards.modelConfig.id.extra')}
|
|
47
|
-
label={t('llm.customModelCards.modelConfig.id.title')}
|
|
48
|
-
name={'id'}
|
|
49
|
-
>
|
|
50
|
-
<Input placeholder={t('llm.customModelCards.modelConfig.id.placeholder')} />
|
|
51
|
-
</Form.Item>
|
|
52
|
-
{showAzureDeployName && (
|
|
53
|
-
<Form.Item
|
|
54
|
-
extra={t('llm.customModelCards.modelConfig.azureDeployName.extra')}
|
|
55
|
-
label={t('llm.customModelCards.modelConfig.azureDeployName.title')}
|
|
56
|
-
name={'deploymentName'}
|
|
57
|
-
>
|
|
58
|
-
<Input
|
|
59
|
-
placeholder={t('llm.customModelCards.modelConfig.azureDeployName.placeholder')}
|
|
60
|
-
/>
|
|
61
|
-
</Form.Item>
|
|
62
|
-
)}
|
|
63
|
-
<Form.Item
|
|
64
|
-
label={t('llm.customModelCards.modelConfig.displayName.title')}
|
|
65
|
-
name={'displayName'}
|
|
66
|
-
>
|
|
67
|
-
<Input placeholder={t('llm.customModelCards.modelConfig.displayName.placeholder')} />
|
|
68
|
-
</Form.Item>
|
|
69
|
-
<Form.Item
|
|
70
|
-
label={t('llm.customModelCards.modelConfig.tokens.title')}
|
|
71
|
-
name={'contextWindowTokens'}
|
|
72
|
-
>
|
|
73
|
-
<MaxTokenSlider />
|
|
74
|
-
</Form.Item>
|
|
75
|
-
<Form.Item
|
|
76
|
-
extra={t('llm.customModelCards.modelConfig.functionCall.extra')}
|
|
77
|
-
label={t('llm.customModelCards.modelConfig.functionCall.title')}
|
|
78
|
-
name={'functionCall'}
|
|
79
|
-
valuePropName={'checked'}
|
|
80
|
-
>
|
|
81
|
-
<Checkbox />
|
|
82
|
-
</Form.Item>
|
|
83
|
-
<Form.Item
|
|
84
|
-
extra={t('llm.customModelCards.modelConfig.vision.extra')}
|
|
85
|
-
label={t('llm.customModelCards.modelConfig.vision.title')}
|
|
86
|
-
name={'vision'}
|
|
87
|
-
valuePropName={'checked'}
|
|
88
|
-
>
|
|
89
|
-
<Checkbox />
|
|
90
|
-
</Form.Item>
|
|
91
|
-
<Form.Item
|
|
92
|
-
extra={t('llm.customModelCards.modelConfig.files.extra')}
|
|
93
|
-
label={t('llm.customModelCards.modelConfig.files.title')}
|
|
94
|
-
name={'files'}
|
|
95
|
-
valuePropName={'checked'}
|
|
96
|
-
>
|
|
97
|
-
<Checkbox />
|
|
98
|
-
</Form.Item>
|
|
99
|
-
</Form>
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
},
|
|
103
|
-
);
|
|
104
|
-
export default ModelConfigForm;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Button, Modal } from '@lobehub/ui';
|
|
2
|
-
import { FormInstance } from 'antd';
|
|
3
|
-
import isEqual from 'fast-deep-equal';
|
|
4
|
-
import { memo, useState } from 'react';
|
|
5
|
-
import { useTranslation } from 'react-i18next';
|
|
6
|
-
|
|
7
|
-
import { useUserStore } from '@/store/user';
|
|
8
|
-
import { modelConfigSelectors } from '@/store/user/selectors';
|
|
9
|
-
|
|
10
|
-
import ModelConfigForm from './Form';
|
|
11
|
-
|
|
12
|
-
interface ModelConfigModalProps {
|
|
13
|
-
provider?: string;
|
|
14
|
-
showAzureDeployName?: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const ModelConfigModal = memo<ModelConfigModalProps>(({ showAzureDeployName, provider }) => {
|
|
18
|
-
const { t } = useTranslation('setting');
|
|
19
|
-
const { t: tc } = useTranslation('common');
|
|
20
|
-
const [formInstance, setFormInstance] = useState<FormInstance>();
|
|
21
|
-
|
|
22
|
-
const [open, id, editingProvider, dispatchCustomModelCards, toggleEditingCustomModelCard] =
|
|
23
|
-
useUserStore((s) => [
|
|
24
|
-
!!s.editingCustomCardModel && provider === s.editingCustomCardModel?.provider,
|
|
25
|
-
s.editingCustomCardModel?.id,
|
|
26
|
-
s.editingCustomCardModel?.provider,
|
|
27
|
-
s.dispatchCustomModelCards,
|
|
28
|
-
s.toggleEditingCustomModelCard,
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
const modelCard = useUserStore(
|
|
32
|
-
modelConfigSelectors.getCustomModelCard({ id, provider: editingProvider }),
|
|
33
|
-
isEqual,
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const closeModal = () => {
|
|
37
|
-
toggleEditingCustomModelCard(undefined);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<Modal
|
|
42
|
-
destroyOnHidden
|
|
43
|
-
footer={[
|
|
44
|
-
<Button key="cancel" onClick={closeModal}>
|
|
45
|
-
{tc('cancel')}
|
|
46
|
-
</Button>,
|
|
47
|
-
<Button
|
|
48
|
-
key="ok"
|
|
49
|
-
onClick={() => {
|
|
50
|
-
if (!editingProvider || !id || !formInstance) return;
|
|
51
|
-
const data = formInstance.getFieldsValue();
|
|
52
|
-
|
|
53
|
-
dispatchCustomModelCards(editingProvider as any, { id, type: 'update', value: data });
|
|
54
|
-
|
|
55
|
-
closeModal();
|
|
56
|
-
}}
|
|
57
|
-
style={{ marginInlineStart: '16px' }}
|
|
58
|
-
type="primary"
|
|
59
|
-
>
|
|
60
|
-
{tc('ok')}
|
|
61
|
-
</Button>,
|
|
62
|
-
]}
|
|
63
|
-
maskClosable
|
|
64
|
-
onCancel={closeModal}
|
|
65
|
-
open={open}
|
|
66
|
-
title={t('llm.customModelCards.modelConfig.modalTitle')}
|
|
67
|
-
zIndex={1251} // Select is 1150
|
|
68
|
-
>
|
|
69
|
-
<ModelConfigForm
|
|
70
|
-
initialValues={modelCard}
|
|
71
|
-
onFormInstanceReady={setFormInstance}
|
|
72
|
-
showAzureDeployName={showAzureDeployName}
|
|
73
|
-
/>
|
|
74
|
-
</Modal>
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
export default ModelConfigModal;
|
package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { ActionIcon, Icon, Text, Tooltip } from '@lobehub/ui';
|
|
2
|
-
import { createStyles } from 'antd-style';
|
|
3
|
-
import dayjs from 'dayjs';
|
|
4
|
-
import isEqual from 'fast-deep-equal';
|
|
5
|
-
import { CircleX, LucideLoaderCircle, LucideRefreshCcwDot } from 'lucide-react';
|
|
6
|
-
import { memo } from 'react';
|
|
7
|
-
import { useTranslation } from 'react-i18next';
|
|
8
|
-
import { Flexbox } from 'react-layout-kit';
|
|
9
|
-
|
|
10
|
-
import { useUserStore } from '@/store/user';
|
|
11
|
-
import {
|
|
12
|
-
modelConfigSelectors,
|
|
13
|
-
modelProviderSelectors,
|
|
14
|
-
settingsSelectors,
|
|
15
|
-
} from '@/store/user/selectors';
|
|
16
|
-
import { GlobalLLMProviderKey } from '@/types/user/settings';
|
|
17
|
-
|
|
18
|
-
const useStyles = createStyles(({ css, token }) => ({
|
|
19
|
-
hover: css`
|
|
20
|
-
cursor: pointer;
|
|
21
|
-
|
|
22
|
-
padding-block: 4px;
|
|
23
|
-
padding-inline: 8px;
|
|
24
|
-
border-radius: ${token.borderRadius}px;
|
|
25
|
-
|
|
26
|
-
transition: all 0.2s ease-in-out;
|
|
27
|
-
|
|
28
|
-
&:hover {
|
|
29
|
-
color: ${token.colorText};
|
|
30
|
-
background-color: ${token.colorFillSecondary};
|
|
31
|
-
}
|
|
32
|
-
`,
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
interface ModelFetcherProps {
|
|
36
|
-
provider: GlobalLLMProviderKey;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const ModelFetcher = memo<ModelFetcherProps>(({ provider }) => {
|
|
40
|
-
const { styles } = useStyles();
|
|
41
|
-
const { t } = useTranslation('setting');
|
|
42
|
-
const [useFetchProviderModelList, clearObtainedModels] = useUserStore((s) => [
|
|
43
|
-
s.useFetchProviderModelList,
|
|
44
|
-
s.clearObtainedModels,
|
|
45
|
-
s.setModelProviderConfig,
|
|
46
|
-
]);
|
|
47
|
-
const enabledAutoFetch = useUserStore(modelConfigSelectors.isAutoFetchModelsEnabled(provider));
|
|
48
|
-
const latestFetchTime = useUserStore(
|
|
49
|
-
(s) => settingsSelectors.providerConfig(provider)(s)?.latestFetchTime,
|
|
50
|
-
);
|
|
51
|
-
const totalModels = useUserStore(
|
|
52
|
-
(s) => modelProviderSelectors.getModelCardsById(provider)(s).length,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const remoteModels = useUserStore(
|
|
56
|
-
modelProviderSelectors.remoteProviderModelCards(provider),
|
|
57
|
-
isEqual,
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const { mutate, isValidating } = useFetchProviderModelList(provider, enabledAutoFetch);
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<Text style={{ fontSize: 12 }} type={'secondary'}>
|
|
64
|
-
<Flexbox align={'center'} gap={0} horizontal justify={'space-between'}>
|
|
65
|
-
<div style={{ display: 'flex', lineHeight: '24px' }}>
|
|
66
|
-
{t('llm.modelList.total', { count: totalModels })}
|
|
67
|
-
{remoteModels && remoteModels.length > 0 && (
|
|
68
|
-
<ActionIcon
|
|
69
|
-
icon={CircleX}
|
|
70
|
-
onClick={() => clearObtainedModels(provider)}
|
|
71
|
-
size={'small'}
|
|
72
|
-
title={t('llm.fetcher.clear')}
|
|
73
|
-
/>
|
|
74
|
-
)}
|
|
75
|
-
</div>
|
|
76
|
-
<Tooltip
|
|
77
|
-
styles={{ root: { pointerEvents: 'none' } }}
|
|
78
|
-
title={
|
|
79
|
-
latestFetchTime
|
|
80
|
-
? t('llm.fetcher.latestTime', {
|
|
81
|
-
time: dayjs(latestFetchTime).format('YYYY-MM-DD HH:mm:ss'),
|
|
82
|
-
})
|
|
83
|
-
: t('llm.fetcher.noLatestTime')
|
|
84
|
-
}
|
|
85
|
-
>
|
|
86
|
-
<Flexbox
|
|
87
|
-
align={'center'}
|
|
88
|
-
className={styles.hover}
|
|
89
|
-
gap={4}
|
|
90
|
-
horizontal
|
|
91
|
-
onClick={() => mutate()}
|
|
92
|
-
>
|
|
93
|
-
<Icon
|
|
94
|
-
icon={isValidating ? LucideLoaderCircle : LucideRefreshCcwDot}
|
|
95
|
-
size={'small'}
|
|
96
|
-
spin={isValidating}
|
|
97
|
-
/>
|
|
98
|
-
<div>{isValidating ? t('llm.fetcher.fetching') : t('llm.fetcher.fetch')}</div>
|
|
99
|
-
</Flexbox>
|
|
100
|
-
</Tooltip>
|
|
101
|
-
</Flexbox>
|
|
102
|
-
</Text>
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
export default ModelFetcher;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { ModelIcon } from '@lobehub/icons';
|
|
2
|
-
import { ActionIcon, Text, Tooltip } from '@lobehub/ui';
|
|
3
|
-
import { useTheme } from 'antd-style';
|
|
4
|
-
import isEqual from 'fast-deep-equal';
|
|
5
|
-
import { Recycle } from 'lucide-react';
|
|
6
|
-
import { memo } from 'react';
|
|
7
|
-
import { useTranslation } from 'react-i18next';
|
|
8
|
-
import { Flexbox } from 'react-layout-kit';
|
|
9
|
-
|
|
10
|
-
import { ModelInfoTags } from '@/components/ModelSelect';
|
|
11
|
-
import { useUserStore } from '@/store/user';
|
|
12
|
-
import { modelProviderSelectors } from '@/store/user/selectors';
|
|
13
|
-
import { GlobalLLMProviderKey } from '@/types/user/settings';
|
|
14
|
-
|
|
15
|
-
import CustomModelOption from './CustomModelOption';
|
|
16
|
-
|
|
17
|
-
interface OptionRenderProps {
|
|
18
|
-
displayName: string;
|
|
19
|
-
id: string;
|
|
20
|
-
isAzure?: boolean;
|
|
21
|
-
provider: GlobalLLMProviderKey;
|
|
22
|
-
removed?: boolean;
|
|
23
|
-
}
|
|
24
|
-
const OptionRender = memo<OptionRenderProps>(({ displayName, id, provider, isAzure, removed }) => {
|
|
25
|
-
const model = useUserStore(
|
|
26
|
-
(s) => modelProviderSelectors.getModelCardById(id, provider)(s),
|
|
27
|
-
isEqual,
|
|
28
|
-
);
|
|
29
|
-
const { t } = useTranslation('components');
|
|
30
|
-
const theme = useTheme();
|
|
31
|
-
// if there is isCustom, it means it is a user defined custom model
|
|
32
|
-
if (model?.isCustom || isAzure) return <CustomModelOption id={id} provider={provider} />;
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<Flexbox
|
|
36
|
-
align={'center'}
|
|
37
|
-
gap={8}
|
|
38
|
-
horizontal
|
|
39
|
-
justify={'space-between'}
|
|
40
|
-
style={{ paddingInlineEnd: 8 }}
|
|
41
|
-
>
|
|
42
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
43
|
-
<ModelIcon model={id} size={32} />
|
|
44
|
-
<Flexbox>
|
|
45
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
46
|
-
{displayName}
|
|
47
|
-
<ModelInfoTags directionReverse placement={'top'} {...model!} />
|
|
48
|
-
</Flexbox>
|
|
49
|
-
<Text style={{ fontSize: 12 }} type={'secondary'}>
|
|
50
|
-
{id}
|
|
51
|
-
</Text>
|
|
52
|
-
</Flexbox>
|
|
53
|
-
</Flexbox>
|
|
54
|
-
{removed && (
|
|
55
|
-
<Tooltip
|
|
56
|
-
placement={'top'}
|
|
57
|
-
style={{ pointerEvents: 'none' }}
|
|
58
|
-
styles={{ root: { maxWidth: 300 } }}
|
|
59
|
-
title={t('ModelSelect.removed')}
|
|
60
|
-
>
|
|
61
|
-
<ActionIcon icon={Recycle} style={{ color: theme.colorWarning }} />
|
|
62
|
-
</Tooltip>
|
|
63
|
-
)}
|
|
64
|
-
</Flexbox>
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
export default OptionRender;
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { ActionIcon, Select } from '@lobehub/ui';
|
|
2
|
-
import { css, cx } from 'antd-style';
|
|
3
|
-
import isEqual from 'fast-deep-equal';
|
|
4
|
-
import { RotateCwIcon } from 'lucide-react';
|
|
5
|
-
import { ReactNode, memo } from 'react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { Flexbox } from 'react-layout-kit';
|
|
8
|
-
|
|
9
|
-
import { useUserStore } from '@/store/user';
|
|
10
|
-
import { modelProviderSelectors } from '@/store/user/selectors';
|
|
11
|
-
import { GlobalLLMProviderKey } from '@/types/user/settings';
|
|
12
|
-
|
|
13
|
-
import ModelConfigModal from './ModelConfigModal';
|
|
14
|
-
import ModelFetcher from './ModelFetcher';
|
|
15
|
-
import OptionRender from './Option';
|
|
16
|
-
|
|
17
|
-
const styles = {
|
|
18
|
-
divStyle: css`
|
|
19
|
-
position: relative;
|
|
20
|
-
|
|
21
|
-
.ant-select-selector {
|
|
22
|
-
padding-inline-end: 50px !important;
|
|
23
|
-
}
|
|
24
|
-
`,
|
|
25
|
-
popup: css`
|
|
26
|
-
&.ant-select-dropdown {
|
|
27
|
-
.ant-select-item-option-selected {
|
|
28
|
-
font-weight: normal;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
`,
|
|
32
|
-
reset: css`
|
|
33
|
-
position: absolute;
|
|
34
|
-
z-index: 20;
|
|
35
|
-
inset-block-start: 50%;
|
|
36
|
-
inset-inline-end: 28px;
|
|
37
|
-
transform: translateY(-50%);
|
|
38
|
-
`,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
interface CustomModelSelectProps {
|
|
42
|
-
notFoundContent?: ReactNode;
|
|
43
|
-
placeholder?: string;
|
|
44
|
-
provider: GlobalLLMProviderKey;
|
|
45
|
-
showAzureDeployName?: boolean;
|
|
46
|
-
showModelFetcher?: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const ProviderModelListSelect = memo<CustomModelSelectProps>(
|
|
50
|
-
({ showModelFetcher = false, provider, showAzureDeployName, notFoundContent, placeholder }) => {
|
|
51
|
-
const { t } = useTranslation('common');
|
|
52
|
-
const { t: transSetting } = useTranslation('setting');
|
|
53
|
-
const [setModelProviderConfig, updateEnabledModels] = useUserStore((s) => [
|
|
54
|
-
s.setModelProviderConfig,
|
|
55
|
-
s.updateEnabledModels,
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
const chatModelCards = useUserStore(
|
|
59
|
-
modelProviderSelectors.getModelCardsById(provider),
|
|
60
|
-
isEqual,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const defaultEnableModel = useUserStore(
|
|
64
|
-
modelProviderSelectors.getDefaultEnabledModelsById(provider),
|
|
65
|
-
isEqual,
|
|
66
|
-
);
|
|
67
|
-
const enabledModels = useUserStore(
|
|
68
|
-
modelProviderSelectors.getEnableModelsById(provider),
|
|
69
|
-
isEqual,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
const showReset = !!enabledModels && !isEqual(defaultEnableModel, enabledModels);
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<>
|
|
76
|
-
<Flexbox gap={8}>
|
|
77
|
-
<div className={cx(styles.divStyle)}>
|
|
78
|
-
<div className={cx(styles.reset)}>
|
|
79
|
-
{showReset && (
|
|
80
|
-
<ActionIcon
|
|
81
|
-
icon={RotateCwIcon}
|
|
82
|
-
onClick={() => {
|
|
83
|
-
setModelProviderConfig(provider, { enabledModels: null });
|
|
84
|
-
}}
|
|
85
|
-
size={'small'}
|
|
86
|
-
title={t('reset')}
|
|
87
|
-
/>
|
|
88
|
-
)}
|
|
89
|
-
</div>
|
|
90
|
-
<Select
|
|
91
|
-
allowClear
|
|
92
|
-
mode="tags"
|
|
93
|
-
notFoundContent={notFoundContent}
|
|
94
|
-
onChange={(value, options) => {
|
|
95
|
-
updateEnabledModels(provider, value, options as any[]);
|
|
96
|
-
}}
|
|
97
|
-
optionFilterProp="label"
|
|
98
|
-
optionRender={({ label, value }) => {
|
|
99
|
-
// model is in the chatModels
|
|
100
|
-
if (chatModelCards.some((c) => c.id === value))
|
|
101
|
-
return (
|
|
102
|
-
<OptionRender
|
|
103
|
-
displayName={label as string}
|
|
104
|
-
id={value as string}
|
|
105
|
-
isAzure={showAzureDeployName}
|
|
106
|
-
provider={provider}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
if (enabledModels?.some((m) => value === m)) {
|
|
111
|
-
return (
|
|
112
|
-
<OptionRender
|
|
113
|
-
displayName={label as string}
|
|
114
|
-
id={value as string}
|
|
115
|
-
isAzure={showAzureDeployName}
|
|
116
|
-
provider={provider}
|
|
117
|
-
removed
|
|
118
|
-
/>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// model is defined by user in client
|
|
123
|
-
return (
|
|
124
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
125
|
-
{transSetting('llm.customModelCards.addNew', { id: value })}
|
|
126
|
-
</Flexbox>
|
|
127
|
-
);
|
|
128
|
-
}}
|
|
129
|
-
options={chatModelCards.map((model) => ({
|
|
130
|
-
label: model.displayName || model.id,
|
|
131
|
-
value: model.id,
|
|
132
|
-
}))}
|
|
133
|
-
placeholder={placeholder}
|
|
134
|
-
popupClassName={cx(styles.popup)}
|
|
135
|
-
value={enabledModels ?? defaultEnableModel}
|
|
136
|
-
/>
|
|
137
|
-
</div>
|
|
138
|
-
{showModelFetcher && <ModelFetcher provider={provider} />}
|
|
139
|
-
</Flexbox>
|
|
140
|
-
<ModelConfigModal provider={provider} showAzureDeployName={showAzureDeployName} />
|
|
141
|
-
</>
|
|
142
|
-
);
|
|
143
|
-
},
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
export default ProviderModelListSelect;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const LLMProviderConfigKey = 'languageModel';
|
|
2
|
-
export const KeyVaultsConfigKey = 'keyVaults';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* we use this key to define default api key
|
|
6
|
-
* equal GOOGLE_API_KEY or ZHIPU_API_KEY
|
|
7
|
-
*/
|
|
8
|
-
export const LLMProviderApiTokenKey = 'apiKey';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* we use this key to define the baseURL
|
|
12
|
-
* equal OPENAI_PROXY_URL
|
|
13
|
-
*/
|
|
14
|
-
export const LLMProviderBaseUrlKey = 'baseURL';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* we use this key to define the custom model name
|
|
18
|
-
* equal CUSTOM_MODELS
|
|
19
|
-
*/
|
|
20
|
-
export const LLMProviderModelListKey = 'enabledModels';
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useTheme } from 'antd-style';
|
|
4
|
-
import Link from 'next/link';
|
|
5
|
-
import { memo } from 'react';
|
|
6
|
-
import { Trans } from 'react-i18next';
|
|
7
|
-
import { Center } from 'react-layout-kit';
|
|
8
|
-
|
|
9
|
-
import { MORE_MODEL_PROVIDER_REQUEST_URL } from '@/const/url';
|
|
10
|
-
|
|
11
|
-
const Footer = memo(() => {
|
|
12
|
-
const theme = useTheme();
|
|
13
|
-
return (
|
|
14
|
-
<Center
|
|
15
|
-
style={{
|
|
16
|
-
background: theme.colorFillQuaternary,
|
|
17
|
-
border: `1px dashed ${theme.colorFillSecondary}`,
|
|
18
|
-
borderRadius: theme.borderRadiusLG,
|
|
19
|
-
padding: 12,
|
|
20
|
-
}}
|
|
21
|
-
>
|
|
22
|
-
<div style={{ color: theme.colorTextSecondary, fontSize: 12, textAlign: 'center' }}>
|
|
23
|
-
<Trans i18nKey="llm.waitingForMore" ns={'setting'}>
|
|
24
|
-
更多模型正在
|
|
25
|
-
<Link aria-label={'todo'} href={MORE_MODEL_PROVIDER_REQUEST_URL} target="_blank">
|
|
26
|
-
计划接入
|
|
27
|
-
</Link>
|
|
28
|
-
中 ,敬请期待
|
|
29
|
-
</Trans>
|
|
30
|
-
</div>
|
|
31
|
-
</Center>
|
|
32
|
-
);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export default Footer;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { isCustomBranding } from '@/const/version';
|
|
4
|
-
|
|
5
|
-
import { useProviderList } from './ProviderList/providers';
|
|
6
|
-
import ProviderConfig from './components/ProviderConfig';
|
|
7
|
-
import Footer from './features/Footer';
|
|
8
|
-
|
|
9
|
-
const Page = () => {
|
|
10
|
-
const list = useProviderList();
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div
|
|
14
|
-
style={{
|
|
15
|
-
display: 'flex',
|
|
16
|
-
flexDirection: 'column',
|
|
17
|
-
gap: 24,
|
|
18
|
-
}}
|
|
19
|
-
>
|
|
20
|
-
{list.map(({ id, ...res }) => (
|
|
21
|
-
<ProviderConfig id={id as any} key={id} {...res} />
|
|
22
|
-
))}
|
|
23
|
-
{!isCustomBranding && <Footer />}
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
Page.displayName = 'LlmSetting';
|
|
29
|
-
|
|
30
|
-
export default Page;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import AzureAD from 'next-auth/providers/azure-ad';
|
|
2
|
-
|
|
3
|
-
import { authEnv } from '@/envs/auth';
|
|
4
|
-
|
|
5
|
-
import { getMicrosoftEntraIdIssuer } from './microsoft-entra-id-helper';
|
|
6
|
-
import { CommonProviderConfig } from './sso.config';
|
|
7
|
-
|
|
8
|
-
const provider = {
|
|
9
|
-
id: 'azure-ad',
|
|
10
|
-
provider: AzureAD({
|
|
11
|
-
...CommonProviderConfig,
|
|
12
|
-
// Specify auth scope, at least include 'openid email'
|
|
13
|
-
// all scopes in Azure AD ref: https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#openid-connect-scopes
|
|
14
|
-
authorization: { params: { scope: 'openid email profile' } },
|
|
15
|
-
// TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
|
|
16
|
-
clientId: authEnv.AZURE_AD_CLIENT_ID ?? process.env.AUTH_AZURE_AD_ID,
|
|
17
|
-
clientSecret: authEnv.AZURE_AD_CLIENT_SECRET ?? process.env.AUTH_AZURE_AD_SECRET,
|
|
18
|
-
issuer: getMicrosoftEntraIdIssuer(),
|
|
19
|
-
// Remove end
|
|
20
|
-
// TODO(NextAuth): map unique user id to `providerAccountId` field
|
|
21
|
-
// profile(profile) {
|
|
22
|
-
// return {
|
|
23
|
-
// email: profile.email,
|
|
24
|
-
// image: profile.picture,
|
|
25
|
-
// name: profile.name,
|
|
26
|
-
// providerAccountId: profile.user_id,
|
|
27
|
-
// id: profile.user_id,
|
|
28
|
-
// };
|
|
29
|
-
// },
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export default provider;
|