@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/Dockerfile +4 -0
  3. package/Dockerfile.database +4 -0
  4. package/README.ja-JP.md +1 -1
  5. package/README.md +1 -1
  6. package/README.zh-CN.md +1 -1
  7. package/README.zh-TW.md +9 -14
  8. package/changelog/v1.json +21 -0
  9. package/docs/changelog/2024-11-25-november-providers.mdx +1 -1
  10. package/docs/changelog/2024-11-25-november-providers.zh-CN.mdx +1 -1
  11. package/docs/usage/features/multi-ai-providers.mdx +1 -1
  12. package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -1
  13. package/locales/ar/modelProvider.json +0 -1
  14. package/locales/ar/setting.json +12 -9
  15. package/locales/bg-BG/modelProvider.json +0 -1
  16. package/locales/bg-BG/setting.json +12 -9
  17. package/locales/de-DE/modelProvider.json +0 -1
  18. package/locales/de-DE/setting.json +13 -10
  19. package/locales/en-US/modelProvider.json +0 -1
  20. package/locales/en-US/setting.json +12 -9
  21. package/locales/es-ES/modelProvider.json +0 -1
  22. package/locales/es-ES/setting.json +12 -9
  23. package/locales/fa-IR/modelProvider.json +0 -1
  24. package/locales/fa-IR/setting.json +12 -9
  25. package/locales/fr-FR/modelProvider.json +0 -1
  26. package/locales/fr-FR/setting.json +12 -9
  27. package/locales/it-IT/modelProvider.json +0 -1
  28. package/locales/it-IT/setting.json +13 -10
  29. package/locales/ja-JP/modelProvider.json +0 -1
  30. package/locales/ja-JP/setting.json +12 -9
  31. package/locales/ko-KR/modelProvider.json +0 -1
  32. package/locales/ko-KR/setting.json +12 -9
  33. package/locales/nl-NL/modelProvider.json +0 -1
  34. package/locales/nl-NL/setting.json +12 -9
  35. package/locales/pl-PL/modelProvider.json +0 -1
  36. package/locales/pl-PL/setting.json +12 -9
  37. package/locales/pt-BR/modelProvider.json +0 -1
  38. package/locales/pt-BR/setting.json +13 -10
  39. package/locales/ru-RU/modelProvider.json +0 -1
  40. package/locales/ru-RU/setting.json +12 -9
  41. package/locales/tr-TR/modelProvider.json +0 -1
  42. package/locales/tr-TR/setting.json +12 -9
  43. package/locales/vi-VN/modelProvider.json +0 -1
  44. package/locales/vi-VN/setting.json +12 -9
  45. package/locales/zh-CN/modelProvider.json +0 -1
  46. package/locales/zh-CN/setting.json +13 -10
  47. package/locales/zh-TW/modelProvider.json +0 -1
  48. package/locales/zh-TW/setting.json +12 -9
  49. package/package.json +1 -1
  50. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +1 -1
  51. package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +4 -0
  52. package/src/components/InfoTooltip/index.tsx +25 -0
  53. package/src/components/Loading/UpdateLoading/index.tsx +19 -0
  54. package/src/config/aiModels/index.ts +6 -0
  55. package/src/config/aiModels/nvidia.ts +155 -0
  56. package/src/config/aiModels/vllm.ts +94 -0
  57. package/src/config/llm.ts +12 -0
  58. package/src/config/modelProviders/index.ts +8 -0
  59. package/src/config/modelProviders/nvidia.ts +21 -0
  60. package/src/config/modelProviders/vllm.ts +20 -0
  61. package/src/const/url.ts +1 -1
  62. package/src/features/ChatInput/ActionBar/Params/ParamsControls.tsx +95 -0
  63. package/src/features/ChatInput/ActionBar/Params/index.tsx +47 -0
  64. package/src/features/ChatInput/ActionBar/config.ts +3 -2
  65. package/src/features/ChatInput/Mobile/index.tsx +1 -1
  66. package/src/features/ModelParamsControl/FrequencyPenalty.tsx +37 -0
  67. package/src/features/ModelParamsControl/PresencePenalty.tsx +35 -0
  68. package/src/features/ModelParamsControl/Temperature.tsx +71 -0
  69. package/src/features/ModelParamsControl/TopP.tsx +39 -0
  70. package/src/features/ModelParamsControl/index.ts +4 -0
  71. package/src/libs/agent-runtime/AgentRuntime.ts +14 -0
  72. package/src/libs/agent-runtime/nvidia/index.ts +44 -0
  73. package/src/libs/agent-runtime/types/type.ts +2 -0
  74. package/src/libs/agent-runtime/vllm/index.ts +44 -0
  75. package/src/locales/default/setting.ts +12 -9
  76. package/src/types/user/settings/keyVaults.ts +2 -0
  77. 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 Temperature from './Temperature';
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: Temperature,
21
+ temperature: Params,
21
22
  tools: Tools,
22
23
  } as const;
23
24
 
@@ -20,9 +20,9 @@ const defaultLeftActions: ActionKeys[] = [
20
20
  'model',
21
21
  'fileUpload',
22
22
  'knowledgeBase',
23
- 'temperature',
24
23
  'history',
25
24
  'tools',
25
+ 'params',
26
26
  'mainToken',
27
27
  ];
28
28
 
@@ -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;
@@ -0,0 +1,4 @@
1
+ export { default as FrequencyPenalty } from './FrequencyPenalty';
2
+ export { default as PresencePenalty } from './PresencePenalty';
3
+ export { default as Temperature } from './Temperature';
4
+ export { default as TopP } from './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
- titleWithValue: '随机性 {{value}}',
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;