@lobehub/chat 1.97.16 → 1.98.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 +50 -0
- package/apps/desktop/package.json +8 -5
- package/apps/desktop/src/main/const/store.ts +12 -0
- package/apps/desktop/src/main/controllers/NetworkProxyCtr.ts +172 -0
- package/apps/desktop/src/main/controllers/__tests__/NetworkProxyCtr.test.ts +401 -0
- package/apps/desktop/src/main/core/Browser.ts +2 -0
- package/apps/desktop/src/main/modules/networkProxy/dispatcher.ts +116 -0
- package/apps/desktop/src/main/modules/networkProxy/index.ts +6 -0
- package/apps/desktop/src/main/modules/networkProxy/tester.ts +163 -0
- package/apps/desktop/src/main/modules/networkProxy/urlBuilder.ts +25 -0
- package/apps/desktop/src/main/modules/networkProxy/validator.ts +80 -0
- package/apps/desktop/src/main/types/store.ts +2 -1
- package/apps/desktop/src/main/utils/logger.ts +2 -1
- package/changelog/v1.json +18 -0
- package/locales/ar/electron.json +39 -0
- package/locales/ar/setting.json +1 -0
- package/locales/bg-BG/electron.json +39 -0
- package/locales/bg-BG/setting.json +1 -0
- package/locales/de-DE/electron.json +39 -0
- package/locales/de-DE/setting.json +1 -0
- package/locales/en-US/electron.json +39 -0
- package/locales/en-US/setting.json +1 -0
- package/locales/es-ES/electron.json +39 -0
- package/locales/es-ES/setting.json +1 -0
- package/locales/fa-IR/electron.json +39 -0
- package/locales/fa-IR/setting.json +1 -0
- package/locales/fr-FR/electron.json +39 -0
- package/locales/fr-FR/setting.json +1 -0
- package/locales/it-IT/electron.json +39 -0
- package/locales/it-IT/setting.json +1 -0
- package/locales/ja-JP/electron.json +39 -0
- package/locales/ja-JP/setting.json +1 -0
- package/locales/ko-KR/electron.json +39 -0
- package/locales/ko-KR/setting.json +1 -0
- package/locales/nl-NL/electron.json +39 -0
- package/locales/nl-NL/setting.json +1 -0
- package/locales/pl-PL/electron.json +39 -0
- package/locales/pl-PL/setting.json +1 -0
- package/locales/pt-BR/electron.json +39 -0
- package/locales/pt-BR/setting.json +1 -0
- package/locales/ru-RU/electron.json +39 -0
- package/locales/ru-RU/setting.json +1 -0
- package/locales/tr-TR/electron.json +39 -0
- package/locales/tr-TR/setting.json +1 -0
- package/locales/vi-VN/electron.json +39 -0
- package/locales/vi-VN/setting.json +1 -0
- package/locales/zh-CN/electron.json +39 -0
- package/locales/zh-CN/setting.json +1 -0
- package/locales/zh-TW/electron.json +39 -0
- package/locales/zh-TW/setting.json +1 -0
- package/package.json +3 -3
- package/packages/electron-client-ipc/src/events/index.ts +3 -1
- package/packages/electron-client-ipc/src/events/settings.ts +12 -0
- package/packages/electron-client-ipc/src/types/index.ts +1 -0
- package/packages/electron-client-ipc/src/types/proxy.ts +12 -0
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +11 -1
- package/src/app/[variants]/(main)/settings/proxy/features/ProxyForm.tsx +369 -0
- package/src/app/[variants]/(main)/settings/proxy/index.tsx +22 -0
- package/src/app/[variants]/(main)/settings/proxy/page.tsx +28 -0
- package/src/config/aiModels/google.ts +15 -26
- package/src/config/aiModels/groq.ts +0 -16
- package/src/config/aiModels/hunyuan.ts +79 -1
- package/src/config/aiModels/novita.ts +50 -56
- package/src/config/aiModels/qwen.ts +10 -32
- package/src/config/aiModels/siliconcloud.ts +111 -86
- package/src/config/aiModels/zhipu.ts +74 -12
- package/src/config/modelProviders/zhipu.ts +1 -2
- package/src/libs/model-runtime/hunyuan/index.ts +9 -1
- package/src/locales/default/electron.ts +39 -0
- package/src/locales/default/setting.ts +1 -0
- package/src/services/electron/settings.ts +33 -0
- package/src/store/electron/actions/settings.ts +55 -0
- package/src/store/electron/initialState.ts +12 -1
- package/src/store/electron/selectors/__tests__/desktopState.test.ts +3 -1
- package/src/store/electron/store.ts +4 -1
- package/src/store/global/initialState.ts +1 -0
- package/apps/desktop/scripts/pglite-server.ts +0 -14
@@ -0,0 +1,369 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { NetworkProxySettings } from '@lobechat/electron-client-ipc';
|
4
|
+
import { Alert, Block, Text } from '@lobehub/ui';
|
5
|
+
import { App, Button, Divider, Form, Input, Radio, Skeleton, Space, Switch } from 'antd';
|
6
|
+
import isEqual from 'fast-deep-equal';
|
7
|
+
import { useCallback, useEffect, useState } from 'react';
|
8
|
+
import { useTranslation } from 'react-i18next';
|
9
|
+
import { Flexbox } from 'react-layout-kit';
|
10
|
+
|
11
|
+
import { desktopSettingsService } from '@/services/electron/settings';
|
12
|
+
import { useElectronStore } from '@/store/electron';
|
13
|
+
|
14
|
+
interface ProxyTestResult {
|
15
|
+
message?: string;
|
16
|
+
responseTime?: number;
|
17
|
+
success: boolean;
|
18
|
+
}
|
19
|
+
|
20
|
+
const ProxyForm = () => {
|
21
|
+
const { t } = useTranslation('electron');
|
22
|
+
const [form] = Form.useForm();
|
23
|
+
const { message } = App.useApp();
|
24
|
+
const [testUrl, setTestUrl] = useState('https://www.google.com');
|
25
|
+
const [isTesting, setIsTesting] = useState(false);
|
26
|
+
const [isSaving, setIsSaving] = useState(false);
|
27
|
+
const [testResult, setTestResult] = useState<ProxyTestResult | null>(null);
|
28
|
+
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
29
|
+
|
30
|
+
const isEnableProxy = Form.useWatch('enableProxy', form);
|
31
|
+
const proxyRequireAuth = Form.useWatch('proxyRequireAuth', form);
|
32
|
+
|
33
|
+
const [setProxySettings, useGetProxySettings] = useElectronStore((s) => [
|
34
|
+
s.setProxySettings,
|
35
|
+
s.useGetProxySettings,
|
36
|
+
]);
|
37
|
+
const { data: proxySettings, isLoading } = useGetProxySettings();
|
38
|
+
|
39
|
+
useEffect(() => {
|
40
|
+
if (proxySettings) {
|
41
|
+
form.setFieldsValue(proxySettings);
|
42
|
+
setHasUnsavedChanges(false);
|
43
|
+
}
|
44
|
+
}, [form, proxySettings]);
|
45
|
+
|
46
|
+
// 监听表单变化
|
47
|
+
const handleValuesChange = useCallback(() => {
|
48
|
+
setHasUnsavedChanges(true);
|
49
|
+
setTestResult(null); // 清除之前的测试结果
|
50
|
+
}, []);
|
51
|
+
|
52
|
+
const updateFormValue = (value: any) => {
|
53
|
+
const preValues = form.getFieldsValue();
|
54
|
+
form.setFieldsValue(value);
|
55
|
+
const newValues = form.getFieldsValue();
|
56
|
+
if (isEqual(newValues, preValues)) return;
|
57
|
+
|
58
|
+
handleValuesChange();
|
59
|
+
};
|
60
|
+
|
61
|
+
// 保存配置
|
62
|
+
const handleSave = useCallback(async () => {
|
63
|
+
try {
|
64
|
+
setIsSaving(true);
|
65
|
+
const values = await form.validateFields();
|
66
|
+
await setProxySettings(values);
|
67
|
+
setHasUnsavedChanges(false);
|
68
|
+
message.success(t('proxy.saveSuccess'));
|
69
|
+
} catch (error) {
|
70
|
+
if (error instanceof Error) {
|
71
|
+
message.error(t('proxy.saveFailed', { error: error.message }));
|
72
|
+
}
|
73
|
+
} finally {
|
74
|
+
setIsSaving(false);
|
75
|
+
}
|
76
|
+
}, [form, t, message]);
|
77
|
+
|
78
|
+
// 重置配置
|
79
|
+
const handleReset = useCallback(() => {
|
80
|
+
if (proxySettings) {
|
81
|
+
form.setFieldsValue(proxySettings);
|
82
|
+
setHasUnsavedChanges(false);
|
83
|
+
setTestResult(null);
|
84
|
+
}
|
85
|
+
}, [form, proxySettings]);
|
86
|
+
|
87
|
+
// 测试代理配置
|
88
|
+
const handleTest = useCallback(async () => {
|
89
|
+
try {
|
90
|
+
setIsTesting(true);
|
91
|
+
setTestResult(null);
|
92
|
+
|
93
|
+
// 验证表单并获取当前配置
|
94
|
+
const values = await form.validateFields();
|
95
|
+
const config: NetworkProxySettings = {
|
96
|
+
...proxySettings,
|
97
|
+
...values,
|
98
|
+
};
|
99
|
+
|
100
|
+
// 使用新的 testProxyConfig 方法测试用户正在配置的代理
|
101
|
+
const result = await desktopSettingsService.testProxyConfig(config, testUrl);
|
102
|
+
|
103
|
+
setTestResult(result);
|
104
|
+
} catch (error) {
|
105
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
106
|
+
const result: ProxyTestResult = {
|
107
|
+
message: errorMessage,
|
108
|
+
success: false,
|
109
|
+
};
|
110
|
+
setTestResult(result);
|
111
|
+
message.error(t('proxy.testFailed'));
|
112
|
+
} finally {
|
113
|
+
setIsTesting(false);
|
114
|
+
}
|
115
|
+
}, [proxySettings, testUrl]);
|
116
|
+
|
117
|
+
if (isLoading) return <Skeleton />;
|
118
|
+
|
119
|
+
return (
|
120
|
+
<Form
|
121
|
+
disabled={isSaving}
|
122
|
+
form={form}
|
123
|
+
layout="vertical"
|
124
|
+
onValuesChange={handleValuesChange}
|
125
|
+
requiredMark={false}
|
126
|
+
>
|
127
|
+
<Flexbox gap={24}>
|
128
|
+
{/* 基本代理设置 */}
|
129
|
+
<Block
|
130
|
+
paddingBlock={16}
|
131
|
+
paddingInline={24}
|
132
|
+
style={{ borderRadius: 12 }}
|
133
|
+
variant={'outlined'}
|
134
|
+
>
|
135
|
+
<Form.Item name="enableProxy" noStyle valuePropName="checked">
|
136
|
+
<Flexbox align={'center'} horizontal justify={'space-between'}>
|
137
|
+
<Flexbox>
|
138
|
+
<Text as={'h4'}>{t('proxy.enable')}</Text>
|
139
|
+
<Text type={'secondary'}>{t('proxy.enableDesc')}</Text>
|
140
|
+
</Flexbox>
|
141
|
+
<Switch
|
142
|
+
checked={isEnableProxy}
|
143
|
+
onChange={(checked) => {
|
144
|
+
updateFormValue({ enableProxy: checked });
|
145
|
+
}}
|
146
|
+
/>
|
147
|
+
</Flexbox>
|
148
|
+
</Form.Item>
|
149
|
+
</Block>
|
150
|
+
|
151
|
+
{/* 认证设置 */}
|
152
|
+
<Block
|
153
|
+
paddingBlock={16}
|
154
|
+
paddingInline={24}
|
155
|
+
style={{ borderRadius: 12 }}
|
156
|
+
variant={'outlined'}
|
157
|
+
>
|
158
|
+
<Flexbox gap={24}>
|
159
|
+
<Flexbox>
|
160
|
+
<Text as={'h4'}>{t('proxy.basicSettings')}</Text>
|
161
|
+
<Text type={'secondary'}>{t('proxy.basicSettingsDesc')}</Text>
|
162
|
+
</Flexbox>
|
163
|
+
<Flexbox>
|
164
|
+
<Form.Item
|
165
|
+
dependencies={['enableProxy']}
|
166
|
+
label={t('proxy.type')}
|
167
|
+
name="proxyType"
|
168
|
+
rules={[
|
169
|
+
({ getFieldValue }) => ({
|
170
|
+
message: t('proxy.validation.typeRequired'),
|
171
|
+
required: getFieldValue('enableProxy'),
|
172
|
+
}),
|
173
|
+
]}
|
174
|
+
>
|
175
|
+
<Radio.Group disabled={!form.getFieldValue('enableProxy')}>
|
176
|
+
<Radio value="http">HTTP</Radio>
|
177
|
+
<Radio value="https">HTTPS</Radio>
|
178
|
+
<Radio value="socks5">SOCKS5</Radio>
|
179
|
+
</Radio.Group>
|
180
|
+
</Form.Item>
|
181
|
+
|
182
|
+
<Space.Compact style={{ width: '100%' }}>
|
183
|
+
<Form.Item
|
184
|
+
dependencies={['enableProxy']}
|
185
|
+
label={t('proxy.server')}
|
186
|
+
name="proxyServer"
|
187
|
+
rules={[
|
188
|
+
({ getFieldValue }) => ({
|
189
|
+
message: t('proxy.validation.serverRequired'),
|
190
|
+
required: getFieldValue('enableProxy'),
|
191
|
+
}),
|
192
|
+
{
|
193
|
+
message: t('proxy.validation.serverInvalid'),
|
194
|
+
pattern:
|
195
|
+
/^((25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(25[0-5]|2[0-4]\d|[01]?\d{1,2})$|^[\dA-Za-z]([\dA-Za-z-]*[\dA-Za-z])?(\.[\dA-Za-z]([\dA-Za-z-]*[\dA-Za-z])?)*$/,
|
196
|
+
},
|
197
|
+
]}
|
198
|
+
style={{ flex: 1, marginBottom: 0 }}
|
199
|
+
>
|
200
|
+
<Input disabled={!form.getFieldValue('enableProxy')} placeholder="127.0.0.1" />
|
201
|
+
</Form.Item>
|
202
|
+
|
203
|
+
<Form.Item
|
204
|
+
dependencies={['enableProxy']}
|
205
|
+
label={t('proxy.port')}
|
206
|
+
name="proxyPort"
|
207
|
+
rules={[
|
208
|
+
({ getFieldValue }) => ({
|
209
|
+
message: t('proxy.validation.portRequired'),
|
210
|
+
required: getFieldValue('enableProxy'),
|
211
|
+
}),
|
212
|
+
{
|
213
|
+
message: t('proxy.validation.portInvalid'),
|
214
|
+
pattern:
|
215
|
+
/^([1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/,
|
216
|
+
},
|
217
|
+
]}
|
218
|
+
style={{ marginBottom: 0, width: 120 }}
|
219
|
+
>
|
220
|
+
<Input disabled={!form.getFieldValue('enableProxy')} placeholder="7890" />
|
221
|
+
</Form.Item>
|
222
|
+
</Space.Compact>
|
223
|
+
</Flexbox>
|
224
|
+
<Divider size={'small'} />
|
225
|
+
<Flexbox gap={12}>
|
226
|
+
<Form.Item
|
227
|
+
dependencies={['enableProxy']}
|
228
|
+
name="proxyRequireAuth"
|
229
|
+
noStyle
|
230
|
+
valuePropName="checked"
|
231
|
+
>
|
232
|
+
<Flexbox align={'center'} horizontal justify={'space-between'}>
|
233
|
+
<Flexbox>
|
234
|
+
<Text as={'h5'}>{t('proxy.auth')}</Text>
|
235
|
+
<Text type={'secondary'}>{t('proxy.authDesc')}</Text>
|
236
|
+
</Flexbox>
|
237
|
+
<Switch
|
238
|
+
checked={proxyRequireAuth}
|
239
|
+
disabled={!isEnableProxy}
|
240
|
+
onChange={(checked) => {
|
241
|
+
updateFormValue({ proxyRequireAuth: checked });
|
242
|
+
}}
|
243
|
+
/>
|
244
|
+
</Flexbox>
|
245
|
+
</Form.Item>
|
246
|
+
|
247
|
+
<Form.Item
|
248
|
+
dependencies={['proxyRequireAuth', 'enableProxy']}
|
249
|
+
label={t('proxy.username')}
|
250
|
+
name="proxyUsername"
|
251
|
+
rules={[
|
252
|
+
({ getFieldValue }) => ({
|
253
|
+
message: t('proxy.validation.usernameRequired'),
|
254
|
+
required: getFieldValue('proxyRequireAuth') && getFieldValue('enableProxy'),
|
255
|
+
}),
|
256
|
+
]}
|
257
|
+
style={{
|
258
|
+
display:
|
259
|
+
form.getFieldValue('proxyRequireAuth') && form.getFieldValue('enableProxy')
|
260
|
+
? 'block'
|
261
|
+
: 'none',
|
262
|
+
}}
|
263
|
+
>
|
264
|
+
<Input placeholder={t('proxy.username_placeholder')} />
|
265
|
+
</Form.Item>
|
266
|
+
|
267
|
+
<Form.Item
|
268
|
+
dependencies={['proxyRequireAuth', 'enableProxy']}
|
269
|
+
label={t('proxy.password')}
|
270
|
+
name="proxyPassword"
|
271
|
+
rules={[
|
272
|
+
({ getFieldValue }) => ({
|
273
|
+
message: t('proxy.validation.passwordRequired'),
|
274
|
+
required: getFieldValue('proxyRequireAuth') && getFieldValue('enableProxy'),
|
275
|
+
}),
|
276
|
+
]}
|
277
|
+
style={{
|
278
|
+
display:
|
279
|
+
form.getFieldValue('proxyRequireAuth') && form.getFieldValue('enableProxy')
|
280
|
+
? 'block'
|
281
|
+
: 'none',
|
282
|
+
}}
|
283
|
+
>
|
284
|
+
<Input.Password placeholder={t('proxy.password_placeholder')} />
|
285
|
+
</Form.Item>
|
286
|
+
</Flexbox>
|
287
|
+
</Flexbox>
|
288
|
+
</Block>
|
289
|
+
|
290
|
+
{/* 连接测试 */}
|
291
|
+
|
292
|
+
<Block
|
293
|
+
paddingBlock={16}
|
294
|
+
paddingInline={24}
|
295
|
+
style={{ borderRadius: 12 }}
|
296
|
+
variant={'outlined'}
|
297
|
+
>
|
298
|
+
<Flexbox gap={24}>
|
299
|
+
<Flexbox>
|
300
|
+
<Text as={'h4'}>{t('proxy.connectionTest')}</Text>
|
301
|
+
<Text type={'secondary'}>{t('proxy.testDescription')}</Text>
|
302
|
+
</Flexbox>
|
303
|
+
<Form.Item label={t('proxy.testUrl')}>
|
304
|
+
<Flexbox gap={8}>
|
305
|
+
<Space.Compact style={{ width: '100%' }}>
|
306
|
+
<Input
|
307
|
+
onChange={(e) => setTestUrl(e.target.value)}
|
308
|
+
placeholder={t('proxy.testUrlPlaceholder')}
|
309
|
+
style={{ flex: 1 }}
|
310
|
+
value={testUrl}
|
311
|
+
/>
|
312
|
+
<Button loading={isTesting} onClick={handleTest} type="default">
|
313
|
+
{t('proxy.testButton')}
|
314
|
+
</Button>
|
315
|
+
</Space.Compact>
|
316
|
+
{/* 测试结果显示 */}
|
317
|
+
{!testResult ? null : testResult.success ? (
|
318
|
+
<Alert
|
319
|
+
closable
|
320
|
+
message={
|
321
|
+
<Flexbox align="center" gap={8} horizontal>
|
322
|
+
{t('proxy.testSuccessWithTime', { time: testResult.responseTime })}
|
323
|
+
</Flexbox>
|
324
|
+
}
|
325
|
+
type={'success'}
|
326
|
+
/>
|
327
|
+
) : (
|
328
|
+
<Alert
|
329
|
+
closable
|
330
|
+
message={
|
331
|
+
<Flexbox align="center" gap={8} horizontal>
|
332
|
+
{t('proxy.testFailed')}: {testResult.message}
|
333
|
+
</Flexbox>
|
334
|
+
}
|
335
|
+
type={'error'}
|
336
|
+
variant={'outlined'}
|
337
|
+
/>
|
338
|
+
)}
|
339
|
+
</Flexbox>
|
340
|
+
</Form.Item>
|
341
|
+
</Flexbox>
|
342
|
+
</Block>
|
343
|
+
{/* 操作按钮 */}
|
344
|
+
<Space>
|
345
|
+
<Button
|
346
|
+
disabled={!hasUnsavedChanges}
|
347
|
+
loading={isSaving}
|
348
|
+
onClick={handleSave}
|
349
|
+
type="primary"
|
350
|
+
>
|
351
|
+
{t('proxy.saveButton')}
|
352
|
+
</Button>
|
353
|
+
|
354
|
+
<Button disabled={!hasUnsavedChanges || isSaving} onClick={handleReset}>
|
355
|
+
{t('proxy.resetButton')}
|
356
|
+
</Button>
|
357
|
+
|
358
|
+
{hasUnsavedChanges && (
|
359
|
+
<Text style={{ marginLeft: 8 }} type="warning">
|
360
|
+
{t('proxy.unsavedChanges')}
|
361
|
+
</Text>
|
362
|
+
)}
|
363
|
+
</Space>
|
364
|
+
</Flexbox>
|
365
|
+
</Form>
|
366
|
+
);
|
367
|
+
};
|
368
|
+
|
369
|
+
export default ProxyForm;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { useTranslation } from 'react-i18next';
|
4
|
+
|
5
|
+
import PageTitle from '@/components/PageTitle';
|
6
|
+
|
7
|
+
import ProxyForm from './features/ProxyForm';
|
8
|
+
|
9
|
+
const ProxySettings = () => {
|
10
|
+
const { t } = useTranslation('setting');
|
11
|
+
|
12
|
+
return (
|
13
|
+
<div>
|
14
|
+
<PageTitle title={t('tab.proxy')} />
|
15
|
+
<ProxyForm />
|
16
|
+
</div>
|
17
|
+
);
|
18
|
+
};
|
19
|
+
|
20
|
+
ProxySettings.displayName = 'ProxySettings';
|
21
|
+
|
22
|
+
export default ProxySettings;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { notFound } from 'next/navigation';
|
2
|
+
|
3
|
+
import { isDesktop } from '@/const/version';
|
4
|
+
import { metadataModule } from '@/server/metadata';
|
5
|
+
import { translation } from '@/server/translation';
|
6
|
+
import { DynamicLayoutProps } from '@/types/next';
|
7
|
+
import { RouteVariants } from '@/utils/server/routeVariants';
|
8
|
+
|
9
|
+
import Client from './index';
|
10
|
+
|
11
|
+
export const generateMetadata = async (props: DynamicLayoutProps) => {
|
12
|
+
const locale = await RouteVariants.getLocale(props);
|
13
|
+
const { t } = await translation('setting', locale);
|
14
|
+
|
15
|
+
return metadataModule.generate({
|
16
|
+
description: t('header.desc'),
|
17
|
+
title: t('tab.proxy'),
|
18
|
+
url: '/settings/proxy',
|
19
|
+
});
|
20
|
+
};
|
21
|
+
|
22
|
+
const Page = () => {
|
23
|
+
if (!isDesktop) return notFound();
|
24
|
+
|
25
|
+
return <Client />;
|
26
|
+
};
|
27
|
+
|
28
|
+
export default Page;
|
@@ -11,7 +11,8 @@ const googleChatModels: AIChatModelCard[] = [
|
|
11
11
|
contextWindowTokens: 1_048_576 + 65_536,
|
12
12
|
description:
|
13
13
|
'Gemini 2.5 Pro 是 Google 最先进的思维模型,能够对代码、数学和STEM领域的复杂问题进行推理,以及使用长上下文分析大型数据集、代码库和文档。',
|
14
|
-
displayName: 'Gemini 2.5 Pro
|
14
|
+
displayName: 'Gemini 2.5 Pro',
|
15
|
+
enabled: true,
|
15
16
|
id: 'gemini-2.5-pro',
|
16
17
|
maxOutput: 65_536,
|
17
18
|
pricing: {
|
@@ -77,30 +78,6 @@ const googleChatModels: AIChatModelCard[] = [
|
|
77
78
|
},
|
78
79
|
type: 'chat',
|
79
80
|
},
|
80
|
-
{
|
81
|
-
abilities: {
|
82
|
-
functionCall: true,
|
83
|
-
reasoning: true,
|
84
|
-
search: true,
|
85
|
-
vision: true,
|
86
|
-
},
|
87
|
-
contextWindowTokens: 1_048_576 + 65_536,
|
88
|
-
description:
|
89
|
-
'Gemini 2.5 Pro Experimental 是 Google 最先进的思维模型,能够对代码、数学和STEM领域的复杂问题进行推理,以及使用长上下文分析大型数据集、代码库和文档。',
|
90
|
-
displayName: 'Gemini 2.5 Pro Experimental 03-25',
|
91
|
-
id: 'gemini-2.5-pro-exp-03-25',
|
92
|
-
maxOutput: 65_536,
|
93
|
-
pricing: {
|
94
|
-
input: 0,
|
95
|
-
output: 0,
|
96
|
-
},
|
97
|
-
releasedAt: '2025-03-25',
|
98
|
-
settings: {
|
99
|
-
searchImpl: 'params',
|
100
|
-
searchProvider: 'google',
|
101
|
-
},
|
102
|
-
type: 'chat',
|
103
|
-
},
|
104
81
|
{
|
105
82
|
abilities: {
|
106
83
|
functionCall: true,
|
@@ -206,7 +183,7 @@ const googleChatModels: AIChatModelCard[] = [
|
|
206
183
|
search: true,
|
207
184
|
vision: true,
|
208
185
|
},
|
209
|
-
contextWindowTokens:
|
186
|
+
contextWindowTokens: 1_048_576 + 65_536,
|
210
187
|
description:
|
211
188
|
'Gemini 2.5 Flash-Lite Preview 是 Google 最小、性价比最高的模型,专为大规模使用而设计。',
|
212
189
|
displayName: 'Gemini 2.5 Flash-Lite Preview 06-17',
|
@@ -493,6 +470,18 @@ const googleChatModels: AIChatModelCard[] = [
|
|
493
470
|
},
|
494
471
|
type: 'chat',
|
495
472
|
},
|
473
|
+
{
|
474
|
+
contextWindowTokens: 2048 + 8192,
|
475
|
+
displayName: 'Gemma 3n E2B',
|
476
|
+
id: 'gemma-3n-e2b-it',
|
477
|
+
maxOutput: 2048,
|
478
|
+
pricing: {
|
479
|
+
cachedInput: 0,
|
480
|
+
input: 0,
|
481
|
+
output: 0,
|
482
|
+
},
|
483
|
+
type: 'chat',
|
484
|
+
},
|
496
485
|
{
|
497
486
|
contextWindowTokens: 2048 + 8192,
|
498
487
|
displayName: 'Gemma 3n E4B',
|
@@ -47,22 +47,6 @@ const groqChatModels: AIChatModelCard[] = [
|
|
47
47
|
},
|
48
48
|
type: 'chat',
|
49
49
|
},
|
50
|
-
{
|
51
|
-
abilities: {
|
52
|
-
functionCall: true,
|
53
|
-
reasoning: true,
|
54
|
-
},
|
55
|
-
contextWindowTokens: 131_072,
|
56
|
-
displayName: 'Qwen QwQ 32B',
|
57
|
-
enabled: true,
|
58
|
-
id: 'qwen-qwq-32b',
|
59
|
-
maxOutput: 131_072,
|
60
|
-
pricing: {
|
61
|
-
input: 0.29,
|
62
|
-
output: 0.39,
|
63
|
-
},
|
64
|
-
type: 'chat',
|
65
|
-
},
|
66
50
|
{
|
67
51
|
abilities: {
|
68
52
|
reasoning: true,
|
@@ -2,6 +2,25 @@ import { AIChatModelCard } from '@/types/aiModel';
|
|
2
2
|
|
3
3
|
// https://cloud.tencent.com/document/product/1729/104753
|
4
4
|
const hunyuanChatModels: AIChatModelCard[] = [
|
5
|
+
{
|
6
|
+
abilities: {
|
7
|
+
reasoning: true,
|
8
|
+
search: true,
|
9
|
+
},
|
10
|
+
contextWindowTokens: 256_000,
|
11
|
+
description:
|
12
|
+
'混元第一个混合推理模型,hunyuan-standard-256K 的升级版本,总参数80B,激活13B,默认是慢思考模式,支持通过参数或者指令进行快慢思考模式切换,慢快思考切换方式为 query 前加/ no_think;整体能力相对上一代全面提升,特别数学、科学、长文理解和 Agent 能力提升显著。',
|
13
|
+
displayName: 'Hunyuan A13B',
|
14
|
+
enabled: true,
|
15
|
+
id: 'hunyuan-a13b',
|
16
|
+
maxOutput: 32_000,
|
17
|
+
releasedAt: '2025-06-25',
|
18
|
+
settings: {
|
19
|
+
extendParams: ['enableReasoning'],
|
20
|
+
searchImpl: 'params',
|
21
|
+
},
|
22
|
+
type: 'chat',
|
23
|
+
},
|
5
24
|
{
|
6
25
|
abilities: {
|
7
26
|
reasoning: true,
|
@@ -366,7 +385,6 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
366
385
|
contextWindowTokens: 8000,
|
367
386
|
description: '混元最新多模态模型,支持多语种作答,中英文能力均衡。',
|
368
387
|
displayName: 'Hunyuan Standard Vision',
|
369
|
-
enabled: true,
|
370
388
|
id: 'hunyuan-standard-vision',
|
371
389
|
maxOutput: 2000,
|
372
390
|
releasedAt: '2024-12-31',
|
@@ -403,6 +421,25 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
403
421
|
releasedAt: '2025-05-26',
|
404
422
|
type: 'chat',
|
405
423
|
},
|
424
|
+
{
|
425
|
+
abilities: {
|
426
|
+
reasoning: true,
|
427
|
+
vision: true,
|
428
|
+
},
|
429
|
+
contextWindowTokens: 40_000,
|
430
|
+
description:
|
431
|
+
'混元最新版t1-vision多模态理解深度思考模型,支持多模态原生长思维链,相比上一代默认版本模型全面提升。',
|
432
|
+
displayName: 'Hunyuan T1 Vision 20250619',
|
433
|
+
id: 'hunyuan-t1-vision-20250619',
|
434
|
+
maxOutput: 24_000,
|
435
|
+
pricing: {
|
436
|
+
currency: 'CNY',
|
437
|
+
input: 1,
|
438
|
+
output: 4,
|
439
|
+
},
|
440
|
+
releasedAt: '2025-06-19',
|
441
|
+
type: 'chat',
|
442
|
+
},
|
406
443
|
{
|
407
444
|
abilities: {
|
408
445
|
reasoning: true,
|
@@ -414,9 +451,50 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
414
451
|
displayName: 'Hunyuan T1 Vision',
|
415
452
|
id: 'hunyuan-t1-vision',
|
416
453
|
maxOutput: 24_000,
|
454
|
+
pricing: {
|
455
|
+
currency: 'CNY',
|
456
|
+
input: 1,
|
457
|
+
output: 4,
|
458
|
+
},
|
417
459
|
releasedAt: '2025-05-16',
|
418
460
|
type: 'chat',
|
419
461
|
},
|
462
|
+
{
|
463
|
+
abilities: {
|
464
|
+
vision: true,
|
465
|
+
},
|
466
|
+
contextWindowTokens: 32_000,
|
467
|
+
description:
|
468
|
+
'混元最新版turbos-vision视觉语言旗舰大模型,在图文理解相关的任务上,包括基于图片的实体识别、知识问答、文案创作、拍照解题等上面相比上一代默认版本模型全面提升。',
|
469
|
+
displayName: 'Hunyuan TurboS Vision 20250619',
|
470
|
+
id: 'hunyuan-turbos-vision-20250619',
|
471
|
+
maxOutput: 16_000,
|
472
|
+
pricing: {
|
473
|
+
currency: 'CNY',
|
474
|
+
input: 3,
|
475
|
+
output: 9,
|
476
|
+
},
|
477
|
+
releasedAt: '2025-06-19',
|
478
|
+
type: 'chat',
|
479
|
+
},
|
480
|
+
{
|
481
|
+
abilities: {
|
482
|
+
vision: true,
|
483
|
+
},
|
484
|
+
contextWindowTokens: 32_000,
|
485
|
+
description:
|
486
|
+
'此模型适用于图文理解场景,是基于混元最新 turbos 的新一代视觉语言旗舰大模型,聚焦图文理解相关任务,包括基于图片的实体识别、知识问答、文案创作、拍照解题等方面,相比前一代模型全面提升。',
|
487
|
+
displayName: 'Hunyuan TurboS Vision',
|
488
|
+
id: 'hunyuan-turbos-vision',
|
489
|
+
maxOutput: 24_000,
|
490
|
+
pricing: {
|
491
|
+
currency: 'CNY',
|
492
|
+
input: 3,
|
493
|
+
output: 9,
|
494
|
+
},
|
495
|
+
releasedAt: '2025-05-23',
|
496
|
+
type: 'chat',
|
497
|
+
},
|
420
498
|
{
|
421
499
|
abilities: {
|
422
500
|
vision: true,
|