@lobehub/chat 1.71.3 → 1.71.5
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/.github/ISSUE_TEMPLATE/1_bug_report.yml +2 -2
- package/.github/ISSUE_TEMPLATE/1_bug_report_cn.yml +2 -2
- package/.github/ISSUE_TEMPLATE/2_feature_request.yml +0 -1
- package/.github/ISSUE_TEMPLATE/2_feature_request_cn.yml +0 -1
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/package.json +3 -3
- package/src/config/aiModels/hunyuan.ts +74 -52
- package/src/config/aiModels/wenxin.ts +221 -33
- package/src/features/ShareModal/ShareImage/index.tsx +27 -11
- package/src/hooks/useImgToClipboard.ts +29 -0
- package/src/hooks/useScreenshot.ts +53 -40
- package/src/utils/server/__tests__/auth.test.ts +95 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
name: '🐛 Bug Report'
|
2
2
|
description: 'Report an bug'
|
3
|
-
|
4
|
-
labels: ['🐛 Bug']
|
3
|
+
labels: ['unconfirm']
|
5
4
|
type: Bug
|
6
5
|
body:
|
7
6
|
- type: dropdown
|
@@ -10,6 +9,7 @@ body:
|
|
10
9
|
multiple: true
|
11
10
|
options:
|
12
11
|
- 'Official Preview'
|
12
|
+
- 'Official Cloud'
|
13
13
|
- 'Vercel'
|
14
14
|
- 'Zeabur'
|
15
15
|
- 'Sealos'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
name: '🐛 反馈缺陷'
|
2
2
|
description: '反馈一个问题缺陷'
|
3
|
-
|
4
|
-
labels: ['🐛 Bug']
|
3
|
+
labels: ['unconfirm']
|
5
4
|
type: Bug
|
6
5
|
body:
|
7
6
|
- type: markdown
|
@@ -17,6 +16,7 @@ body:
|
|
17
16
|
multiple: true
|
18
17
|
options:
|
19
18
|
- 'Official Preview'
|
19
|
+
- 'Official Cloud'
|
20
20
|
- 'Vercel'
|
21
21
|
- 'Zeabur'
|
22
22
|
- 'Sealos'
|
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.71.5](https://github.com/lobehub/lobe-chat/compare/v1.71.4...v1.71.5)
|
6
|
+
|
7
|
+
<sup>Released on **2025-03-17**</sup>
|
8
|
+
|
9
|
+
#### 💄 Styles
|
10
|
+
|
11
|
+
- **misc**: Support screenshot to clipboard when sharing.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Styles
|
19
|
+
|
20
|
+
- **misc**: Support screenshot to clipboard when sharing, closes [#6275](https://github.com/lobehub/lobe-chat/issues/6275) ([45663c3](https://github.com/lobehub/lobe-chat/commit/45663c3))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.71.4](https://github.com/lobehub/lobe-chat/compare/v1.71.3...v1.71.4)
|
31
|
+
|
32
|
+
<sup>Released on **2025-03-17**</sup>
|
33
|
+
|
34
|
+
#### 💄 Styles
|
35
|
+
|
36
|
+
- **misc**: Update Wenxin & Hunyuan model list.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### Styles
|
44
|
+
|
45
|
+
- **misc**: Update Wenxin & Hunyuan model list, closes [#6995](https://github.com/lobehub/lobe-chat/issues/6995) ([d017f35](https://github.com/lobehub/lobe-chat/commit/d017f35))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.71.3](https://github.com/lobehub/lobe-chat/compare/v1.71.2...v1.71.3)
|
6
56
|
|
7
57
|
<sup>Released on **2025-03-15**</sup>
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"improvements": [
|
5
|
+
"Support screenshot to clipboard when sharing."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-03-17",
|
9
|
+
"version": "1.71.5"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"improvements": [
|
14
|
+
"Update Wenxin & Hunyuan model list."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2025-03-17",
|
18
|
+
"version": "1.71.4"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {
|
4
22
|
"fixes": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.71.
|
3
|
+
"version": "1.71.5",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -182,7 +182,7 @@
|
|
182
182
|
"langfuse": "3.29.1",
|
183
183
|
"langfuse-core": "3.29.1",
|
184
184
|
"lodash-es": "^4.17.21",
|
185
|
-
"lucide-react": "^0.
|
185
|
+
"lucide-react": "^0.482.0",
|
186
186
|
"mammoth": "^1.9.0",
|
187
187
|
"mdast-util-to-markdown": "^2.1.2",
|
188
188
|
"modern-screenshot": "^4.5.5",
|
@@ -330,7 +330,7 @@
|
|
330
330
|
"vitest": "~1.2.2",
|
331
331
|
"vitest-canvas-mock": "^0.3.3"
|
332
332
|
},
|
333
|
-
"packageManager": "pnpm@9.15.
|
333
|
+
"packageManager": "pnpm@9.15.9",
|
334
334
|
"publishConfig": {
|
335
335
|
"access": "public",
|
336
336
|
"registry": "https://registry.npmjs.org"
|
@@ -49,7 +49,6 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
49
49
|
description:
|
50
50
|
'采用更优的路由策略,同时缓解了负载均衡和专家趋同的问题。长文方面,大海捞针指标达到99.9%。MOE-256K 在长度和效果上进一步突破,极大的扩展了可输入长度。',
|
51
51
|
displayName: 'Hunyuan Standard 256K',
|
52
|
-
enabled: true,
|
53
52
|
id: 'hunyuan-standard-256K',
|
54
53
|
maxOutput: 6000,
|
55
54
|
pricing: {
|
@@ -65,22 +64,43 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
65
64
|
},
|
66
65
|
{
|
67
66
|
abilities: {
|
68
|
-
functionCall: true,
|
69
67
|
search: true,
|
70
68
|
},
|
71
69
|
contextWindowTokens: 32_000,
|
72
70
|
description:
|
73
|
-
'
|
74
|
-
displayName: 'Hunyuan
|
71
|
+
'Hunyuan-large 模型总参数量约 389B,激活参数量约 52B,是当前业界参数规模最大、效果最好的 Transformer 架构的开源 MoE 模型。',
|
72
|
+
displayName: 'Hunyuan Large',
|
75
73
|
enabled: true,
|
76
|
-
id: 'hunyuan-
|
74
|
+
id: 'hunyuan-large',
|
77
75
|
maxOutput: 4000,
|
78
76
|
pricing: {
|
79
77
|
currency: 'CNY',
|
80
|
-
input:
|
81
|
-
output:
|
78
|
+
input: 4,
|
79
|
+
output: 12,
|
82
80
|
},
|
83
|
-
releasedAt: '2025-
|
81
|
+
releasedAt: '2025-02-10',
|
82
|
+
settings: {
|
83
|
+
searchImpl: 'params',
|
84
|
+
},
|
85
|
+
type: 'chat',
|
86
|
+
},
|
87
|
+
{
|
88
|
+
abilities: {
|
89
|
+
search: true,
|
90
|
+
},
|
91
|
+
contextWindowTokens: 134_000,
|
92
|
+
description:
|
93
|
+
'擅长处理长文任务如文档摘要和文档问答等,同时也具备处理通用文本生成任务的能力。在长文本的分析和生成上表现优异,能有效应对复杂和详尽的长文内容处理需求。',
|
94
|
+
displayName: 'Hunyuan Large Longcontext',
|
95
|
+
enabled: true,
|
96
|
+
id: 'hunyuan-large-longcontext',
|
97
|
+
maxOutput: 6000,
|
98
|
+
pricing: {
|
99
|
+
currency: 'CNY',
|
100
|
+
input: 6,
|
101
|
+
output: 18,
|
102
|
+
},
|
103
|
+
releasedAt: '2024-12-18',
|
84
104
|
settings: {
|
85
105
|
searchImpl: 'params',
|
86
106
|
},
|
@@ -93,14 +113,15 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
93
113
|
},
|
94
114
|
contextWindowTokens: 32_000,
|
95
115
|
description:
|
96
|
-
'
|
116
|
+
'通用体验优化,包括NLP理解、文本创作、闲聊、知识问答、翻译、领域等;提升拟人性,优化模型情商;提升意图模糊时模型主动澄清能力;提升字词解析类问题的处理能力;提升创作的质量和可互动性;提升多轮体验。',
|
97
117
|
displayName: 'Hunyuan Turbo',
|
98
|
-
|
118
|
+
enabled: true,
|
119
|
+
id: 'hunyuan-turbo-latest',
|
99
120
|
maxOutput: 4000,
|
100
121
|
pricing: {
|
101
122
|
currency: 'CNY',
|
102
|
-
input:
|
103
|
-
output:
|
123
|
+
input: 2.4,
|
124
|
+
output: 9.6,
|
104
125
|
},
|
105
126
|
releasedAt: '2025-01-10',
|
106
127
|
settings: {
|
@@ -121,8 +142,8 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
121
142
|
maxOutput: 4000,
|
122
143
|
pricing: {
|
123
144
|
currency: 'CNY',
|
124
|
-
input:
|
125
|
-
output:
|
145
|
+
input: 2.4,
|
146
|
+
output: 9.6,
|
126
147
|
},
|
127
148
|
releasedAt: '2025-01-10',
|
128
149
|
settings: {
|
@@ -137,16 +158,17 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
137
158
|
},
|
138
159
|
contextWindowTokens: 32_000,
|
139
160
|
description:
|
140
|
-
'hunyuan-
|
141
|
-
displayName: 'Hunyuan
|
142
|
-
|
143
|
-
|
161
|
+
'hunyuan-TurboS 混元旗舰大模型最新版本,具备更强的思考能力,更优的体验效果。',
|
162
|
+
displayName: 'Hunyuan TurboS',
|
163
|
+
enabled: true,
|
164
|
+
id: 'hunyuan-turbos-latest',
|
165
|
+
maxOutput: 8000,
|
144
166
|
pricing: {
|
145
167
|
currency: 'CNY',
|
146
|
-
input:
|
147
|
-
output:
|
168
|
+
input: 0.8,
|
169
|
+
output: 2,
|
148
170
|
},
|
149
|
-
releasedAt: '
|
171
|
+
releasedAt: '2025-03-13',
|
150
172
|
settings: {
|
151
173
|
searchImpl: 'params',
|
152
174
|
},
|
@@ -154,21 +176,21 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
154
176
|
},
|
155
177
|
{
|
156
178
|
abilities: {
|
179
|
+
functionCall: true,
|
157
180
|
search: true,
|
158
181
|
},
|
159
182
|
contextWindowTokens: 32_000,
|
160
183
|
description:
|
161
|
-
'
|
162
|
-
displayName: 'Hunyuan
|
163
|
-
|
164
|
-
|
165
|
-
maxOutput: 4000,
|
184
|
+
'统一数学解题步骤的风格,加强数学多轮问答。文本创作优化回答风格,去除AI味,增加文采。',
|
185
|
+
displayName: 'Hunyuan TurboS 20250313',
|
186
|
+
id: 'hunyuan-turbos-20250313',
|
187
|
+
maxOutput: 8000,
|
166
188
|
pricing: {
|
167
189
|
currency: 'CNY',
|
168
|
-
input:
|
169
|
-
output:
|
190
|
+
input: 0.8,
|
191
|
+
output: 2,
|
170
192
|
},
|
171
|
-
releasedAt: '2025-
|
193
|
+
releasedAt: '2025-03-13',
|
172
194
|
settings: {
|
173
195
|
searchImpl: 'params',
|
174
196
|
},
|
@@ -176,21 +198,21 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
176
198
|
},
|
177
199
|
{
|
178
200
|
abilities: {
|
201
|
+
functionCall: true,
|
179
202
|
search: true,
|
180
203
|
},
|
181
|
-
contextWindowTokens:
|
204
|
+
contextWindowTokens: 32_000,
|
182
205
|
description:
|
183
|
-
'
|
184
|
-
displayName: 'Hunyuan
|
185
|
-
|
186
|
-
|
187
|
-
maxOutput: 6000,
|
206
|
+
'hunyuan-TurboS pv2.1.2 固定版本预训练底座训练token 数升级;数学/逻辑/代码等思考能力提升;中英文通用体验效果提升,包括文本创作、文本理解、知识问答、闲聊等。',
|
207
|
+
displayName: 'Hunyuan TurboS 20250226',
|
208
|
+
id: 'hunyuan-turbos-20250226',
|
209
|
+
maxOutput: 8000,
|
188
210
|
pricing: {
|
189
211
|
currency: 'CNY',
|
190
|
-
input:
|
191
|
-
output:
|
212
|
+
input: 0.8,
|
213
|
+
output: 2,
|
192
214
|
},
|
193
|
-
releasedAt: '
|
215
|
+
releasedAt: '2025-02-25',
|
194
216
|
settings: {
|
195
217
|
searchImpl: 'params',
|
196
218
|
},
|
@@ -267,8 +289,8 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
267
289
|
maxOutput: 4000,
|
268
290
|
pricing: {
|
269
291
|
currency: 'CNY',
|
270
|
-
input:
|
271
|
-
output:
|
292
|
+
input: 3.5,
|
293
|
+
output: 7,
|
272
294
|
},
|
273
295
|
releasedAt: '2024-11-12',
|
274
296
|
type: 'chat',
|
@@ -309,31 +331,31 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
309
331
|
{
|
310
332
|
contextWindowTokens: 8000,
|
311
333
|
description:
|
312
|
-
'
|
313
|
-
displayName: 'Hunyuan Translation',
|
314
|
-
id: 'hunyuan-translation',
|
334
|
+
'混元翻译模型支持自然语言对话式翻译;支持中文和英语、日语、法语、葡萄牙语、西班牙语、土耳其语、俄语、阿拉伯语、韩语、意大利语、德语、越南语、马来语、印尼语15种语言互译。',
|
335
|
+
displayName: 'Hunyuan Translation Lite',
|
336
|
+
id: 'hunyuan-translation-lite',
|
315
337
|
maxOutput: 4000,
|
316
338
|
pricing: {
|
317
339
|
currency: 'CNY',
|
318
|
-
input:
|
319
|
-
output:
|
340
|
+
input: 1,
|
341
|
+
output: 3,
|
320
342
|
},
|
321
|
-
releasedAt: '2024-
|
343
|
+
releasedAt: '2024-11-25',
|
322
344
|
type: 'chat',
|
323
345
|
},
|
324
346
|
{
|
325
347
|
contextWindowTokens: 8000,
|
326
348
|
description:
|
327
|
-
'
|
328
|
-
displayName: 'Hunyuan Translation
|
329
|
-
id: 'hunyuan-translation
|
349
|
+
'支持中文和英语、日语、法语、葡萄牙语、西班牙语、土耳其语、俄语、阿拉伯语、韩语、意大利语、德语、越南语、马来语、印尼语15种语言互译,基于多场景翻译评测集自动化评估COMET评分,在十余种常用语种中外互译能力上整体优于市场同规模模型。',
|
350
|
+
displayName: 'Hunyuan Translation',
|
351
|
+
id: 'hunyuan-translation',
|
330
352
|
maxOutput: 4000,
|
331
353
|
pricing: {
|
332
354
|
currency: 'CNY',
|
333
|
-
input:
|
334
|
-
output:
|
355
|
+
input: 15,
|
356
|
+
output: 45,
|
335
357
|
},
|
336
|
-
releasedAt: '2024-
|
358
|
+
releasedAt: '2024-10-25',
|
337
359
|
type: 'chat',
|
338
360
|
},
|
339
361
|
];
|
@@ -1,63 +1,47 @@
|
|
1
1
|
import { AIChatModelCard } from '@/types/aiModel';
|
2
2
|
|
3
3
|
const wenxinChatModels: AIChatModelCard[] = [
|
4
|
+
/*
|
4
5
|
{
|
5
6
|
abilities: {
|
6
|
-
|
7
|
+
resoning: true,
|
7
8
|
search: true,
|
8
9
|
},
|
9
|
-
contextWindowTokens:
|
10
|
+
contextWindowTokens: 32_768,
|
10
11
|
description:
|
11
|
-
'
|
12
|
-
displayName: 'ERNIE
|
12
|
+
'文心大模型X1具备更强的理解、规划、反思、进化能力。作为能力更全面的深度思考模型,文心X1兼备准确、创意和文采,在中文知识问答、文学创作、文稿写作、日常对话、逻辑推理、复杂计算及工具调用等方面表现尤为出色。',
|
13
|
+
displayName: 'ERNIE X1 32K Preview',
|
13
14
|
enabled: true,
|
14
|
-
id: 'ernie-
|
15
|
+
id: 'ernie-x1-32k-preview',
|
15
16
|
pricing: {
|
16
17
|
currency: 'CNY',
|
17
|
-
input:
|
18
|
-
output:
|
18
|
+
input: 2,
|
19
|
+
output: 8,
|
19
20
|
},
|
21
|
+
releasedAt: '2025-03-16',
|
20
22
|
settings: {
|
21
23
|
searchImpl: 'params',
|
22
24
|
},
|
23
25
|
type: 'chat',
|
24
26
|
},
|
27
|
+
*/
|
25
28
|
{
|
26
29
|
abilities: {
|
27
|
-
functionCall: true,
|
28
30
|
search: true,
|
31
|
+
vision: true,
|
29
32
|
},
|
30
33
|
contextWindowTokens: 8192,
|
31
34
|
description:
|
32
|
-
'
|
33
|
-
displayName: 'ERNIE
|
34
|
-
id: 'ernie-3.5-8k-preview',
|
35
|
-
pricing: {
|
36
|
-
currency: 'CNY',
|
37
|
-
input: 0.8,
|
38
|
-
output: 2,
|
39
|
-
},
|
40
|
-
settings: {
|
41
|
-
searchImpl: 'params',
|
42
|
-
},
|
43
|
-
type: 'chat',
|
44
|
-
},
|
45
|
-
{
|
46
|
-
abilities: {
|
47
|
-
functionCall: true,
|
48
|
-
search: true,
|
49
|
-
},
|
50
|
-
contextWindowTokens: 128_000,
|
51
|
-
description:
|
52
|
-
'百度自研的旗舰级大规模⼤语⾔模型,覆盖海量中英文语料,具有强大的通用能力,可满足绝大部分对话问答、创作生成、插件应用场景要求;支持自动对接百度搜索插件,保障问答信息时效。',
|
53
|
-
displayName: 'ERNIE 3.5 128K',
|
35
|
+
'文心大模型4.5是百度自主研发的新一代原生多模态基础大模型,通过多个模态联合建模实现协同优化,多模态理解能力优秀;具备更精进的语言能力,理解、生成、逻辑、记忆能力全面提升,去幻觉、逻辑推理、代码能力显著提升。',
|
36
|
+
displayName: 'ERNIE 4.5 8K Preview',
|
54
37
|
enabled: true,
|
55
|
-
id: 'ernie-
|
38
|
+
id: 'ernie-4.5-8k-preview',
|
56
39
|
pricing: {
|
57
40
|
currency: 'CNY',
|
58
|
-
input:
|
59
|
-
output:
|
41
|
+
input: 4,
|
42
|
+
output: 16,
|
60
43
|
},
|
44
|
+
releasedAt: '2025-03-16',
|
61
45
|
settings: {
|
62
46
|
searchImpl: 'params',
|
63
47
|
},
|
@@ -166,6 +150,66 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
166
150
|
},
|
167
151
|
type: 'chat',
|
168
152
|
},
|
153
|
+
{
|
154
|
+
abilities: {
|
155
|
+
functionCall: true,
|
156
|
+
search: true,
|
157
|
+
},
|
158
|
+
contextWindowTokens: 8192,
|
159
|
+
description:
|
160
|
+
'百度自研的旗舰级大规模⼤语⾔模型,覆盖海量中英文语料,具有强大的通用能力,可满足绝大部分对话问答、创作生成、插件应用场景要求;支持自动对接百度搜索插件,保障问答信息时效。',
|
161
|
+
displayName: 'ERNIE 3.5 8K',
|
162
|
+
id: 'ernie-3.5-8k',
|
163
|
+
pricing: {
|
164
|
+
currency: 'CNY',
|
165
|
+
input: 0.8,
|
166
|
+
output: 2,
|
167
|
+
},
|
168
|
+
settings: {
|
169
|
+
searchImpl: 'params',
|
170
|
+
},
|
171
|
+
type: 'chat',
|
172
|
+
},
|
173
|
+
{
|
174
|
+
abilities: {
|
175
|
+
functionCall: true,
|
176
|
+
search: true,
|
177
|
+
},
|
178
|
+
contextWindowTokens: 8192,
|
179
|
+
description:
|
180
|
+
'百度自研的旗舰级大规模⼤语⾔模型,覆盖海量中英文语料,具有强大的通用能力,可满足绝大部分对话问答、创作生成、插件应用场景要求;支持自动对接百度搜索插件,保障问答信息时效。',
|
181
|
+
displayName: 'ERNIE 3.5 8K Preview',
|
182
|
+
id: 'ernie-3.5-8k-preview',
|
183
|
+
pricing: {
|
184
|
+
currency: 'CNY',
|
185
|
+
input: 0.8,
|
186
|
+
output: 2,
|
187
|
+
},
|
188
|
+
settings: {
|
189
|
+
searchImpl: 'params',
|
190
|
+
},
|
191
|
+
type: 'chat',
|
192
|
+
},
|
193
|
+
{
|
194
|
+
abilities: {
|
195
|
+
functionCall: true,
|
196
|
+
search: true,
|
197
|
+
},
|
198
|
+
contextWindowTokens: 128_000,
|
199
|
+
description:
|
200
|
+
'百度自研的旗舰级大规模⼤语⾔模型,覆盖海量中英文语料,具有强大的通用能力,可满足绝大部分对话问答、创作生成、插件应用场景要求;支持自动对接百度搜索插件,保障问答信息时效。',
|
201
|
+
displayName: 'ERNIE 3.5 128K',
|
202
|
+
id: 'ernie-3.5-128k',
|
203
|
+
pricing: {
|
204
|
+
currency: 'CNY',
|
205
|
+
input: 0.8,
|
206
|
+
output: 2,
|
207
|
+
},
|
208
|
+
settings: {
|
209
|
+
searchImpl: 'params',
|
210
|
+
},
|
211
|
+
type: 'chat',
|
212
|
+
},
|
169
213
|
{
|
170
214
|
contextWindowTokens: 8192,
|
171
215
|
description:
|
@@ -302,6 +346,150 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
302
346
|
},
|
303
347
|
type: 'chat',
|
304
348
|
},
|
349
|
+
{
|
350
|
+
abilities: {
|
351
|
+
reasoning: true,
|
352
|
+
},
|
353
|
+
contextWindowTokens: 32_768,
|
354
|
+
description:
|
355
|
+
'DeepSeek-R1-Distill-Qwen-1.5B是DeepSeek-R1基于Qwen-2.5系列的蒸馏模型。',
|
356
|
+
displayName: 'DeepSeek R1 Distill Qwen 1.5B',
|
357
|
+
id: 'deepseek-r1-distill-qwen-1.5b',
|
358
|
+
pricing: {
|
359
|
+
currency: 'CNY',
|
360
|
+
input: 2,
|
361
|
+
output: 8,
|
362
|
+
},
|
363
|
+
type: 'chat',
|
364
|
+
},
|
365
|
+
{
|
366
|
+
abilities: {
|
367
|
+
reasoning: true,
|
368
|
+
},
|
369
|
+
contextWindowTokens: 32_768,
|
370
|
+
description:
|
371
|
+
'DeepSeek-R1-Distill-Qwen-7B是DeepSeek-R1基于Qwen-2.5系列的蒸馏模型。',
|
372
|
+
displayName: 'DeepSeek R1 Distill Qwen 7B',
|
373
|
+
id: 'deepseek-r1-distill-qwen-7b',
|
374
|
+
pricing: {
|
375
|
+
currency: 'CNY',
|
376
|
+
input: 0.6,
|
377
|
+
output: 2.4,
|
378
|
+
},
|
379
|
+
type: 'chat',
|
380
|
+
},
|
381
|
+
{
|
382
|
+
abilities: {
|
383
|
+
reasoning: true,
|
384
|
+
},
|
385
|
+
contextWindowTokens: 32_768,
|
386
|
+
description:
|
387
|
+
'DeepSeek-R1-Distill-Qwen-14B是DeepSeek-R1基于Qwen-2.5系列的蒸馏模型。',
|
388
|
+
displayName: 'DeepSeek R1 Distill Qwen 14B',
|
389
|
+
id: 'deepseek-r1-distill-qwen-14b',
|
390
|
+
pricing: {
|
391
|
+
currency: 'CNY',
|
392
|
+
input: 0.6,
|
393
|
+
output: 2.4,
|
394
|
+
},
|
395
|
+
type: 'chat',
|
396
|
+
},
|
397
|
+
{
|
398
|
+
abilities: {
|
399
|
+
reasoning: true,
|
400
|
+
},
|
401
|
+
contextWindowTokens: 32_768,
|
402
|
+
description:
|
403
|
+
'DeepSeek-R1-Distill-Qwen-32B是DeepSeek-R1基于Qwen-2.5系列的蒸馏模型。',
|
404
|
+
displayName: 'DeepSeek R1 Distill Qwen 32B',
|
405
|
+
id: 'deepseek-r1-distill-qwen-32b',
|
406
|
+
pricing: {
|
407
|
+
currency: 'CNY',
|
408
|
+
input: 1.5,
|
409
|
+
output: 6,
|
410
|
+
},
|
411
|
+
type: 'chat',
|
412
|
+
},
|
413
|
+
{
|
414
|
+
abilities: {
|
415
|
+
reasoning: true,
|
416
|
+
},
|
417
|
+
contextWindowTokens: 32_768,
|
418
|
+
description:
|
419
|
+
'DeepSeek-R1-Distill-Llama-8B是DeepSeek-R1基于Llama3.1-8B-Base的蒸馏模型。',
|
420
|
+
displayName: 'DeepSeek R1 Distill Llama 8B',
|
421
|
+
id: 'deepseek-r1-distill-llama-8b',
|
422
|
+
pricing: {
|
423
|
+
currency: 'CNY',
|
424
|
+
input: 1.5,
|
425
|
+
output: 6,
|
426
|
+
},
|
427
|
+
type: 'chat',
|
428
|
+
},
|
429
|
+
{
|
430
|
+
abilities: {
|
431
|
+
reasoning: true,
|
432
|
+
},
|
433
|
+
contextWindowTokens: 32_768,
|
434
|
+
description:
|
435
|
+
'DeepSeek-R1-Distill-Llama-70B是DeepSeek-R1基于Llama3.3-70B-Instruct的蒸馏模型。',
|
436
|
+
displayName: 'DeepSeek R1 Distill Llama 70B',
|
437
|
+
id: 'deepseek-r1-distill-llama-70b',
|
438
|
+
pricing: {
|
439
|
+
currency: 'CNY',
|
440
|
+
input: 2,
|
441
|
+
output: 8,
|
442
|
+
},
|
443
|
+
type: 'chat',
|
444
|
+
},
|
445
|
+
{
|
446
|
+
abilities: {
|
447
|
+
reasoning: true,
|
448
|
+
},
|
449
|
+
contextWindowTokens: 32_768,
|
450
|
+
description:
|
451
|
+
'2025年2月14日首次发布,由千帆大模型研发团队以 Llama3_8B为base模型(Built with Meta Llama)蒸馏所得,蒸馏数据中也同步添加了千帆的语料。',
|
452
|
+
displayName: 'DeepSeek R1 Distill Qianfan Llama 8B',
|
453
|
+
id: 'deepseek-r1-distill-qianfan-llama-8b',
|
454
|
+
pricing: {
|
455
|
+
currency: 'CNY',
|
456
|
+
input: 1,
|
457
|
+
output: 4,
|
458
|
+
},
|
459
|
+
type: 'chat',
|
460
|
+
},
|
461
|
+
{
|
462
|
+
abilities: {
|
463
|
+
reasoning: true,
|
464
|
+
},
|
465
|
+
contextWindowTokens: 32_768,
|
466
|
+
description:
|
467
|
+
'2025年2月14日首次发布,由千帆大模型研发团队以 Llama3_70B为base模型(Built with Meta Llama)蒸馏所得,蒸馏数据中也同步添加了千帆的语料。',
|
468
|
+
displayName: 'DeepSeek R1 Distill Qianfan Llama 70B',
|
469
|
+
id: 'deepseek-r1-distill-qianfan-llama-70b',
|
470
|
+
pricing: {
|
471
|
+
currency: 'CNY',
|
472
|
+
input: 2,
|
473
|
+
output: 8,
|
474
|
+
},
|
475
|
+
type: 'chat',
|
476
|
+
},
|
477
|
+
{
|
478
|
+
abilities: {
|
479
|
+
reasoning: true,
|
480
|
+
},
|
481
|
+
contextWindowTokens: 32_768,
|
482
|
+
description:
|
483
|
+
'通义千问团队推出的高效推理模型,支持消费级硬件部署,具备强大的实时推理能力和与智能体Agent集成的潜力。',
|
484
|
+
displayName: 'QwQ 32B',
|
485
|
+
id: 'qwq-32b',
|
486
|
+
pricing: {
|
487
|
+
currency: 'CNY',
|
488
|
+
input: 2,
|
489
|
+
output: 8,
|
490
|
+
},
|
491
|
+
type: 'chat',
|
492
|
+
},
|
305
493
|
];
|
306
494
|
|
307
495
|
export const allModels = [...wenxinChatModels];
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import { Form, type FormItemProps } from '@lobehub/ui';
|
1
|
+
import { Form, type FormItemProps, Icon } from '@lobehub/ui';
|
2
2
|
import { Button, Segmented, Switch } from 'antd';
|
3
|
+
import { CopyIcon } from 'lucide-react';
|
3
4
|
import { memo, useState } from 'react';
|
4
5
|
import { useTranslation } from 'react-i18next';
|
5
6
|
import { Flexbox } from 'react-layout-kit';
|
6
7
|
|
7
8
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
9
|
+
import { useImgToClipboard } from '@/hooks/useImgToClipboard';
|
8
10
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
9
11
|
import { ImageType, imageTypeOptions, useScreenshot } from '@/hooks/useScreenshot';
|
10
12
|
import { useSessionStore } from '@/store/session';
|
@@ -32,7 +34,9 @@ const ShareImage = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
32
34
|
title: currentAgentTitle,
|
33
35
|
width: mobile ? 720 : undefined,
|
34
36
|
});
|
35
|
-
|
37
|
+
const { loading: copyLoading, onCopy } = useImgToClipboard({
|
38
|
+
width: mobile ? 720 : undefined,
|
39
|
+
});
|
36
40
|
const settings: FormItemProps[] = [
|
37
41
|
{
|
38
42
|
children: <Switch />,
|
@@ -66,15 +70,27 @@ const ShareImage = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
66
70
|
const isMobile = useIsMobile();
|
67
71
|
|
68
72
|
const button = (
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
<>
|
74
|
+
<Button
|
75
|
+
block
|
76
|
+
icon={<Icon icon={CopyIcon} />}
|
77
|
+
loading={copyLoading}
|
78
|
+
onClick={() => onCopy()}
|
79
|
+
size={isMobile ? undefined : 'large'}
|
80
|
+
type={'primary'}
|
81
|
+
>
|
82
|
+
{t('copy', { ns: 'common' })}
|
83
|
+
</Button>
|
84
|
+
<Button
|
85
|
+
block
|
86
|
+
loading={loading}
|
87
|
+
onClick={onDownload}
|
88
|
+
size={isMobile ? undefined : 'large'}
|
89
|
+
variant={'filled'}
|
90
|
+
>
|
91
|
+
{t('shareModal.download')}
|
92
|
+
</Button>
|
93
|
+
</>
|
78
94
|
);
|
79
95
|
|
80
96
|
return (
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { App } from 'antd';
|
2
|
+
import { t } from 'i18next';
|
3
|
+
import { useState } from 'react';
|
4
|
+
|
5
|
+
import { ImageType, getImageUrl } from './useScreenshot';
|
6
|
+
|
7
|
+
export const useImgToClipboard = ({ id = '#preview', width }: { id?: string; width?: number }) => {
|
8
|
+
const [loading, setLoading] = useState(false);
|
9
|
+
const { message } = App.useApp();
|
10
|
+
|
11
|
+
const handleCopy = async () => {
|
12
|
+
setLoading(true);
|
13
|
+
try {
|
14
|
+
const dataUrl = await getImageUrl({ id, imageType: ImageType.PNG, width });
|
15
|
+
const blob = await fetch(dataUrl).then((res) => res.blob());
|
16
|
+
navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
|
17
|
+
setLoading(false);
|
18
|
+
message.success(t('copySuccess', { defaultValue: 'Copy Success', ns: 'common' }));
|
19
|
+
} catch (error) {
|
20
|
+
console.error('Failed to copy image', error);
|
21
|
+
setLoading(false);
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
return {
|
26
|
+
loading,
|
27
|
+
onCopy: handleCopy,
|
28
|
+
};
|
29
|
+
};
|
@@ -31,6 +31,58 @@ export const imageTypeOptions: SegmentedProps['options'] = [
|
|
31
31
|
},
|
32
32
|
];
|
33
33
|
|
34
|
+
export const getImageUrl = async ({
|
35
|
+
imageType,
|
36
|
+
id = '#preview',
|
37
|
+
width,
|
38
|
+
}: {
|
39
|
+
id?: string;
|
40
|
+
imageType: ImageType;
|
41
|
+
width?: number;
|
42
|
+
}) => {
|
43
|
+
let screenshotFn: any;
|
44
|
+
switch (imageType) {
|
45
|
+
case ImageType.JPG: {
|
46
|
+
screenshotFn = domToJpeg;
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
case ImageType.PNG: {
|
50
|
+
screenshotFn = domToPng;
|
51
|
+
break;
|
52
|
+
}
|
53
|
+
case ImageType.SVG: {
|
54
|
+
screenshotFn = domToSvg;
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
case ImageType.WEBP: {
|
58
|
+
screenshotFn = domToWebp;
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
const dom: HTMLDivElement = document.querySelector(id) as HTMLDivElement;
|
64
|
+
let copy: HTMLDivElement = dom;
|
65
|
+
|
66
|
+
if (width) {
|
67
|
+
copy = dom.cloneNode(true) as HTMLDivElement;
|
68
|
+
copy.style.width = `${width}px`;
|
69
|
+
document.body.append(copy);
|
70
|
+
}
|
71
|
+
|
72
|
+
const dataUrl = await screenshotFn(width ? copy : dom, {
|
73
|
+
features: {
|
74
|
+
// 不启用移除控制符,否则会导致 safari emoji 报错
|
75
|
+
removeControlCharacter: false,
|
76
|
+
},
|
77
|
+
scale: 2,
|
78
|
+
width,
|
79
|
+
});
|
80
|
+
|
81
|
+
if (width && copy) copy?.remove();
|
82
|
+
|
83
|
+
return dataUrl;
|
84
|
+
};
|
85
|
+
|
34
86
|
export const useScreenshot = ({
|
35
87
|
imageType,
|
36
88
|
title = 'share',
|
@@ -47,46 +99,7 @@ export const useScreenshot = ({
|
|
47
99
|
const handleDownload = useCallback(async () => {
|
48
100
|
setLoading(true);
|
49
101
|
try {
|
50
|
-
|
51
|
-
switch (imageType) {
|
52
|
-
case ImageType.JPG: {
|
53
|
-
screenshotFn = domToJpeg;
|
54
|
-
break;
|
55
|
-
}
|
56
|
-
case ImageType.PNG: {
|
57
|
-
screenshotFn = domToPng;
|
58
|
-
break;
|
59
|
-
}
|
60
|
-
case ImageType.SVG: {
|
61
|
-
screenshotFn = domToSvg;
|
62
|
-
break;
|
63
|
-
}
|
64
|
-
case ImageType.WEBP: {
|
65
|
-
screenshotFn = domToWebp;
|
66
|
-
break;
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
const dom: HTMLDivElement = document.querySelector(id) as HTMLDivElement;
|
71
|
-
let copy: HTMLDivElement = dom;
|
72
|
-
|
73
|
-
if (width) {
|
74
|
-
copy = dom.cloneNode(true) as HTMLDivElement;
|
75
|
-
copy.style.width = `${width}px`;
|
76
|
-
document.body.append(copy);
|
77
|
-
}
|
78
|
-
|
79
|
-
const dataUrl = await screenshotFn(width ? copy : dom, {
|
80
|
-
features: {
|
81
|
-
// 不启用移除控制符,否则会导致 safari emoji 报错
|
82
|
-
removeControlCharacter: false,
|
83
|
-
},
|
84
|
-
scale: 2,
|
85
|
-
width,
|
86
|
-
});
|
87
|
-
|
88
|
-
if (width && copy) copy?.remove();
|
89
|
-
|
102
|
+
const dataUrl = await getImageUrl({ id, imageType, width });
|
90
103
|
const link = document.createElement('a');
|
91
104
|
link.download = `${BRANDING_NAME}_${title}_${dayjs().format('YYYY-MM-DD')}.${imageType}`;
|
92
105
|
link.href = dataUrl;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
2
|
+
|
3
|
+
import { getUserAuth } from '../auth';
|
4
|
+
|
5
|
+
// Mock auth constants
|
6
|
+
let mockEnableClerk = false;
|
7
|
+
let mockEnableNextAuth = false;
|
8
|
+
|
9
|
+
vi.mock('@/const/auth', () => ({
|
10
|
+
get enableClerk() {
|
11
|
+
return mockEnableClerk;
|
12
|
+
},
|
13
|
+
get enableNextAuth() {
|
14
|
+
return mockEnableNextAuth;
|
15
|
+
},
|
16
|
+
}));
|
17
|
+
|
18
|
+
vi.mock('@/libs/clerk-auth', () => ({
|
19
|
+
ClerkAuth: class {
|
20
|
+
async getAuth() {
|
21
|
+
return {
|
22
|
+
clerkAuth: {
|
23
|
+
redirectToSignIn: vi.fn(),
|
24
|
+
},
|
25
|
+
userId: 'clerk-user-id',
|
26
|
+
};
|
27
|
+
}
|
28
|
+
},
|
29
|
+
}));
|
30
|
+
|
31
|
+
vi.mock('@/libs/next-auth/edge', () => ({
|
32
|
+
default: {
|
33
|
+
auth: vi.fn().mockResolvedValue({
|
34
|
+
user: {
|
35
|
+
id: 'next-auth-user-id',
|
36
|
+
},
|
37
|
+
}),
|
38
|
+
},
|
39
|
+
}));
|
40
|
+
|
41
|
+
describe('getUserAuth', () => {
|
42
|
+
beforeEach(() => {
|
43
|
+
vi.clearAllMocks();
|
44
|
+
mockEnableClerk = false;
|
45
|
+
mockEnableNextAuth = false;
|
46
|
+
});
|
47
|
+
|
48
|
+
it('should throw error when no auth method is enabled', async () => {
|
49
|
+
await expect(getUserAuth()).rejects.toThrow('Auth method is not enabled');
|
50
|
+
});
|
51
|
+
|
52
|
+
it('should return clerk auth when clerk is enabled', async () => {
|
53
|
+
mockEnableClerk = true;
|
54
|
+
mockEnableNextAuth = false;
|
55
|
+
|
56
|
+
const auth = await getUserAuth();
|
57
|
+
|
58
|
+
expect(auth).toEqual({
|
59
|
+
clerkAuth: {
|
60
|
+
redirectToSignIn: expect.any(Function),
|
61
|
+
},
|
62
|
+
userId: 'clerk-user-id',
|
63
|
+
});
|
64
|
+
});
|
65
|
+
|
66
|
+
it('should return next auth when next auth is enabled', async () => {
|
67
|
+
mockEnableClerk = false;
|
68
|
+
mockEnableNextAuth = true;
|
69
|
+
|
70
|
+
const auth = await getUserAuth();
|
71
|
+
|
72
|
+
expect(auth).toEqual({
|
73
|
+
nextAuth: {
|
74
|
+
user: {
|
75
|
+
id: 'next-auth-user-id',
|
76
|
+
},
|
77
|
+
},
|
78
|
+
userId: 'next-auth-user-id',
|
79
|
+
});
|
80
|
+
});
|
81
|
+
|
82
|
+
it('should prioritize clerk auth over next auth when both are enabled', async () => {
|
83
|
+
mockEnableClerk = true;
|
84
|
+
mockEnableNextAuth = true;
|
85
|
+
|
86
|
+
const auth = await getUserAuth();
|
87
|
+
|
88
|
+
expect(auth).toEqual({
|
89
|
+
clerkAuth: {
|
90
|
+
redirectToSignIn: expect.any(Function),
|
91
|
+
},
|
92
|
+
userId: 'clerk-user-id',
|
93
|
+
});
|
94
|
+
});
|
95
|
+
});
|