@lobehub/lobehub 2.0.0-next.2 → 2.0.0-next.3

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 (29) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/changelog/v1.json +9 -0
  3. package/package.json +1 -1
  4. package/packages/const/src/models.ts +13 -0
  5. package/packages/model-bank/src/aiModels/azure.ts +155 -0
  6. package/packages/model-bank/src/aiModels/bedrock.ts +44 -0
  7. package/packages/model-runtime/src/core/parameterResolver.ts +3 -0
  8. package/packages/model-runtime/src/providers/azureOpenai/index.ts +2 -1
  9. package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +0 -3
  10. package/src/app/[variants]/(main)/settings/llm/ProviderList/Azure/index.tsx +0 -93
  11. package/src/app/[variants]/(main)/settings/llm/ProviderList/Bedrock/index.tsx +0 -70
  12. package/src/app/[variants]/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +0 -39
  13. package/src/app/[variants]/(main)/settings/llm/ProviderList/Github/index.tsx +0 -52
  14. package/src/app/[variants]/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +0 -52
  15. package/src/app/[variants]/(main)/settings/llm/ProviderList/Ollama/index.tsx +0 -20
  16. package/src/app/[variants]/(main)/settings/llm/ProviderList/OpenAI/index.tsx +0 -17
  17. package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +0 -132
  18. package/src/app/[variants]/(main)/settings/llm/components/Checker.tsx +0 -118
  19. package/src/app/[variants]/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -303
  20. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +0 -98
  21. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/Form.tsx +0 -104
  22. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +0 -77
  23. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -105
  24. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/Option.tsx +0 -68
  25. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/index.tsx +0 -146
  26. package/src/app/[variants]/(main)/settings/llm/const.ts +0 -20
  27. package/src/app/[variants]/(main)/settings/llm/features/Footer.tsx +0 -35
  28. package/src/app/[variants]/(main)/settings/llm/index.tsx +0 -30
  29. package/src/app/[variants]/(main)/settings/llm/type.ts +0 -5
@@ -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;
@@ -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,5 +0,0 @@
1
- import { ProviderConfigProps } from './components/ProviderConfig';
2
-
3
- export interface ProviderItem extends Omit<ProviderConfigProps, 'id'> {
4
- id: string;
5
- }