@lobehub/chat 1.84.19 → 1.84.21
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/changelog/v1.json +18 -0
- package/package.json +1 -1
- package/src/config/aiModels/hunyuan.ts +4 -4
- package/src/config/aiModels/index.ts +0 -3
- package/src/config/aiModels/novita.ts +66 -6
- package/src/config/aiModels/qwen.ts +19 -17
- package/src/config/aiModels/siliconcloud.ts +19 -27
- package/src/config/aiModels/volcengine.ts +9 -9
- package/src/config/llm.ts +0 -6
- package/src/config/modelProviders/index.ts +0 -3
- package/src/libs/agent-runtime/qwen/index.ts +20 -8
- package/src/libs/agent-runtime/runtimeMap.ts +0 -1
- package/src/libs/agent-runtime/types/type.ts +0 -4
- package/src/libs/agent-runtime/utils/streams/qwen.test.ts +76 -1
- package/src/libs/agent-runtime/utils/streams/qwen.ts +26 -2
- package/src/libs/agent-runtime/volcengine/index.ts +1 -1
- package/src/server/globalConfig/index.ts +0 -3
- package/src/server/modules/AssistantStore/index.test.ts +141 -8
- package/src/services/chat.ts +0 -1
- package/src/types/aiModel.ts +2 -2
- package/src/types/aiProvider.ts +0 -4
- package/src/types/user/settings/keyVaults.ts +0 -1
- package/src/app/[variants]/(main)/settings/provider/(detail)/doubao/page.tsx +0 -39
- package/src/config/aiModels/doubao.ts +0 -65
- package/src/config/modelProviders/doubao.ts +0 -24
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.84.21](https://github.com/lobehub/lobe-chat/compare/v1.84.20...v1.84.21)
|
6
|
+
|
7
|
+
<sup>Released on **2025-05-04**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Remove doubao Provider.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Remove doubao Provider, closes [#7573](https://github.com/lobehub/lobe-chat/issues/7573) ([0cf3bcc](https://github.com/lobehub/lobe-chat/commit/0cf3bcc))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.84.20](https://github.com/lobehub/lobe-chat/compare/v1.84.19...v1.84.20)
|
31
|
+
|
32
|
+
<sup>Released on **2025-05-04**</sup>
|
33
|
+
|
34
|
+
#### 💄 Styles
|
35
|
+
|
36
|
+
- **misc**: Show Aliyun Bailian tokens usage tracking.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### Styles
|
44
|
+
|
45
|
+
- **misc**: Show Aliyun Bailian tokens usage tracking, closes [#7660](https://github.com/lobehub/lobe-chat/issues/7660) ([3ef0542](https://github.com/lobehub/lobe-chat/commit/3ef0542))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.84.19](https://github.com/lobehub/lobe-chat/compare/v1.84.18...v1.84.19)
|
6
56
|
|
7
57
|
<sup>Released on **2025-05-04**</sup>
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"improvements": [
|
5
|
+
"Remove doubao Provider."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-05-04",
|
9
|
+
"version": "1.84.21"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"improvements": [
|
14
|
+
"Show Aliyun Bailian tokens usage tracking."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2025-05-04",
|
18
|
+
"version": "1.84.20"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {
|
4
22
|
"improvements": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.84.
|
3
|
+
"version": "1.84.21",
|
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",
|
@@ -231,7 +231,7 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
231
231
|
input: 0.8,
|
232
232
|
output: 2,
|
233
233
|
},
|
234
|
-
releasedAt: '2025-
|
234
|
+
releasedAt: '2025-04-16',
|
235
235
|
settings: {
|
236
236
|
searchImpl: 'params',
|
237
237
|
},
|
@@ -349,12 +349,12 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
349
349
|
abilities: {
|
350
350
|
vision: true,
|
351
351
|
},
|
352
|
-
contextWindowTokens:
|
352
|
+
contextWindowTokens: 32_000,
|
353
353
|
description: '混元最新多模态模型,支持图片+文本输入生成文本内容。',
|
354
354
|
displayName: 'Hunyuan Vision',
|
355
355
|
enabled: true,
|
356
356
|
id: 'hunyuan-vision',
|
357
|
-
maxOutput:
|
357
|
+
maxOutput: 16_000,
|
358
358
|
pricing: {
|
359
359
|
currency: 'CNY',
|
360
360
|
input: 18,
|
@@ -393,7 +393,7 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
393
393
|
input: 4,
|
394
394
|
output: 8,
|
395
395
|
},
|
396
|
-
releasedAt: '
|
396
|
+
releasedAt: '2025-04-22',
|
397
397
|
type: 'chat',
|
398
398
|
},
|
399
399
|
{
|
@@ -10,7 +10,6 @@ import { default as bedrock } from './bedrock';
|
|
10
10
|
import { default as cloudflare } from './cloudflare';
|
11
11
|
import { default as cohere } from './cohere';
|
12
12
|
import { default as deepseek } from './deepseek';
|
13
|
-
import { default as doubao } from './doubao';
|
14
13
|
import { default as fireworksai } from './fireworksai';
|
15
14
|
import { default as giteeai } from './giteeai';
|
16
15
|
import { default as github } from './github';
|
@@ -83,7 +82,6 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({
|
|
83
82
|
cloudflare,
|
84
83
|
cohere,
|
85
84
|
deepseek,
|
86
|
-
doubao,
|
87
85
|
fireworksai,
|
88
86
|
giteeai,
|
89
87
|
github,
|
@@ -137,7 +135,6 @@ export { default as bedrock } from './bedrock';
|
|
137
135
|
export { default as cloudflare } from './cloudflare';
|
138
136
|
export { default as cohere } from './cohere';
|
139
137
|
export { default as deepseek } from './deepseek';
|
140
|
-
export { default as doubao } from './doubao';
|
141
138
|
export { default as fireworksai } from './fireworksai';
|
142
139
|
export { default as giteeai } from './giteeai';
|
143
140
|
export { default as github } from './github';
|
@@ -279,7 +279,7 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
279
279
|
},
|
280
280
|
{
|
281
281
|
contextWindowTokens: 32_000,
|
282
|
-
displayName: '
|
282
|
+
displayName: 'Qwen2.5 72B Instruct',
|
283
283
|
id: 'qwen/qwen-2.5-72b-instruct',
|
284
284
|
pricing: {
|
285
285
|
input: 0.38,
|
@@ -332,7 +332,7 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
332
332
|
vision: true,
|
333
333
|
},
|
334
334
|
contextWindowTokens: 96_000,
|
335
|
-
displayName: '
|
335
|
+
displayName: 'Qwen2.5 VL 72B Instruct',
|
336
336
|
enabled: true,
|
337
337
|
id: 'qwen/qwen2.5-vl-72b-instruct',
|
338
338
|
pricing: {
|
@@ -345,9 +345,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
345
345
|
contextWindowTokens: 131_000,
|
346
346
|
displayName: 'Llama 3.2 1B Instruct',
|
347
347
|
id: 'meta-llama/llama-3.2-1b-instruct',
|
348
|
-
pricing: {
|
349
|
-
input: 0
|
350
|
-
output: 0
|
348
|
+
pricing: {
|
349
|
+
input: 0,
|
350
|
+
output: 0
|
351
351
|
},
|
352
352
|
type: 'chat',
|
353
353
|
},
|
@@ -405,8 +405,68 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
405
405
|
},
|
406
406
|
type: 'chat',
|
407
407
|
},
|
408
|
+
{
|
409
|
+
contextWindowTokens: 32_000,
|
410
|
+
displayName: 'Qwen2.5 7B Instruct',
|
411
|
+
id: 'qwen/qwen2.5-7b-instruct',
|
412
|
+
pricing: {
|
413
|
+
input: 0,
|
414
|
+
output: 0,
|
415
|
+
},
|
416
|
+
type: 'chat',
|
417
|
+
},
|
418
|
+
{
|
419
|
+
contextWindowTokens: 32_000,
|
420
|
+
displayName: 'GLM 4 9B 0414',
|
421
|
+
id: 'thudm/glm-4-9b-0414',
|
422
|
+
pricing: {
|
423
|
+
input: 0,
|
424
|
+
output: 0
|
425
|
+
},
|
426
|
+
type: 'chat',
|
427
|
+
},
|
428
|
+
{
|
429
|
+
contextWindowTokens: 32_000,
|
430
|
+
displayName: 'GLM Z1 9B 0414',
|
431
|
+
id: 'thudm/glm-z1-9b-0414',
|
432
|
+
pricing: {
|
433
|
+
input: 0,
|
434
|
+
output: 0
|
435
|
+
},
|
436
|
+
type: 'chat',
|
437
|
+
},
|
438
|
+
{
|
439
|
+
contextWindowTokens: 32_000,
|
440
|
+
displayName: 'GLM Z1 32B 0414',
|
441
|
+
id: 'thudm/glm-z1-32b-0414',
|
442
|
+
pricing: {
|
443
|
+
input: 0.24,
|
444
|
+
output: 0.24
|
445
|
+
},
|
446
|
+
type: 'chat',
|
447
|
+
},
|
448
|
+
{
|
449
|
+
contextWindowTokens: 32_000,
|
450
|
+
displayName: 'GLM 4 32B 0414',
|
451
|
+
id: 'thudm/glm-4-32b-0414',
|
452
|
+
pricing: {
|
453
|
+
input: 0.24,
|
454
|
+
output: 0.24
|
455
|
+
},
|
456
|
+
type: 'chat',
|
457
|
+
},
|
458
|
+
{
|
459
|
+
contextWindowTokens: 32_000,
|
460
|
+
displayName: 'GLM Z1 Rumination 32B 0414',
|
461
|
+
id: 'thudm/glm-z1-rumination-32b-0414',
|
462
|
+
pricing: {
|
463
|
+
input: 0.24,
|
464
|
+
output: 0.24
|
465
|
+
},
|
466
|
+
type: 'chat',
|
467
|
+
},
|
408
468
|
];
|
409
469
|
|
410
470
|
export const allModels = [...novitaChatModels];
|
411
471
|
|
412
|
-
export default allModels;
|
472
|
+
export default allModels;
|
@@ -270,7 +270,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
270
270
|
functionCall: true,
|
271
271
|
search: true,
|
272
272
|
},
|
273
|
-
contextWindowTokens:
|
273
|
+
contextWindowTokens: 131_072,
|
274
274
|
description:
|
275
275
|
'通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入,当前通义千问2.5产品版本背后的API模型。',
|
276
276
|
displayName: 'Qwen Max',
|
@@ -292,13 +292,13 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
292
292
|
abilities: {
|
293
293
|
functionCall: true,
|
294
294
|
},
|
295
|
-
contextWindowTokens:
|
295
|
+
contextWindowTokens: 10_000_000,
|
296
296
|
description:
|
297
297
|
'通义千问超大规模语言模型,支持长文本上下文,以及基于长文档、多文档等多个场景的对话功能。',
|
298
298
|
displayName: 'Qwen Long',
|
299
299
|
enabled: true,
|
300
300
|
id: 'qwen-long',
|
301
|
-
maxOutput:
|
301
|
+
maxOutput: 8192,
|
302
302
|
organization: 'Qwen',
|
303
303
|
pricing: {
|
304
304
|
currency: 'CNY',
|
@@ -337,23 +337,23 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
337
337
|
id: 'qwen2.5-omni-7b',
|
338
338
|
maxOutput: 2048,
|
339
339
|
organization: 'Qwen',
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
340
|
+
pricing: {
|
341
|
+
currency: 'CNY',
|
342
|
+
input: 0.6,
|
343
|
+
output: 6,
|
344
|
+
},
|
345
345
|
type: 'chat',
|
346
346
|
},
|
347
347
|
{
|
348
348
|
abilities: {
|
349
349
|
vision: true,
|
350
350
|
},
|
351
|
-
contextWindowTokens:
|
351
|
+
contextWindowTokens: 131_072,
|
352
352
|
description:
|
353
353
|
'通义千问大规模视觉语言模型增强版。大幅提升细节识别能力和文字识别能力,支持超百万像素分辨率和任意长宽比规格的图像。',
|
354
354
|
displayName: 'Qwen VL Plus',
|
355
355
|
id: 'qwen-vl-plus-latest',
|
356
|
-
maxOutput:
|
356
|
+
maxOutput: 8192,
|
357
357
|
organization: 'Qwen',
|
358
358
|
pricing: {
|
359
359
|
currency: 'CNY',
|
@@ -366,13 +366,13 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
366
366
|
abilities: {
|
367
367
|
vision: true,
|
368
368
|
},
|
369
|
-
contextWindowTokens:
|
369
|
+
contextWindowTokens: 131_072,
|
370
370
|
description:
|
371
371
|
'通义千问超大规模视觉语言模型。相比增强版,再次提升视觉推理能力和指令遵循能力,提供更高的视觉感知和认知水平。',
|
372
372
|
displayName: 'Qwen VL Max',
|
373
373
|
enabled: true,
|
374
374
|
id: 'qwen-vl-max-latest',
|
375
|
-
maxOutput:
|
375
|
+
maxOutput: 8192,
|
376
376
|
organization: 'Qwen',
|
377
377
|
pricing: {
|
378
378
|
currency: 'CNY',
|
@@ -505,7 +505,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
505
505
|
description:
|
506
506
|
'通义千问QVQ视觉推理模型,支持视觉输入及思维链输出,在数学、编程、视觉分析、创作以及通用任务上都表现了更强的能力。',
|
507
507
|
displayName: 'QVQ Max',
|
508
|
-
id: 'qvq-max',
|
508
|
+
id: 'qvq-max-latest',
|
509
509
|
maxOutput: 8192,
|
510
510
|
organization: 'Qwen',
|
511
511
|
pricing: {
|
@@ -582,8 +582,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
582
582
|
organization: 'Qwen',
|
583
583
|
pricing: {
|
584
584
|
currency: 'CNY',
|
585
|
-
input:
|
586
|
-
output:
|
585
|
+
input: 2,
|
586
|
+
output: 6,
|
587
587
|
},
|
588
588
|
type: 'chat',
|
589
589
|
},
|
@@ -673,8 +673,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
673
673
|
organization: 'Qwen',
|
674
674
|
pricing: {
|
675
675
|
currency: 'CNY',
|
676
|
-
input:
|
677
|
-
output:
|
676
|
+
input: 2,
|
677
|
+
output: 6,
|
678
678
|
},
|
679
679
|
type: 'chat',
|
680
680
|
},
|
@@ -686,6 +686,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
686
686
|
description: '以 Qwen-7B 语言模型初始化,添加图像模型,图像输入分辨率为448的预训练模型。',
|
687
687
|
displayName: 'Qwen VL',
|
688
688
|
id: 'qwen-vl-v1',
|
689
|
+
maxOutput: 1500,
|
689
690
|
organization: 'Qwen',
|
690
691
|
pricing: {
|
691
692
|
currency: 'CNY',
|
@@ -702,6 +703,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
702
703
|
description: '通义千问VL支持灵活的交互方式,包括多图、多轮问答、创作等能力的模型。',
|
703
704
|
displayName: 'Qwen VL Chat',
|
704
705
|
id: 'qwen-vl-chat-v1',
|
706
|
+
maxOutput: 1500,
|
705
707
|
organization: 'Qwen',
|
706
708
|
pricing: {
|
707
709
|
currency: 'CNY',
|
@@ -125,8 +125,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
125
125
|
id: 'THUDM/GLM-Z1-Rumination-32B-0414',
|
126
126
|
pricing: {
|
127
127
|
currency: 'CNY',
|
128
|
-
input:
|
129
|
-
output:
|
128
|
+
input: 1,
|
129
|
+
output: 4,
|
130
130
|
},
|
131
131
|
type: 'chat',
|
132
132
|
},
|
@@ -142,8 +142,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
142
142
|
id: 'THUDM/GLM-Z1-32B-0414',
|
143
143
|
pricing: {
|
144
144
|
currency: 'CNY',
|
145
|
-
input:
|
146
|
-
output:
|
145
|
+
input: 1,
|
146
|
+
output: 4,
|
147
147
|
},
|
148
148
|
type: 'chat',
|
149
149
|
},
|
@@ -176,8 +176,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
176
176
|
id: 'THUDM/GLM-4-32B-0414',
|
177
177
|
pricing: {
|
178
178
|
currency: 'CNY',
|
179
|
-
input:
|
180
|
-
output:
|
179
|
+
input: 1.89,
|
180
|
+
output: 1.89,
|
181
181
|
},
|
182
182
|
type: 'chat',
|
183
183
|
},
|
@@ -200,7 +200,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
200
200
|
},
|
201
201
|
{
|
202
202
|
abilities: {
|
203
|
-
functionCall: true,
|
204
203
|
reasoning: true,
|
205
204
|
},
|
206
205
|
contextWindowTokens: 65_536,
|
@@ -233,7 +232,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
233
232
|
},
|
234
233
|
{
|
235
234
|
abilities: {
|
236
|
-
functionCall: true,
|
237
235
|
reasoning: true,
|
238
236
|
},
|
239
237
|
contextWindowTokens: 65_536,
|
@@ -282,7 +280,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
282
280
|
},
|
283
281
|
{
|
284
282
|
abilities: {
|
285
|
-
|
283
|
+
functionCall: true,
|
284
|
+
reasoning: true
|
286
285
|
},
|
287
286
|
contextWindowTokens: 32_768,
|
288
287
|
description:
|
@@ -298,7 +297,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
298
297
|
},
|
299
298
|
{
|
300
299
|
abilities: {
|
301
|
-
|
300
|
+
functionCall: true,
|
301
|
+
reasoning: true
|
302
302
|
},
|
303
303
|
contextWindowTokens: 32_768,
|
304
304
|
description:
|
@@ -314,7 +314,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
314
314
|
},
|
315
315
|
{
|
316
316
|
abilities: {
|
317
|
-
|
317
|
+
functionCall: true,
|
318
|
+
reasoning: true
|
318
319
|
},
|
319
320
|
contextWindowTokens: 32_768,
|
320
321
|
description:
|
@@ -330,7 +331,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
330
331
|
},
|
331
332
|
{
|
332
333
|
abilities: {
|
333
|
-
|
334
|
+
functionCall: true,
|
335
|
+
reasoning: true
|
334
336
|
},
|
335
337
|
contextWindowTokens: 32_768,
|
336
338
|
description:
|
@@ -346,7 +348,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
346
348
|
},
|
347
349
|
{
|
348
350
|
abilities: {
|
349
|
-
|
351
|
+
functionCall: true,
|
352
|
+
reasoning: true
|
350
353
|
},
|
351
354
|
contextWindowTokens: 32_768,
|
352
355
|
description:
|
@@ -362,7 +365,8 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
362
365
|
},
|
363
366
|
{
|
364
367
|
abilities: {
|
365
|
-
|
368
|
+
functionCall: true,
|
369
|
+
reasoning: true
|
366
370
|
},
|
367
371
|
contextWindowTokens: 32_768,
|
368
372
|
description:
|
@@ -427,6 +431,7 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
427
431
|
},
|
428
432
|
{
|
429
433
|
abilities: {
|
434
|
+
functionCall: true,
|
430
435
|
reasoning: true,
|
431
436
|
},
|
432
437
|
contextWindowTokens: 32_768,
|
@@ -817,19 +822,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
817
822
|
},
|
818
823
|
type: 'chat',
|
819
824
|
},
|
820
|
-
{
|
821
|
-
contextWindowTokens: 8192,
|
822
|
-
description:
|
823
|
-
'TeleChat2大模型是由中国电信从0到1自主研发的生成式语义大模型,支持百科问答、代码生成、长文生成等功能,为用户提供对话咨询服务,能够与用户进行对话互动,回答问题,协助创作,高效便捷地帮助用户获取信息、知识和灵感。模型在幻觉问题、长文生成、逻辑理解等方面均有较出色表现。',
|
824
|
-
displayName: 'TeleChat2',
|
825
|
-
id: 'TeleAI/TeleChat2',
|
826
|
-
pricing: {
|
827
|
-
currency: 'CNY',
|
828
|
-
input: 1.33,
|
829
|
-
output: 1.33,
|
830
|
-
},
|
831
|
-
type: 'chat',
|
832
|
-
},
|
833
825
|
];
|
834
826
|
|
835
827
|
export const allModels = [...siliconcloudChatModels];
|
@@ -12,7 +12,7 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
12
12
|
config: {
|
13
13
|
deploymentName: 'doubao-1-5-thinking-pro-250415',
|
14
14
|
},
|
15
|
-
contextWindowTokens:
|
15
|
+
contextWindowTokens: 131_072,
|
16
16
|
description:
|
17
17
|
'Doubao-1.5全新深度思考模型,在数学、编程、科学推理等专业领域及创意写作等通用任务中表现突出,在AIME 2024、Codeforces、GPQA等多项权威基准上达到或接近业界第一梯队水平。支持128k上下文窗口,16k输出。',
|
18
18
|
displayName: 'Doubao 1.5 Thinking Pro',
|
@@ -35,12 +35,12 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
35
35
|
config: {
|
36
36
|
deploymentName: 'doubao-1-5-thinking-pro-m-250415',
|
37
37
|
},
|
38
|
-
contextWindowTokens:
|
38
|
+
contextWindowTokens: 131_072,
|
39
39
|
description:
|
40
|
-
'Doubao-1.5
|
41
|
-
displayName: 'Doubao 1.5 Thinking Pro
|
40
|
+
'Doubao-1.5全新深度思考模型 (m 版本自带原生多模态深度推理能力),在数学、编程、科学推理等专业领域及创意写作等通用任务中表现突出,在AIME 2024、Codeforces、GPQA等多项权威基准上达到或接近业界第一梯队水平。支持128k上下文窗口,16k输出。',
|
41
|
+
displayName: 'Doubao 1.5 Thinking Pro M',
|
42
42
|
enabled: true,
|
43
|
-
id: '
|
43
|
+
id: 'Doubao-1.5-thinking-pro-m',
|
44
44
|
maxOutput: 16_000,
|
45
45
|
pricing: {
|
46
46
|
currency: 'CNY',
|
@@ -57,7 +57,7 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
57
57
|
config: {
|
58
58
|
deploymentName: 'deepseek-r1-250120',
|
59
59
|
},
|
60
|
-
contextWindowTokens:
|
60
|
+
contextWindowTokens: 98_304,
|
61
61
|
description:
|
62
62
|
'DeepSeek-R1 在后训练阶段大规模使用了强化学习技术,在仅有极少标注数据的情况下,极大提升了模型推理能力。在数学、代码、自然语言推理等任务上,性能比肩 OpenAI o1 正式版。',
|
63
63
|
displayName: 'DeepSeek R1',
|
@@ -78,7 +78,7 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
78
78
|
config: {
|
79
79
|
deploymentName: 'deepseek-r1-distill-qwen-32b-250120',
|
80
80
|
},
|
81
|
-
contextWindowTokens:
|
81
|
+
contextWindowTokens: 65_536,
|
82
82
|
description:
|
83
83
|
'DeepSeek-R1-Distill 模型是在开源模型的基础上通过微调训练得到的,训练过程中使用了由 DeepSeek-R1 生成的样本数据。',
|
84
84
|
displayName: 'DeepSeek R1 Distill Qwen 32B',
|
@@ -99,7 +99,7 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
99
99
|
config: {
|
100
100
|
deploymentName: 'deepseek-r1-distill-qwen-7b-250120',
|
101
101
|
},
|
102
|
-
contextWindowTokens:
|
102
|
+
contextWindowTokens: 65_536,
|
103
103
|
description:
|
104
104
|
'DeepSeek-R1-Distill 模型是在开源模型的基础上通过微调训练得到的,训练过程中使用了由 DeepSeek-R1 生成的样本数据。',
|
105
105
|
displayName: 'DeepSeek R1 Distill Qwen 7B',
|
@@ -119,7 +119,7 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
119
119
|
config: {
|
120
120
|
deploymentName: 'deepseek-v3-250324',
|
121
121
|
},
|
122
|
-
contextWindowTokens:
|
122
|
+
contextWindowTokens: 128_000,
|
123
123
|
description:
|
124
124
|
'DeepSeek-V3 是一款由深度求索公司自研的MoE模型。DeepSeek-V3 多项评测成绩超越了 Qwen2.5-72B 和 Llama-3.1-405B 等其他开源模型,并在性能上和世界顶尖的闭源模型 GPT-4o 以及 Claude-3.5-Sonnet 不分伯仲。',
|
125
125
|
displayName: 'DeepSeek V3',
|
package/src/config/llm.ts
CHANGED
@@ -136,9 +136,6 @@ export const getLLMConfig = () => {
|
|
136
136
|
ENABLED_HIGRESS: z.boolean(),
|
137
137
|
HIGRESS_API_KEY: z.string().optional(),
|
138
138
|
|
139
|
-
ENABLED_DOUBAO: z.boolean(),
|
140
|
-
DOUBAO_API_KEY: z.string().optional(),
|
141
|
-
|
142
139
|
ENABLED_VOLCENGINE: z.boolean(),
|
143
140
|
VOLCENGINE_API_KEY: z.string().optional(),
|
144
141
|
|
@@ -299,9 +296,6 @@ export const getLLMConfig = () => {
|
|
299
296
|
ENABLED_HIGRESS: !!process.env.HIGRESS_API_KEY,
|
300
297
|
HIGRESS_API_KEY: process.env.HIGRESS_API_KEY,
|
301
298
|
|
302
|
-
ENABLED_DOUBAO: !!process.env.DOUBAO_API_KEY,
|
303
|
-
DOUBAO_API_KEY: process.env.DOUBAO_API_KEY,
|
304
|
-
|
305
299
|
ENABLED_TENCENT_CLOUD: !!process.env.TENCENT_CLOUD_API_KEY,
|
306
300
|
TENCENT_CLOUD_API_KEY: process.env.TENCENT_CLOUD_API_KEY,
|
307
301
|
|
@@ -10,7 +10,6 @@ import BedrockProvider from './bedrock';
|
|
10
10
|
import CloudflareProvider from './cloudflare';
|
11
11
|
import CohereProvider from './cohere';
|
12
12
|
import DeepSeekProvider from './deepseek';
|
13
|
-
import DoubaoProvider from './doubao';
|
14
13
|
import FireworksAIProvider from './fireworksai';
|
15
14
|
import GiteeAIProvider from './giteeai';
|
16
15
|
import GithubProvider from './github';
|
@@ -155,7 +154,6 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
|
|
155
154
|
GiteeAIProvider,
|
156
155
|
TaichuProvider,
|
157
156
|
Ai360Provider,
|
158
|
-
DoubaoProvider,
|
159
157
|
Search1APIProvider,
|
160
158
|
InfiniAIProvider,
|
161
159
|
];
|
@@ -179,7 +177,6 @@ export { default as BedrockProviderCard } from './bedrock';
|
|
179
177
|
export { default as CloudflareProviderCard } from './cloudflare';
|
180
178
|
export { default as CohereProviderCard } from './cohere';
|
181
179
|
export { default as DeepSeekProviderCard } from './deepseek';
|
182
|
-
export { default as DoubaoProviderCard } from './doubao';
|
183
180
|
export { default as FireworksAIProviderCard } from './fireworksai';
|
184
181
|
export { default as GiteeAIProviderCard } from './giteeai';
|
185
182
|
export { default as GithubProviderCard } from './github';
|
@@ -24,16 +24,19 @@ export const LobeQwenAI = LobeOpenAICompatibleFactory({
|
|
24
24
|
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
25
25
|
chatCompletion: {
|
26
26
|
handlePayload: (payload) => {
|
27
|
-
const { model, presence_penalty, temperature, thinking, top_p, enabledSearch, ...rest } =
|
27
|
+
const { model, presence_penalty, temperature, thinking, top_p, enabledSearch, ...rest } =
|
28
|
+
payload;
|
28
29
|
|
29
30
|
return {
|
30
31
|
...rest,
|
31
|
-
...(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
...(['qwen3', 'qwen-turbo', 'qwen-plus'].some((keyword) =>
|
33
|
+
model.toLowerCase().includes(keyword),
|
34
|
+
)
|
35
|
+
? {
|
36
|
+
enable_thinking: thinking !== undefined ? thinking.type === 'enabled' : false,
|
37
|
+
thinking_budget:
|
38
|
+
thinking?.budget_tokens === 0 ? 0 : thinking?.budget_tokens || undefined,
|
39
|
+
}
|
37
40
|
: {}),
|
38
41
|
frequency_penalty: undefined,
|
39
42
|
model,
|
@@ -77,7 +80,16 @@ export const LobeQwenAI = LobeOpenAICompatibleFactory({
|
|
77
80
|
models: async ({ client }) => {
|
78
81
|
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
79
82
|
|
80
|
-
const functionCallKeywords = [
|
83
|
+
const functionCallKeywords = [
|
84
|
+
'qwen-max',
|
85
|
+
'qwen-plus',
|
86
|
+
'qwen-turbo',
|
87
|
+
'qwen-long',
|
88
|
+
'qwen1.5',
|
89
|
+
'qwen2',
|
90
|
+
'qwen2.5',
|
91
|
+
'qwen3',
|
92
|
+
];
|
81
93
|
|
82
94
|
const visionKeywords = ['qvq', 'vl'];
|
83
95
|
|
@@ -1,6 +1,8 @@
|
|
1
|
+
import OpenAI from 'openai';
|
1
2
|
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
2
3
|
|
3
|
-
import {
|
4
|
+
import { StreamContext } from './protocol';
|
5
|
+
import { QwenAIStream, transformQwenStream } from './qwen';
|
4
6
|
|
5
7
|
describe('QwenAIStream', () => {
|
6
8
|
beforeAll(() => {});
|
@@ -349,3 +351,76 @@ describe('QwenAIStream', () => {
|
|
349
351
|
]);
|
350
352
|
});
|
351
353
|
});
|
354
|
+
|
355
|
+
describe('transformQwenStream', () => {
|
356
|
+
it('should handle usage chunk', () => {
|
357
|
+
const mockChunk: OpenAI.ChatCompletionChunk = {
|
358
|
+
choices: [],
|
359
|
+
id: 'usage-test-id',
|
360
|
+
model: 'qwen-test-model',
|
361
|
+
object: 'chat.completion.chunk',
|
362
|
+
created: Date.now(),
|
363
|
+
usage: {
|
364
|
+
completion_tokens: 50,
|
365
|
+
prompt_tokens: 100,
|
366
|
+
total_tokens: 150,
|
367
|
+
completion_tokens_details: {}, // Ensure these exist even if empty
|
368
|
+
prompt_tokens_details: {}, // Ensure these exist even if empty
|
369
|
+
},
|
370
|
+
};
|
371
|
+
|
372
|
+
const streamContext: StreamContext = { id: '' };
|
373
|
+
|
374
|
+
const result = transformQwenStream(mockChunk, streamContext);
|
375
|
+
|
376
|
+
expect(result).toEqual({
|
377
|
+
id: 'usage-test-id',
|
378
|
+
type: 'usage',
|
379
|
+
data: {
|
380
|
+
inputTextTokens: 100,
|
381
|
+
outputTextTokens: 50,
|
382
|
+
totalInputTokens: 100,
|
383
|
+
totalOutputTokens: 50,
|
384
|
+
totalTokens: 150,
|
385
|
+
},
|
386
|
+
});
|
387
|
+
|
388
|
+
// Verify streamContext is updated
|
389
|
+
expect(streamContext.usage).toEqual({
|
390
|
+
inputTextTokens: 100,
|
391
|
+
outputTextTokens: 50,
|
392
|
+
totalInputTokens: 100,
|
393
|
+
totalOutputTokens: 50,
|
394
|
+
totalTokens: 150,
|
395
|
+
});
|
396
|
+
});
|
397
|
+
|
398
|
+
it('should handle usage chunk without streamContext', () => {
|
399
|
+
const mockChunk: OpenAI.ChatCompletionChunk = {
|
400
|
+
choices: [],
|
401
|
+
id: 'usage-test-id-no-ctx',
|
402
|
+
model: 'qwen-test-model',
|
403
|
+
object: 'chat.completion.chunk',
|
404
|
+
created: Date.now(),
|
405
|
+
usage: {
|
406
|
+
completion_tokens: 55,
|
407
|
+
prompt_tokens: 105,
|
408
|
+
total_tokens: 160,
|
409
|
+
},
|
410
|
+
};
|
411
|
+
|
412
|
+
const result = transformQwenStream(mockChunk); // No streamContext passed
|
413
|
+
|
414
|
+
expect(result).toEqual({
|
415
|
+
id: 'usage-test-id-no-ctx',
|
416
|
+
type: 'usage',
|
417
|
+
data: {
|
418
|
+
inputTextTokens: 105,
|
419
|
+
outputTextTokens: 55,
|
420
|
+
totalInputTokens: 105,
|
421
|
+
totalOutputTokens: 55,
|
422
|
+
totalTokens: 160,
|
423
|
+
},
|
424
|
+
});
|
425
|
+
});
|
426
|
+
});
|
@@ -4,17 +4,37 @@ import { ChatCompletionContentPart } from 'openai/resources/index.mjs';
|
|
4
4
|
import type { Stream } from 'openai/streaming';
|
5
5
|
|
6
6
|
import { ChatStreamCallbacks } from '../../types';
|
7
|
+
import { convertUsage } from '../usageConverter';
|
7
8
|
import {
|
9
|
+
StreamContext,
|
8
10
|
StreamProtocolChunk,
|
9
11
|
StreamProtocolToolCallChunk,
|
10
12
|
StreamToolCallChunkData,
|
11
13
|
convertIterableToStream,
|
12
14
|
createCallbacksTransformer,
|
13
15
|
createSSEProtocolTransformer,
|
16
|
+
createTokenSpeedCalculator,
|
14
17
|
generateToolCallId,
|
15
18
|
} from './protocol';
|
16
19
|
|
17
|
-
export const transformQwenStream = (
|
20
|
+
export const transformQwenStream = (
|
21
|
+
chunk: OpenAI.ChatCompletionChunk,
|
22
|
+
streamContext?: StreamContext,
|
23
|
+
): StreamProtocolChunk | StreamProtocolChunk[] => {
|
24
|
+
if (Array.isArray(chunk.choices) && chunk.choices.length === 0 && chunk.usage) {
|
25
|
+
const usage = convertUsage({
|
26
|
+
...chunk.usage,
|
27
|
+
completion_tokens_details: chunk.usage.completion_tokens_details || {},
|
28
|
+
prompt_tokens_details: chunk.usage.prompt_tokens_details || {},
|
29
|
+
});
|
30
|
+
|
31
|
+
if (streamContext) {
|
32
|
+
streamContext.usage = usage;
|
33
|
+
}
|
34
|
+
|
35
|
+
return { data: usage, id: chunk.id, type: 'usage' };
|
36
|
+
}
|
37
|
+
|
18
38
|
const item = chunk.choices[0];
|
19
39
|
|
20
40
|
if (!item) {
|
@@ -96,10 +116,14 @@ export const QwenAIStream = (
|
|
96
116
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
97
117
|
{ callbacks, inputStartAt }: { callbacks?: ChatStreamCallbacks; inputStartAt?: number } = {},
|
98
118
|
) => {
|
119
|
+
const streamContext: StreamContext = { id: '' };
|
99
120
|
const readableStream =
|
100
121
|
stream instanceof ReadableStream ? stream : convertIterableToStream(stream);
|
101
122
|
|
102
123
|
return readableStream
|
103
|
-
.pipeThrough(
|
124
|
+
.pipeThrough(
|
125
|
+
createTokenSpeedCalculator(transformQwenStream, { inputStartAt, streamStack: streamContext }),
|
126
|
+
)
|
127
|
+
.pipeThrough(createSSEProtocolTransformer((c) => c, streamContext))
|
104
128
|
.pipeThrough(createCallbacksTransformer(callbacks));
|
105
129
|
};
|
@@ -4,7 +4,7 @@ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
|
4
4
|
export const LobeVolcengineAI = LobeOpenAICompatibleFactory({
|
5
5
|
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
|
6
6
|
debug: {
|
7
|
-
chatCompletion: () => process.env.
|
7
|
+
chatCompletion: () => process.env.DEBUG_VOLCENGINE_CHAT_COMPLETION === '1',
|
8
8
|
},
|
9
9
|
provider: ModelProvider.Volcengine,
|
10
10
|
});
|
@@ -26,9 +26,6 @@ export const getServerGlobalConfig = async () => {
|
|
26
26
|
enabledKey: 'ENABLED_AWS_BEDROCK',
|
27
27
|
modelListKey: 'AWS_BEDROCK_MODEL_LIST',
|
28
28
|
},
|
29
|
-
doubao: {
|
30
|
-
withDeploymentName: true,
|
31
|
-
},
|
32
29
|
giteeai: {
|
33
30
|
enabledKey: 'ENABLED_GITEE_AI',
|
34
31
|
modelListKey: 'GITEE_AI_MODEL_LIST',
|
@@ -1,10 +1,28 @@
|
|
1
1
|
// @vitest-environment node
|
2
|
-
import { describe, expect, it } from 'vitest';
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
3
|
+
|
4
|
+
import { EdgeConfig } from '@/server/modules/EdgeConfig';
|
3
5
|
|
4
6
|
import { AssistantStore } from './index';
|
5
7
|
|
6
8
|
const baseURL = 'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public';
|
9
|
+
|
10
|
+
vi.mock('@/server/modules/EdgeConfig', () => {
|
11
|
+
const EdgeConfigMock = vi.fn();
|
12
|
+
// @ts-expect-error: static mock for isEnabled
|
13
|
+
EdgeConfigMock.isEnabled = vi.fn();
|
14
|
+
EdgeConfigMock.prototype.getAgentRestrictions = vi.fn();
|
15
|
+
return { EdgeConfig: EdgeConfigMock };
|
16
|
+
});
|
17
|
+
|
7
18
|
describe('AssistantStore', () => {
|
19
|
+
beforeEach(() => {
|
20
|
+
vi.restoreAllMocks();
|
21
|
+
vi.clearAllMocks();
|
22
|
+
// @ts-expect-error
|
23
|
+
global.fetch = undefined;
|
24
|
+
});
|
25
|
+
|
8
26
|
it('should return the default index URL when no language is provided', () => {
|
9
27
|
const agentMarket = new AssistantStore();
|
10
28
|
const url = agentMarket['getAgentIndexUrl']();
|
@@ -20,17 +38,13 @@ describe('AssistantStore', () => {
|
|
20
38
|
it('should return the zh-CN URL for zh locale', () => {
|
21
39
|
const agentMarket = new AssistantStore();
|
22
40
|
const url = agentMarket['getAgentIndexUrl']('zh' as any);
|
23
|
-
expect(url).toBe(
|
24
|
-
'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public/index.zh-CN.json',
|
25
|
-
);
|
41
|
+
expect(url).toBe(`${baseURL}/index.zh-CN.json`);
|
26
42
|
});
|
27
43
|
|
28
44
|
it('should return the default URL for en locale', () => {
|
29
45
|
const agentMarket = new AssistantStore();
|
30
46
|
const url = agentMarket['getAgentIndexUrl']('en' as any);
|
31
|
-
expect(url).toBe(
|
32
|
-
'https://registry.npmmirror.com/@lobehub/agents-index/v1/files/public/index.en-US.json',
|
33
|
-
);
|
47
|
+
expect(url).toBe(`${baseURL}/index.en-US.json`);
|
34
48
|
});
|
35
49
|
|
36
50
|
it('should return the base URL if the provided language is not supported', () => {
|
@@ -45,7 +59,7 @@ describe('AssistantStore', () => {
|
|
45
59
|
expect(url).toBe(`${baseURL}/agent-123.en-US.json`);
|
46
60
|
});
|
47
61
|
|
48
|
-
it('should return the agent URL for a
|
62
|
+
it('should return the agent URL for a supported language', () => {
|
49
63
|
const agentMarket = new AssistantStore();
|
50
64
|
const url = agentMarket.getAgentUrl('agent-123', 'zh-CN');
|
51
65
|
expect(url).toBe(`${baseURL}/agent-123.zh-CN.json`);
|
@@ -56,4 +70,123 @@ describe('AssistantStore', () => {
|
|
56
70
|
const url = agentMarket.getAgentUrl('agent-123', 'fr' as any);
|
57
71
|
expect(url).toBe(`${baseURL}/agent-123.json`);
|
58
72
|
});
|
73
|
+
|
74
|
+
it('should return empty agents array with schema version when fetch fails', async () => {
|
75
|
+
global.fetch = vi.fn().mockRejectedValue(new Error('fetch failed'));
|
76
|
+
const store = new AssistantStore();
|
77
|
+
const result = await store.getAgentIndex();
|
78
|
+
expect(result).toEqual({ agents: [], schemaVersion: 1 });
|
79
|
+
});
|
80
|
+
|
81
|
+
it('should handle fetch error and return empty agents with schema version when error.ok is false', async () => {
|
82
|
+
global.fetch = vi.fn().mockResolvedValue({
|
83
|
+
ok: false,
|
84
|
+
text: () => Promise.resolve('Error'),
|
85
|
+
});
|
86
|
+
const store = new AssistantStore();
|
87
|
+
const result = await store.getAgentIndex();
|
88
|
+
expect(result).toEqual({ agents: [], schemaVersion: 1 });
|
89
|
+
});
|
90
|
+
|
91
|
+
it('should filter agents by whitelist when EdgeConfig is enabled', async () => {
|
92
|
+
const mockAgents = {
|
93
|
+
agents: [
|
94
|
+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
|
95
|
+
{ identifier: 'agent2', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
|
96
|
+
],
|
97
|
+
schemaVersion: 1,
|
98
|
+
};
|
99
|
+
|
100
|
+
global.fetch = vi.fn().mockResolvedValue({
|
101
|
+
ok: true,
|
102
|
+
status: 200,
|
103
|
+
json: () => Promise.resolve({ ...mockAgents }),
|
104
|
+
});
|
105
|
+
|
106
|
+
// @ts-expect-error
|
107
|
+
EdgeConfig.isEnabled.mockReturnValue(true);
|
108
|
+
|
109
|
+
const store = new AssistantStore();
|
110
|
+
(EdgeConfig as any).prototype.getAgentRestrictions.mockResolvedValue({
|
111
|
+
whitelist: ['agent1'],
|
112
|
+
blacklist: undefined,
|
113
|
+
});
|
114
|
+
|
115
|
+
const result = await store.getAgentIndex();
|
116
|
+
|
117
|
+
expect(result.agents).toHaveLength(1);
|
118
|
+
expect(result.agents[0].identifier).toBe('agent1');
|
119
|
+
});
|
120
|
+
|
121
|
+
it('should filter agents by blacklist when EdgeConfig is enabled and no whitelist', async () => {
|
122
|
+
const mockAgents = {
|
123
|
+
agents: [
|
124
|
+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
|
125
|
+
{ identifier: 'agent2', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
|
126
|
+
],
|
127
|
+
schemaVersion: 1,
|
128
|
+
};
|
129
|
+
|
130
|
+
global.fetch = vi.fn().mockResolvedValue({
|
131
|
+
ok: true,
|
132
|
+
status: 200,
|
133
|
+
json: () => Promise.resolve({ ...mockAgents }),
|
134
|
+
});
|
135
|
+
|
136
|
+
// @ts-expect-error
|
137
|
+
EdgeConfig.isEnabled.mockReturnValue(true);
|
138
|
+
|
139
|
+
const store = new AssistantStore();
|
140
|
+
(EdgeConfig as any).prototype.getAgentRestrictions.mockResolvedValue({
|
141
|
+
whitelist: undefined,
|
142
|
+
blacklist: ['agent2'],
|
143
|
+
});
|
144
|
+
|
145
|
+
const result = await store.getAgentIndex();
|
146
|
+
|
147
|
+
expect(result.agents).toHaveLength(1);
|
148
|
+
expect(result.agents[0].identifier).toBe('agent1');
|
149
|
+
});
|
150
|
+
|
151
|
+
it('should fallback to default language if fetch returns 404', async () => {
|
152
|
+
const mockAgents = {
|
153
|
+
agents: [
|
154
|
+
{ identifier: 'agent1', meta: {}, author: '', createAt: '', createdAt: '', homepage: '' },
|
155
|
+
],
|
156
|
+
schemaVersion: 1,
|
157
|
+
};
|
158
|
+
|
159
|
+
const fetchMock = vi
|
160
|
+
.fn()
|
161
|
+
.mockResolvedValueOnce({
|
162
|
+
status: 404,
|
163
|
+
ok: false,
|
164
|
+
text: () => Promise.resolve('Not found'),
|
165
|
+
})
|
166
|
+
.mockResolvedValueOnce({
|
167
|
+
status: 200,
|
168
|
+
ok: true,
|
169
|
+
json: () => Promise.resolve({ ...mockAgents }),
|
170
|
+
});
|
171
|
+
|
172
|
+
global.fetch = fetchMock as any;
|
173
|
+
|
174
|
+
// @ts-expect-error
|
175
|
+
EdgeConfig.isEnabled.mockReturnValue(false);
|
176
|
+
|
177
|
+
const store = new AssistantStore();
|
178
|
+
const result = await store.getAgentIndex('zh-CN');
|
179
|
+
expect(result).toEqual(mockAgents);
|
180
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
181
|
+
});
|
182
|
+
|
183
|
+
it('should throw error for unexpected error in getAgentIndex', async () => {
|
184
|
+
global.fetch = vi.fn().mockRejectedValue(new Error('something else'));
|
185
|
+
const store = new AssistantStore();
|
186
|
+
|
187
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
188
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
189
|
+
|
190
|
+
await expect(store.getAgentIndex()).rejects.toThrow('something else');
|
191
|
+
});
|
59
192
|
});
|
package/src/services/chat.ts
CHANGED
package/src/types/aiModel.ts
CHANGED
@@ -131,7 +131,7 @@ export interface AIBaseModelCard {
|
|
131
131
|
|
132
132
|
export interface AiModelConfig {
|
133
133
|
/**
|
134
|
-
* used in azure and
|
134
|
+
* used in azure and volcengine
|
135
135
|
*/
|
136
136
|
deploymentName?: string;
|
137
137
|
|
@@ -241,7 +241,7 @@ export interface AIRealtimeModelCard extends AIBaseModelCard {
|
|
241
241
|
vision?: boolean;
|
242
242
|
};
|
243
243
|
/**
|
244
|
-
* used in azure and
|
244
|
+
* used in azure and volcengine
|
245
245
|
*/
|
246
246
|
deploymentName?: string;
|
247
247
|
maxOutput?: number;
|
package/src/types/aiProvider.ts
CHANGED
@@ -43,7 +43,6 @@ export interface UserKeyVaults extends SearchEngineKeyVaults {
|
|
43
43
|
cloudflare?: CloudflareKeyVault;
|
44
44
|
cohere?: OpenAICompatibleKeyVault;
|
45
45
|
deepseek?: OpenAICompatibleKeyVault;
|
46
|
-
doubao?: OpenAICompatibleKeyVault;
|
47
46
|
fireworksai?: OpenAICompatibleKeyVault;
|
48
47
|
giteeai?: OpenAICompatibleKeyVault;
|
49
48
|
github?: OpenAICompatibleKeyVault;
|
@@ -1,39 +0,0 @@
|
|
1
|
-
'use client';
|
2
|
-
|
3
|
-
import { DoubaoProviderCard } from '@/config/modelProviders';
|
4
|
-
import { ModelProvider } from '@/libs/agent-runtime';
|
5
|
-
import { useUserStore } from '@/store/user';
|
6
|
-
import { modelProviderSelectors } from '@/store/user/selectors';
|
7
|
-
|
8
|
-
import { ProviderItem } from '../../type';
|
9
|
-
import ProviderDetail from '../[id]';
|
10
|
-
|
11
|
-
const providerKey = ModelProvider.Doubao;
|
12
|
-
|
13
|
-
const useProviderCard = (): ProviderItem => {
|
14
|
-
// Get the first model card's deployment name as the check model
|
15
|
-
const checkModel = useUserStore((s) => {
|
16
|
-
const chatModelCards = modelProviderSelectors.getModelCardsById(providerKey)(s);
|
17
|
-
|
18
|
-
if (chatModelCards.length > 0) {
|
19
|
-
return chatModelCards[0].deploymentName;
|
20
|
-
}
|
21
|
-
|
22
|
-
return 'Doubao-lite-4k';
|
23
|
-
});
|
24
|
-
return {
|
25
|
-
...DoubaoProviderCard,
|
26
|
-
checkModel,
|
27
|
-
modelList: {
|
28
|
-
azureDeployName: true,
|
29
|
-
},
|
30
|
-
};
|
31
|
-
};
|
32
|
-
|
33
|
-
const Page = () => {
|
34
|
-
const card = useProviderCard();
|
35
|
-
|
36
|
-
return <ProviderDetail {...card} />;
|
37
|
-
};
|
38
|
-
|
39
|
-
export default Page;
|
@@ -1,65 +0,0 @@
|
|
1
|
-
import { AIChatModelCard } from '@/types/aiModel';
|
2
|
-
|
3
|
-
const doubaoChatModels: AIChatModelCard[] = [
|
4
|
-
{
|
5
|
-
contextWindowTokens: 4096,
|
6
|
-
description:
|
7
|
-
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 4k 上下文窗口的推理和精调。',
|
8
|
-
displayName: 'Doubao Lite 4k',
|
9
|
-
enabled: true,
|
10
|
-
id: 'Doubao-lite-4k',
|
11
|
-
type: 'chat',
|
12
|
-
},
|
13
|
-
{
|
14
|
-
contextWindowTokens: 32_768,
|
15
|
-
description:
|
16
|
-
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 32k 上下文窗口的推理和精调。',
|
17
|
-
displayName: 'Doubao Lite 32k',
|
18
|
-
enabled: true,
|
19
|
-
id: 'Doubao-lite-32k',
|
20
|
-
type: 'chat',
|
21
|
-
},
|
22
|
-
{
|
23
|
-
contextWindowTokens: 128_000,
|
24
|
-
description:
|
25
|
-
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 128k 上下文窗口的推理和精调。',
|
26
|
-
displayName: 'Doubao Lite 128k',
|
27
|
-
enabled: true,
|
28
|
-
id: 'Doubao-lite-128k',
|
29
|
-
type: 'chat',
|
30
|
-
},
|
31
|
-
{
|
32
|
-
contextWindowTokens: 4096,
|
33
|
-
description:
|
34
|
-
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 4k 上下文窗口的推理和精调。',
|
35
|
-
displayName: 'Doubao Pro 4k',
|
36
|
-
enabled: true,
|
37
|
-
id: 'Doubao-pro-4k',
|
38
|
-
type: 'chat',
|
39
|
-
},
|
40
|
-
{
|
41
|
-
config: {
|
42
|
-
deploymentName: 'Doubao-pro-test',
|
43
|
-
},
|
44
|
-
contextWindowTokens: 32_768,
|
45
|
-
description:
|
46
|
-
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 32k 上下文窗口的推理和精调。',
|
47
|
-
displayName: 'Doubao Pro 32k',
|
48
|
-
enabled: true,
|
49
|
-
id: 'Doubao-pro-32k',
|
50
|
-
type: 'chat',
|
51
|
-
},
|
52
|
-
{
|
53
|
-
contextWindowTokens: 128_000,
|
54
|
-
description:
|
55
|
-
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 128k 上下文窗口的推理和精调。',
|
56
|
-
displayName: 'Doubao Pro 128k',
|
57
|
-
enabled: true,
|
58
|
-
id: 'Doubao-pro-128k',
|
59
|
-
type: 'chat',
|
60
|
-
},
|
61
|
-
];
|
62
|
-
|
63
|
-
export const allModels = [...doubaoChatModels];
|
64
|
-
|
65
|
-
export default allModels;
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import { ModelProviderCard } from '@/types/llm';
|
2
|
-
|
3
|
-
// ref https://www.volcengine.com/docs/82379/1330310
|
4
|
-
const Doubao: ModelProviderCard = {
|
5
|
-
chatModels: [],
|
6
|
-
// checkModel: 'Doubao-lite-4k',
|
7
|
-
description:
|
8
|
-
'字节跳动推出的自研大模型。通过字节跳动内部50+业务场景实践验证,每日万亿级tokens大使用量持续打磨,提供多种模态能力,以优质模型效果为企业打造丰富的业务体验。',
|
9
|
-
id: 'doubao',
|
10
|
-
modelsUrl: 'https://www.volcengine.com/product/doubao',
|
11
|
-
name: '豆包',
|
12
|
-
settings: {
|
13
|
-
disableBrowserRequest: true, // CORS error
|
14
|
-
sdkType: 'doubao',
|
15
|
-
// showModelFetcher: false,
|
16
|
-
smoothing: {
|
17
|
-
speed: 2,
|
18
|
-
text: true,
|
19
|
-
},
|
20
|
-
},
|
21
|
-
url: 'https://www.volcengine.com/product/doubao',
|
22
|
-
};
|
23
|
-
|
24
|
-
export default Doubao;
|