@lobehub/chat 1.53.12 → 1.55.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.
- package/CHANGELOG.md +58 -0
- package/Dockerfile +4 -0
- package/Dockerfile.database +4 -0
- package/README.ja-JP.md +1 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/README.zh-TW.md +9 -14
- package/changelog/v1.json +21 -0
- package/docs/changelog/2024-11-25-november-providers.mdx +1 -1
- package/docs/changelog/2024-11-25-november-providers.zh-CN.mdx +1 -1
- package/docs/usage/features/multi-ai-providers.mdx +1 -1
- package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -1
- package/locales/ar/modelProvider.json +0 -1
- package/locales/ar/setting.json +12 -9
- package/locales/bg-BG/modelProvider.json +0 -1
- package/locales/bg-BG/setting.json +12 -9
- package/locales/de-DE/modelProvider.json +0 -1
- package/locales/de-DE/setting.json +13 -10
- package/locales/en-US/modelProvider.json +0 -1
- package/locales/en-US/setting.json +12 -9
- package/locales/es-ES/modelProvider.json +0 -1
- package/locales/es-ES/setting.json +12 -9
- package/locales/fa-IR/modelProvider.json +0 -1
- package/locales/fa-IR/setting.json +12 -9
- package/locales/fr-FR/modelProvider.json +0 -1
- package/locales/fr-FR/setting.json +12 -9
- package/locales/it-IT/modelProvider.json +0 -1
- package/locales/it-IT/setting.json +13 -10
- package/locales/ja-JP/modelProvider.json +0 -1
- package/locales/ja-JP/setting.json +12 -9
- package/locales/ko-KR/modelProvider.json +0 -1
- package/locales/ko-KR/setting.json +12 -9
- package/locales/nl-NL/modelProvider.json +0 -1
- package/locales/nl-NL/setting.json +12 -9
- package/locales/pl-PL/modelProvider.json +0 -1
- package/locales/pl-PL/setting.json +12 -9
- package/locales/pt-BR/modelProvider.json +0 -1
- package/locales/pt-BR/setting.json +13 -10
- package/locales/ru-RU/modelProvider.json +0 -1
- package/locales/ru-RU/setting.json +12 -9
- package/locales/tr-TR/modelProvider.json +0 -1
- package/locales/tr-TR/setting.json +12 -9
- package/locales/vi-VN/modelProvider.json +0 -1
- package/locales/vi-VN/setting.json +12 -9
- package/locales/zh-CN/modelProvider.json +0 -1
- package/locales/zh-CN/setting.json +13 -10
- package/locales/zh-TW/modelProvider.json +0 -1
- package/locales/zh-TW/setting.json +12 -9
- package/package.json +1 -1
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +4 -0
- package/src/components/InfoTooltip/index.tsx +25 -0
- package/src/components/Loading/UpdateLoading/index.tsx +19 -0
- package/src/config/aiModels/index.ts +6 -0
- package/src/config/aiModels/nvidia.ts +155 -0
- package/src/config/aiModels/vllm.ts +94 -0
- package/src/config/llm.ts +12 -0
- package/src/config/modelProviders/index.ts +8 -0
- package/src/config/modelProviders/nvidia.ts +21 -0
- package/src/config/modelProviders/vllm.ts +20 -0
- package/src/const/url.ts +1 -1
- package/src/features/ChatInput/ActionBar/Params/ParamsControls.tsx +95 -0
- package/src/features/ChatInput/ActionBar/Params/index.tsx +47 -0
- package/src/features/ChatInput/ActionBar/config.ts +3 -2
- package/src/features/ChatInput/Mobile/index.tsx +1 -1
- package/src/features/ModelParamsControl/FrequencyPenalty.tsx +37 -0
- package/src/features/ModelParamsControl/PresencePenalty.tsx +35 -0
- package/src/features/ModelParamsControl/Temperature.tsx +71 -0
- package/src/features/ModelParamsControl/TopP.tsx +39 -0
- package/src/features/ModelParamsControl/index.ts +4 -0
- package/src/libs/agent-runtime/AgentRuntime.ts +14 -0
- package/src/libs/agent-runtime/nvidia/index.ts +44 -0
- package/src/libs/agent-runtime/types/type.ts +2 -0
- package/src/libs/agent-runtime/vllm/index.ts +44 -0
- package/src/locales/default/setting.ts +12 -9
- package/src/types/user/settings/keyVaults.ts +2 -0
- package/src/features/ChatInput/ActionBar/Temperature.tsx +0 -49
@@ -0,0 +1,95 @@
|
|
1
|
+
import { Form, Tag } from '@lobehub/ui';
|
2
|
+
import type { FormItemProps } from '@lobehub/ui/es/Form/components/FormItem';
|
3
|
+
import isEqual from 'fast-deep-equal';
|
4
|
+
import { debounce } from 'lodash-es';
|
5
|
+
import { memo } from 'react';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
8
|
+
|
9
|
+
import InfoTooltip from '@/components/InfoTooltip';
|
10
|
+
import {
|
11
|
+
FrequencyPenalty,
|
12
|
+
PresencePenalty,
|
13
|
+
Temperature,
|
14
|
+
TopP,
|
15
|
+
} from '@/features/ModelParamsControl';
|
16
|
+
import { useAgentStore } from '@/store/agent';
|
17
|
+
import { agentSelectors } from '@/store/agent/selectors';
|
18
|
+
|
19
|
+
interface ParamsControlsProps {
|
20
|
+
setUpdating: (updating: boolean) => void;
|
21
|
+
}
|
22
|
+
const ParamsControls = memo<ParamsControlsProps>(({ setUpdating }) => {
|
23
|
+
const { t } = useTranslation('setting');
|
24
|
+
|
25
|
+
const updateAgentConfig = useAgentStore((s) => s.updateAgentConfig);
|
26
|
+
|
27
|
+
const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
|
28
|
+
|
29
|
+
const items: FormItemProps[] = [
|
30
|
+
{
|
31
|
+
children: <Temperature />,
|
32
|
+
desc: <Tag>temperature</Tag>,
|
33
|
+
label: (
|
34
|
+
<Flexbox gap={8} horizontal>
|
35
|
+
{t('settingModel.temperature.title')}
|
36
|
+
<InfoTooltip title={t('settingModel.temperature.desc')} />
|
37
|
+
</Flexbox>
|
38
|
+
),
|
39
|
+
name: ['params', 'temperature'],
|
40
|
+
},
|
41
|
+
{
|
42
|
+
children: <TopP />,
|
43
|
+
desc: <Tag>top_p</Tag>,
|
44
|
+
label: (
|
45
|
+
<Flexbox gap={8} horizontal>
|
46
|
+
{t('settingModel.topP.title')}
|
47
|
+
<InfoTooltip title={t('settingModel.topP.desc')} />
|
48
|
+
</Flexbox>
|
49
|
+
),
|
50
|
+
name: ['params', 'top_p'],
|
51
|
+
},
|
52
|
+
{
|
53
|
+
children: <PresencePenalty />,
|
54
|
+
desc: <Tag>presence_penalty</Tag>,
|
55
|
+
label: (
|
56
|
+
<Flexbox gap={8} horizontal>
|
57
|
+
{t('settingModel.presencePenalty.title')}
|
58
|
+
<InfoTooltip title={t('settingModel.presencePenalty.desc')} />
|
59
|
+
</Flexbox>
|
60
|
+
),
|
61
|
+
name: ['params', 'presence_penalty'],
|
62
|
+
},
|
63
|
+
{
|
64
|
+
children: <FrequencyPenalty />,
|
65
|
+
desc: <Tag>frequency_penalty</Tag>,
|
66
|
+
label: (
|
67
|
+
<Flexbox gap={8} horizontal>
|
68
|
+
{t('settingModel.frequencyPenalty.title')}
|
69
|
+
<InfoTooltip title={t('settingModel.frequencyPenalty.desc')} />
|
70
|
+
</Flexbox>
|
71
|
+
),
|
72
|
+
name: ['params', 'frequency_penalty'],
|
73
|
+
},
|
74
|
+
];
|
75
|
+
|
76
|
+
return (
|
77
|
+
<Form
|
78
|
+
initialValues={config}
|
79
|
+
itemMinWidth={200}
|
80
|
+
items={items}
|
81
|
+
itemsType={'flat'}
|
82
|
+
onValuesChange={debounce(async (values) => {
|
83
|
+
setUpdating(true);
|
84
|
+
console.log(values);
|
85
|
+
await updateAgentConfig(values);
|
86
|
+
setUpdating(false);
|
87
|
+
}, 500)}
|
88
|
+
size={'small'}
|
89
|
+
style={{ fontSize: 12 }}
|
90
|
+
variant={'pure'}
|
91
|
+
/>
|
92
|
+
);
|
93
|
+
});
|
94
|
+
|
95
|
+
export default ParamsControls;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { ActionIcon } from '@lobehub/ui';
|
2
|
+
import { Popover } from 'antd';
|
3
|
+
import { useTheme } from 'antd-style';
|
4
|
+
import { Settings2Icon } from 'lucide-react';
|
5
|
+
import { memo, useState } from 'react';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
8
|
+
|
9
|
+
import UpdateLoading from '@/components/Loading/UpdateLoading';
|
10
|
+
|
11
|
+
import ParamsControls from './ParamsControls';
|
12
|
+
|
13
|
+
const Params = memo(() => {
|
14
|
+
const { t } = useTranslation('setting');
|
15
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
16
|
+
const [isUpdating, setUpdating] = useState(false);
|
17
|
+
|
18
|
+
const theme = useTheme();
|
19
|
+
return (
|
20
|
+
<Popover
|
21
|
+
arrow={false}
|
22
|
+
content={<ParamsControls setUpdating={setUpdating} />}
|
23
|
+
onOpenChange={setPopoverOpen}
|
24
|
+
open={popoverOpen}
|
25
|
+
placement={'top'}
|
26
|
+
styles={{
|
27
|
+
body: { minWidth: 400 },
|
28
|
+
}}
|
29
|
+
title={
|
30
|
+
<Flexbox horizontal justify={'space-between'}>
|
31
|
+
{t('settingModel.params.title')}
|
32
|
+
|
33
|
+
{isUpdating && <UpdateLoading style={{ color: theme.colorTextSecondary }} />}
|
34
|
+
</Flexbox>
|
35
|
+
}
|
36
|
+
trigger={'click'}
|
37
|
+
>
|
38
|
+
<ActionIcon
|
39
|
+
icon={Settings2Icon}
|
40
|
+
placement={'bottom'}
|
41
|
+
title={popoverOpen ? undefined : t('settingModel.params.title')}
|
42
|
+
/>
|
43
|
+
</Popover>
|
44
|
+
);
|
45
|
+
});
|
46
|
+
|
47
|
+
export default Params;
|
@@ -3,7 +3,7 @@ import Clear from './Clear';
|
|
3
3
|
import History from './History';
|
4
4
|
import Knowledge from './Knowledge';
|
5
5
|
import ModelSwitch from './ModelSwitch';
|
6
|
-
import
|
6
|
+
import Params from './Params';
|
7
7
|
import { MainToken, PortalToken } from './Token';
|
8
8
|
import Tools from './Tools';
|
9
9
|
import Upload from './Upload';
|
@@ -15,9 +15,10 @@ export const actionMap = {
|
|
15
15
|
knowledgeBase: Knowledge,
|
16
16
|
mainToken: MainToken,
|
17
17
|
model: ModelSwitch,
|
18
|
+
params: Params,
|
18
19
|
portalToken: PortalToken,
|
19
20
|
stt: STT,
|
20
|
-
temperature:
|
21
|
+
temperature: Params,
|
21
22
|
tools: Tools,
|
22
23
|
} as const;
|
23
24
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { Icon, SliderWithInput } from '@lobehub/ui';
|
2
|
+
import { useTheme } from 'antd-style';
|
3
|
+
import { BookOpenText, FileIcon } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
interface FrequencyPenaltyProps {
|
8
|
+
onChange?: (value: number) => void;
|
9
|
+
value?: number;
|
10
|
+
}
|
11
|
+
|
12
|
+
const FrequencyPenalty = memo<FrequencyPenaltyProps>(({ value, onChange }) => {
|
13
|
+
const theme = useTheme();
|
14
|
+
|
15
|
+
return (
|
16
|
+
<Flexbox style={{ paddingInlineStart: 8 }}>
|
17
|
+
<SliderWithInput
|
18
|
+
marks={{
|
19
|
+
'-2': (
|
20
|
+
<Icon icon={FileIcon} size={'small'} style={{ color: theme.colorTextQuaternary }} />
|
21
|
+
),
|
22
|
+
0: <div />,
|
23
|
+
2: (
|
24
|
+
<Icon icon={BookOpenText} size={'small'} style={{ color: theme.colorTextQuaternary }} />
|
25
|
+
),
|
26
|
+
}}
|
27
|
+
max={2}
|
28
|
+
min={-2}
|
29
|
+
onChange={onChange}
|
30
|
+
size={'small'}
|
31
|
+
step={0.1}
|
32
|
+
value={value}
|
33
|
+
/>
|
34
|
+
</Flexbox>
|
35
|
+
);
|
36
|
+
});
|
37
|
+
export default FrequencyPenalty;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { Icon, SliderWithInput } from '@lobehub/ui';
|
2
|
+
import { useTheme } from 'antd-style';
|
3
|
+
import { AtomIcon, RepeatIcon } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
interface PresencePenaltyProps {
|
8
|
+
onChange?: (value: number) => void;
|
9
|
+
value?: number;
|
10
|
+
}
|
11
|
+
|
12
|
+
const PresencePenalty = memo<PresencePenaltyProps>(({ value, onChange }) => {
|
13
|
+
const theme = useTheme();
|
14
|
+
|
15
|
+
return (
|
16
|
+
<Flexbox style={{ paddingInlineStart: 8 }}>
|
17
|
+
<SliderWithInput
|
18
|
+
marks={{
|
19
|
+
'-2': (
|
20
|
+
<Icon icon={RepeatIcon} size={'small'} style={{ color: theme.colorTextQuaternary }} />
|
21
|
+
),
|
22
|
+
0: <div />,
|
23
|
+
2: <Icon icon={AtomIcon} size={'small'} style={{ color: theme.colorTextQuaternary }} />,
|
24
|
+
}}
|
25
|
+
max={2}
|
26
|
+
min={-2}
|
27
|
+
onChange={onChange}
|
28
|
+
size={'small'}
|
29
|
+
step={0.1}
|
30
|
+
value={value}
|
31
|
+
/>
|
32
|
+
</Flexbox>
|
33
|
+
);
|
34
|
+
});
|
35
|
+
export default PresencePenalty;
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import { Alert, Icon, SliderWithInput } from '@lobehub/ui';
|
2
|
+
import { css, cx, useTheme } from 'antd-style';
|
3
|
+
import { Sparkle, Sparkles } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
import { Flexbox } from 'react-layout-kit';
|
7
|
+
|
8
|
+
import { useAgentStore } from '@/store/agent';
|
9
|
+
import { agentSelectors } from '@/store/agent/selectors';
|
10
|
+
|
11
|
+
const alertCls = css`
|
12
|
+
.ant-alert-message {
|
13
|
+
font-size: 12px;
|
14
|
+
line-height: 18px !important;
|
15
|
+
}
|
16
|
+
|
17
|
+
.ant-alert-icon {
|
18
|
+
height: 18px !important;
|
19
|
+
}
|
20
|
+
`;
|
21
|
+
|
22
|
+
const Warning = memo(() => {
|
23
|
+
const { t } = useTranslation('setting');
|
24
|
+
const [temperature] = useAgentStore((s) => {
|
25
|
+
const config = agentSelectors.currentAgentConfig(s);
|
26
|
+
return [config.params?.temperature];
|
27
|
+
});
|
28
|
+
|
29
|
+
return (
|
30
|
+
typeof temperature === 'number' &&
|
31
|
+
temperature >= 1.5 && (
|
32
|
+
<Alert
|
33
|
+
classNames={{ alert: cx(alertCls) }}
|
34
|
+
message={t('settingModel.temperature.warning')}
|
35
|
+
style={{ fontSize: 12 }}
|
36
|
+
type={'warning'}
|
37
|
+
variant={'pure'}
|
38
|
+
/>
|
39
|
+
)
|
40
|
+
);
|
41
|
+
});
|
42
|
+
|
43
|
+
interface TemperatureProps {
|
44
|
+
onChange?: (value: number) => void;
|
45
|
+
value?: number;
|
46
|
+
}
|
47
|
+
|
48
|
+
const Temperature = memo<TemperatureProps>(({ value, onChange }) => {
|
49
|
+
const theme = useTheme();
|
50
|
+
return (
|
51
|
+
<Flexbox gap={4} style={{ paddingInlineStart: 8 }}>
|
52
|
+
<SliderWithInput
|
53
|
+
controls={false}
|
54
|
+
marks={{
|
55
|
+
0: <Icon icon={Sparkle} size={'small'} style={{ color: theme.colorTextQuaternary }} />,
|
56
|
+
1: <div />,
|
57
|
+
2: <Icon icon={Sparkles} size={'small'} style={{ color: theme.colorTextQuaternary }} />,
|
58
|
+
}}
|
59
|
+
max={2}
|
60
|
+
onChange={onChange}
|
61
|
+
size={'small'}
|
62
|
+
step={0.1}
|
63
|
+
style={{ height: 48 }}
|
64
|
+
value={value}
|
65
|
+
/>
|
66
|
+
<Warning />
|
67
|
+
</Flexbox>
|
68
|
+
);
|
69
|
+
});
|
70
|
+
|
71
|
+
export default Temperature;
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { Icon, SliderWithInput } from '@lobehub/ui';
|
2
|
+
import { useTheme } from 'antd-style';
|
3
|
+
import { FlowerIcon, TrainFrontTunnel } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
interface TopPProps {
|
8
|
+
onChange?: (value: number) => void;
|
9
|
+
value?: number;
|
10
|
+
}
|
11
|
+
|
12
|
+
const TopP = memo<TopPProps>(({ value, onChange }) => {
|
13
|
+
const theme = useTheme();
|
14
|
+
|
15
|
+
return (
|
16
|
+
<Flexbox style={{ paddingInlineStart: 8 }}>
|
17
|
+
<SliderWithInput
|
18
|
+
marks={{
|
19
|
+
0: (
|
20
|
+
<Icon
|
21
|
+
icon={TrainFrontTunnel}
|
22
|
+
size={'small'}
|
23
|
+
style={{ color: theme.colorTextQuaternary }}
|
24
|
+
/>
|
25
|
+
),
|
26
|
+
0.9: <div />,
|
27
|
+
1: <Icon icon={FlowerIcon} size={'small'} style={{ color: theme.colorTextQuaternary }} />,
|
28
|
+
}}
|
29
|
+
max={1}
|
30
|
+
min={0}
|
31
|
+
onChange={onChange}
|
32
|
+
size={'small'}
|
33
|
+
step={0.1}
|
34
|
+
value={value}
|
35
|
+
/>
|
36
|
+
</Flexbox>
|
37
|
+
);
|
38
|
+
});
|
39
|
+
export default TopP;
|
@@ -26,6 +26,7 @@ import { LobeMinimaxAI } from './minimax';
|
|
26
26
|
import { LobeMistralAI } from './mistral';
|
27
27
|
import { LobeMoonshotAI } from './moonshot';
|
28
28
|
import { LobeNovitaAI } from './novita';
|
29
|
+
import { LobeNvidiaAI } from './nvidia';
|
29
30
|
import { LobeOllamaAI } from './ollama';
|
30
31
|
import { LobeOpenAI } from './openai';
|
31
32
|
import { LobeOpenRouterAI } from './openrouter';
|
@@ -48,6 +49,7 @@ import {
|
|
48
49
|
TextToSpeechPayload,
|
49
50
|
} from './types';
|
50
51
|
import { LobeUpstageAI } from './upstage';
|
52
|
+
import { LobeVLLMAI } from './vllm';
|
51
53
|
import { LobeWenxinAI } from './wenxin';
|
52
54
|
import { LobeXAI } from './xai';
|
53
55
|
import { LobeZeroOneAI } from './zeroone';
|
@@ -157,6 +159,7 @@ class AgentRuntime {
|
|
157
159
|
mistral: Partial<ClientOptions>;
|
158
160
|
moonshot: Partial<ClientOptions>;
|
159
161
|
novita: Partial<ClientOptions>;
|
162
|
+
nvidia: Partial<ClientOptions>;
|
160
163
|
ollama: Partial<ClientOptions>;
|
161
164
|
openai: Partial<ClientOptions>;
|
162
165
|
openrouter: Partial<ClientOptions>;
|
@@ -170,6 +173,7 @@ class AgentRuntime {
|
|
170
173
|
tencentcloud: Partial<ClientOptions>;
|
171
174
|
togetherai: Partial<ClientOptions>;
|
172
175
|
upstage: Partial<ClientOptions>;
|
176
|
+
vllm: Partial<ClientOptions>;
|
173
177
|
wenxin: Partial<ClientOptions>;
|
174
178
|
xai: Partial<ClientOptions>;
|
175
179
|
zeroone: Partial<ClientOptions>;
|
@@ -225,6 +229,11 @@ class AgentRuntime {
|
|
225
229
|
break;
|
226
230
|
}
|
227
231
|
|
232
|
+
case ModelProvider.VLLM: {
|
233
|
+
runtimeModel = new LobeVLLMAI(params.vllm);
|
234
|
+
break;
|
235
|
+
}
|
236
|
+
|
228
237
|
case ModelProvider.Perplexity: {
|
229
238
|
runtimeModel = new LobePerplexityAI(params.perplexity);
|
230
239
|
break;
|
@@ -300,6 +309,11 @@ class AgentRuntime {
|
|
300
309
|
break;
|
301
310
|
}
|
302
311
|
|
312
|
+
case ModelProvider.Nvidia: {
|
313
|
+
runtimeModel = new LobeNvidiaAI(params.nvidia);
|
314
|
+
break;
|
315
|
+
}
|
316
|
+
|
303
317
|
case ModelProvider.Baichuan: {
|
304
318
|
runtimeModel = new LobeBaichuanAI(params.baichuan ?? {});
|
305
319
|
break;
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import { ModelProvider } from '../types';
|
2
|
+
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
|
+
|
4
|
+
import type { ChatModelCard } from '@/types/llm';
|
5
|
+
|
6
|
+
export interface NvidiaModelCard {
|
7
|
+
id: string;
|
8
|
+
}
|
9
|
+
|
10
|
+
export const LobeNvidiaAI = LobeOpenAICompatibleFactory({
|
11
|
+
baseURL: 'https://integrate.api.nvidia.com/v1',
|
12
|
+
debug: {
|
13
|
+
chatCompletion: () => process.env.DEBUG_NVIDIA_CHAT_COMPLETION === '1',
|
14
|
+
},
|
15
|
+
models: async ({ client }) => {
|
16
|
+
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
17
|
+
|
18
|
+
const modelsPage = await client.models.list() as any;
|
19
|
+
const modelList: NvidiaModelCard[] = modelsPage.data;
|
20
|
+
|
21
|
+
return modelList
|
22
|
+
.map((model) => {
|
23
|
+
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());
|
24
|
+
|
25
|
+
return {
|
26
|
+
contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
|
27
|
+
displayName: knownModel?.displayName ?? undefined,
|
28
|
+
enabled: knownModel?.enabled || false,
|
29
|
+
functionCall:
|
30
|
+
knownModel?.abilities?.functionCall
|
31
|
+
|| false,
|
32
|
+
id: model.id,
|
33
|
+
reasoning:
|
34
|
+
knownModel?.abilities?.reasoning
|
35
|
+
|| false,
|
36
|
+
vision:
|
37
|
+
knownModel?.abilities?.vision
|
38
|
+
|| false,
|
39
|
+
};
|
40
|
+
})
|
41
|
+
.filter(Boolean) as ChatModelCard[];
|
42
|
+
},
|
43
|
+
provider: ModelProvider.Nvidia,
|
44
|
+
});
|
@@ -45,6 +45,7 @@ export enum ModelProvider {
|
|
45
45
|
Mistral = 'mistral',
|
46
46
|
Moonshot = 'moonshot',
|
47
47
|
Novita = 'novita',
|
48
|
+
Nvidia = 'nvidia',
|
48
49
|
Ollama = 'ollama',
|
49
50
|
OpenAI = 'openai',
|
50
51
|
OpenRouter = 'openrouter',
|
@@ -58,6 +59,7 @@ export enum ModelProvider {
|
|
58
59
|
TencentCloud = 'tencentcloud',
|
59
60
|
TogetherAI = 'togetherai',
|
60
61
|
Upstage = 'upstage',
|
62
|
+
VLLM = 'vllm',
|
61
63
|
Wenxin = 'wenxin',
|
62
64
|
XAI = 'xai',
|
63
65
|
ZeroOne = 'zeroone',
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import { ModelProvider } from '../types';
|
2
|
+
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
|
+
|
4
|
+
import type { ChatModelCard } from '@/types/llm';
|
5
|
+
|
6
|
+
export interface VLLMModelCard {
|
7
|
+
id: string;
|
8
|
+
}
|
9
|
+
|
10
|
+
export const LobeVLLMAI = LobeOpenAICompatibleFactory({
|
11
|
+
baseURL: 'http://localhost:8000/v1',
|
12
|
+
debug: {
|
13
|
+
chatCompletion: () => process.env.DEBUG_VLLM_CHAT_COMPLETION === '1',
|
14
|
+
},
|
15
|
+
models: async ({ client }) => {
|
16
|
+
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
17
|
+
|
18
|
+
const modelsPage = await client.models.list() as any;
|
19
|
+
const modelList: VLLMModelCard[] = modelsPage.data;
|
20
|
+
|
21
|
+
return modelList
|
22
|
+
.map((model) => {
|
23
|
+
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());
|
24
|
+
|
25
|
+
return {
|
26
|
+
contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
|
27
|
+
displayName: knownModel?.displayName ?? undefined,
|
28
|
+
enabled: knownModel?.enabled || false,
|
29
|
+
functionCall:
|
30
|
+
knownModel?.abilities?.functionCall
|
31
|
+
|| false,
|
32
|
+
id: model.id,
|
33
|
+
reasoning:
|
34
|
+
knownModel?.abilities?.reasoning
|
35
|
+
|| false,
|
36
|
+
vision:
|
37
|
+
knownModel?.abilities?.vision
|
38
|
+
|| false,
|
39
|
+
};
|
40
|
+
})
|
41
|
+
.filter(Boolean) as ChatModelCard[];
|
42
|
+
},
|
43
|
+
provider: ModelProvider.VLLM,
|
44
|
+
});
|
@@ -206,8 +206,8 @@ export default {
|
|
206
206
|
title: '开启推理强度调整',
|
207
207
|
},
|
208
208
|
frequencyPenalty: {
|
209
|
-
desc: '
|
210
|
-
title: '
|
209
|
+
desc: '值越大,用词越丰富多样;值越低,用词更朴实简单',
|
210
|
+
title: '词汇丰富度',
|
211
211
|
},
|
212
212
|
maxTokens: {
|
213
213
|
desc: '单次交互所用的最大 Token 数',
|
@@ -217,9 +217,12 @@ export default {
|
|
217
217
|
desc: '{{provider}} 模型',
|
218
218
|
title: '模型',
|
219
219
|
},
|
220
|
+
params: {
|
221
|
+
title: '高级参数',
|
222
|
+
},
|
220
223
|
presencePenalty: {
|
221
|
-
desc: '
|
222
|
-
title: '
|
224
|
+
desc: '值越大,越倾向不同的表达方式,避免概念重复;值越小,越倾向使用重复的概念或叙述,表达更具一致性',
|
225
|
+
title: '表述发散度',
|
223
226
|
},
|
224
227
|
reasoningEffort: {
|
225
228
|
desc: '值越大,推理能力越强,但可能会增加响应时间和 Token 消耗',
|
@@ -231,14 +234,14 @@ export default {
|
|
231
234
|
title: '推理强度',
|
232
235
|
},
|
233
236
|
temperature: {
|
234
|
-
desc: '
|
235
|
-
title: '
|
236
|
-
|
237
|
+
desc: '数值越大,回答越有创意和想象力;数值越小,回答越严谨',
|
238
|
+
title: '创意活跃度',
|
239
|
+
warning: '创意活跃度数值过大,输出可能会产生乱码',
|
237
240
|
},
|
238
241
|
title: '模型设置',
|
239
242
|
topP: {
|
240
|
-
desc: '
|
241
|
-
title: '
|
243
|
+
desc: '考虑多少种可能性,值越大,接受更多可能的回答;值越小,倾向选择最可能的回答。不推荐和创意活跃度一起更改',
|
244
|
+
title: '思维开放度',
|
242
245
|
},
|
243
246
|
},
|
244
247
|
settingPlugin: {
|
@@ -50,6 +50,7 @@ export interface UserKeyVaults {
|
|
50
50
|
mistral?: OpenAICompatibleKeyVault;
|
51
51
|
moonshot?: OpenAICompatibleKeyVault;
|
52
52
|
novita?: OpenAICompatibleKeyVault;
|
53
|
+
nvidia?: OpenAICompatibleKeyVault;
|
53
54
|
ollama?: OpenAICompatibleKeyVault;
|
54
55
|
openai?: OpenAICompatibleKeyVault;
|
55
56
|
openrouter?: OpenAICompatibleKeyVault;
|
@@ -64,6 +65,7 @@ export interface UserKeyVaults {
|
|
64
65
|
tencentcloud?: OpenAICompatibleKeyVault;
|
65
66
|
togetherai?: OpenAICompatibleKeyVault;
|
66
67
|
upstage?: OpenAICompatibleKeyVault;
|
68
|
+
vllm?: OpenAICompatibleKeyVault;
|
67
69
|
wenxin?: OpenAICompatibleKeyVault;
|
68
70
|
xai?: OpenAICompatibleKeyVault;
|
69
71
|
zeroone?: OpenAICompatibleKeyVault;
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import { ActionIcon, SliderWithInput } from '@lobehub/ui';
|
2
|
-
import { Popover } from 'antd';
|
3
|
-
import { Thermometer } from 'lucide-react';
|
4
|
-
import { memo, useState } from 'react';
|
5
|
-
import { useTranslation } from 'react-i18next';
|
6
|
-
|
7
|
-
import { useAgentStore } from '@/store/agent';
|
8
|
-
import { agentSelectors } from '@/store/agent/selectors';
|
9
|
-
|
10
|
-
const Temperature = memo(() => {
|
11
|
-
const { t } = useTranslation('setting');
|
12
|
-
const [popoverOpen, setPopoverOpen] = useState(false);
|
13
|
-
|
14
|
-
const [temperature, updateAgentConfig] = useAgentStore((s) => {
|
15
|
-
const config = agentSelectors.currentAgentConfig(s);
|
16
|
-
return [config.params?.temperature, s.updateAgentConfig];
|
17
|
-
});
|
18
|
-
|
19
|
-
const title = t('settingModel.temperature.titleWithValue', { value: temperature });
|
20
|
-
|
21
|
-
return (
|
22
|
-
<Popover
|
23
|
-
arrow={false}
|
24
|
-
content={
|
25
|
-
<SliderWithInput
|
26
|
-
controls={false}
|
27
|
-
max={2}
|
28
|
-
min={0}
|
29
|
-
onChange={(v) => {
|
30
|
-
updateAgentConfig({ params: { temperature: v } });
|
31
|
-
}}
|
32
|
-
size={'small'}
|
33
|
-
step={0.1}
|
34
|
-
style={{ width: 160 }}
|
35
|
-
value={temperature}
|
36
|
-
/>
|
37
|
-
}
|
38
|
-
onOpenChange={setPopoverOpen}
|
39
|
-
open={popoverOpen}
|
40
|
-
placement={'top'}
|
41
|
-
title={t('settingModel.temperature.title')}
|
42
|
-
trigger={'click'}
|
43
|
-
>
|
44
|
-
<ActionIcon icon={Thermometer} placement={'bottom'} title={popoverOpen ? undefined : title} />
|
45
|
-
</Popover>
|
46
|
-
);
|
47
|
-
});
|
48
|
-
|
49
|
-
export default Temperature;
|