@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/apps/desktop/package.json +8 -5
  3. package/apps/desktop/src/main/const/store.ts +12 -0
  4. package/apps/desktop/src/main/controllers/NetworkProxyCtr.ts +172 -0
  5. package/apps/desktop/src/main/controllers/__tests__/NetworkProxyCtr.test.ts +401 -0
  6. package/apps/desktop/src/main/core/Browser.ts +2 -0
  7. package/apps/desktop/src/main/modules/networkProxy/dispatcher.ts +116 -0
  8. package/apps/desktop/src/main/modules/networkProxy/index.ts +6 -0
  9. package/apps/desktop/src/main/modules/networkProxy/tester.ts +163 -0
  10. package/apps/desktop/src/main/modules/networkProxy/urlBuilder.ts +25 -0
  11. package/apps/desktop/src/main/modules/networkProxy/validator.ts +80 -0
  12. package/apps/desktop/src/main/types/store.ts +2 -1
  13. package/apps/desktop/src/main/utils/logger.ts +2 -1
  14. package/changelog/v1.json +18 -0
  15. package/locales/ar/electron.json +39 -0
  16. package/locales/ar/setting.json +1 -0
  17. package/locales/bg-BG/electron.json +39 -0
  18. package/locales/bg-BG/setting.json +1 -0
  19. package/locales/de-DE/electron.json +39 -0
  20. package/locales/de-DE/setting.json +1 -0
  21. package/locales/en-US/electron.json +39 -0
  22. package/locales/en-US/setting.json +1 -0
  23. package/locales/es-ES/electron.json +39 -0
  24. package/locales/es-ES/setting.json +1 -0
  25. package/locales/fa-IR/electron.json +39 -0
  26. package/locales/fa-IR/setting.json +1 -0
  27. package/locales/fr-FR/electron.json +39 -0
  28. package/locales/fr-FR/setting.json +1 -0
  29. package/locales/it-IT/electron.json +39 -0
  30. package/locales/it-IT/setting.json +1 -0
  31. package/locales/ja-JP/electron.json +39 -0
  32. package/locales/ja-JP/setting.json +1 -0
  33. package/locales/ko-KR/electron.json +39 -0
  34. package/locales/ko-KR/setting.json +1 -0
  35. package/locales/nl-NL/electron.json +39 -0
  36. package/locales/nl-NL/setting.json +1 -0
  37. package/locales/pl-PL/electron.json +39 -0
  38. package/locales/pl-PL/setting.json +1 -0
  39. package/locales/pt-BR/electron.json +39 -0
  40. package/locales/pt-BR/setting.json +1 -0
  41. package/locales/ru-RU/electron.json +39 -0
  42. package/locales/ru-RU/setting.json +1 -0
  43. package/locales/tr-TR/electron.json +39 -0
  44. package/locales/tr-TR/setting.json +1 -0
  45. package/locales/vi-VN/electron.json +39 -0
  46. package/locales/vi-VN/setting.json +1 -0
  47. package/locales/zh-CN/electron.json +39 -0
  48. package/locales/zh-CN/setting.json +1 -0
  49. package/locales/zh-TW/electron.json +39 -0
  50. package/locales/zh-TW/setting.json +1 -0
  51. package/package.json +3 -3
  52. package/packages/electron-client-ipc/src/events/index.ts +3 -1
  53. package/packages/electron-client-ipc/src/events/settings.ts +12 -0
  54. package/packages/electron-client-ipc/src/types/index.ts +1 -0
  55. package/packages/electron-client-ipc/src/types/proxy.ts +12 -0
  56. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +11 -1
  57. package/src/app/[variants]/(main)/settings/proxy/features/ProxyForm.tsx +369 -0
  58. package/src/app/[variants]/(main)/settings/proxy/index.tsx +22 -0
  59. package/src/app/[variants]/(main)/settings/proxy/page.tsx +28 -0
  60. package/src/config/aiModels/google.ts +15 -26
  61. package/src/config/aiModels/groq.ts +0 -16
  62. package/src/config/aiModels/hunyuan.ts +79 -1
  63. package/src/config/aiModels/novita.ts +50 -56
  64. package/src/config/aiModels/qwen.ts +10 -32
  65. package/src/config/aiModels/siliconcloud.ts +111 -86
  66. package/src/config/aiModels/zhipu.ts +74 -12
  67. package/src/config/modelProviders/zhipu.ts +1 -2
  68. package/src/libs/model-runtime/hunyuan/index.ts +9 -1
  69. package/src/locales/default/electron.ts +39 -0
  70. package/src/locales/default/setting.ts +1 -0
  71. package/src/services/electron/settings.ts +33 -0
  72. package/src/store/electron/actions/settings.ts +55 -0
  73. package/src/store/electron/initialState.ts +12 -1
  74. package/src/store/electron/selectors/__tests__/desktopState.test.ts +3 -1
  75. package/src/store/electron/store.ts +4 -1
  76. package/src/store/global/initialState.ts +1 -0
  77. 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 (Paid)',
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: 65_536 + 65_536,
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,