@lobehub/chat 1.92.0 → 1.92.1
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 +28 -0
- package/changelog/v1.json +9 -0
- package/package.json +1 -1
- package/src/components/ModelSelect/index.tsx +6 -3
- package/src/config/aiModels/google.ts +25 -0
- package/src/config/aiModels/hunyuan.ts +44 -0
- package/src/config/aiModels/novita.ts +39 -3
- package/src/config/aiModels/openrouter.ts +0 -1
- package/src/config/aiModels/qwen.ts +48 -6
- package/src/config/aiModels/siliconcloud.ts +0 -106
- package/src/store/user/slices/auth/selectors.test.ts +76 -0
- package/src/store/user/slices/auth/selectors.ts +2 -0
- package/src/utils/client/parserPlaceholder.test.ts +66 -77
- package/src/utils/client/parserPlaceholder.ts +3 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,34 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.92.1](https://github.com/lobehub/lobe-chat/compare/v1.92.0...v1.92.1)
|
6
|
+
|
7
|
+
<sup>Released on **2025-06-07**</sup>
|
8
|
+
|
9
|
+
#### 💄 Styles
|
10
|
+
|
11
|
+
- **ModelSelect**: Add responsive layout for mobile devices.
|
12
|
+
- **misc**: Improve `{{username}}` placeholder variable, Update Gemini & Qwen models.
|
13
|
+
|
14
|
+
<br/>
|
15
|
+
|
16
|
+
<details>
|
17
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
18
|
+
|
19
|
+
#### Styles
|
20
|
+
|
21
|
+
- **ModelSelect**: Add responsive layout for mobile devices, closes [#7960](https://github.com/lobehub/lobe-chat/issues/7960) ([cb84c3e](https://github.com/lobehub/lobe-chat/commit/cb84c3e))
|
22
|
+
- **misc**: Improve `{{username}}` placeholder variable, closes [#8100](https://github.com/lobehub/lobe-chat/issues/8100) ([95fd588](https://github.com/lobehub/lobe-chat/commit/95fd588))
|
23
|
+
- **misc**: Update Gemini & Qwen models, closes [#8083](https://github.com/lobehub/lobe-chat/issues/8083) ([6308237](https://github.com/lobehub/lobe-chat/commit/6308237))
|
24
|
+
|
25
|
+
</details>
|
26
|
+
|
27
|
+
<div align="right">
|
28
|
+
|
29
|
+
[](#readme-top)
|
30
|
+
|
31
|
+
</div>
|
32
|
+
|
5
33
|
## [Version 1.92.0](https://github.com/lobehub/lobe-chat/compare/v1.91.3...v1.92.0)
|
6
34
|
|
7
35
|
<sup>Released on **2025-06-06**</sup>
|
package/changelog/v1.json
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.92.
|
3
|
+
"version": "1.92.1",
|
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",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { IconAvatarProps, ModelIcon, ProviderIcon } from '@lobehub/icons';
|
2
2
|
import { Avatar, Icon, Tag, Tooltip } from '@lobehub/ui';
|
3
3
|
import { Typography } from 'antd';
|
4
|
-
import { createStyles } from 'antd-style';
|
4
|
+
import { createStyles, useResponsive } from 'antd-style';
|
5
5
|
import {
|
6
6
|
Infinity,
|
7
7
|
AtomIcon,
|
@@ -167,17 +167,20 @@ interface ModelItemRenderProps extends ChatModelCard {
|
|
167
167
|
}
|
168
168
|
|
169
169
|
export const ModelItemRender = memo<ModelItemRenderProps>(({ showInfoTag = true, ...model }) => {
|
170
|
+
const { mobile } = useResponsive();
|
170
171
|
return (
|
171
172
|
<Flexbox
|
172
173
|
align={'center'}
|
173
174
|
gap={32}
|
174
175
|
horizontal
|
175
176
|
justify={'space-between'}
|
176
|
-
style={{ overflow: 'hidden', position: 'relative' }}
|
177
|
+
style={{ overflow: 'hidden', position: 'relative', width: mobile ? '80vw' : 'auto' }}
|
177
178
|
>
|
178
179
|
<Flexbox align={'center'} gap={8} horizontal style={{ overflow: 'hidden' }}>
|
179
180
|
<ModelIcon model={model.id} size={20} />
|
180
|
-
<Typography.Text
|
181
|
+
<Typography.Text style={mobile ? { overflowX: 'auto', whiteSpace: 'nowrap' } : {}}>
|
182
|
+
{model.displayName || model.id}
|
183
|
+
</Typography.Text>
|
181
184
|
</Flexbox>
|
182
185
|
{showInfoTag && <ModelInfoTags {...model} />}
|
183
186
|
</Flexbox>
|
@@ -1,6 +1,31 @@
|
|
1
1
|
import { AIChatModelCard } from '@/types/aiModel';
|
2
2
|
|
3
3
|
const googleChatModels: AIChatModelCard[] = [
|
4
|
+
{
|
5
|
+
abilities: {
|
6
|
+
functionCall: true,
|
7
|
+
reasoning: true,
|
8
|
+
search: true,
|
9
|
+
vision: true,
|
10
|
+
},
|
11
|
+
contextWindowTokens: 1_048_576 + 65_536,
|
12
|
+
description:
|
13
|
+
'Gemini 2.5 Pro Preview 是 Google 最先进的思维模型,能够对代码、数学和STEM领域的复杂问题进行推理,以及使用长上下文分析大型数据集、代码库和文档。',
|
14
|
+
displayName: 'Gemini 2.5 Pro Preview 06-05 (Paid)',
|
15
|
+
id: 'gemini-2.5-pro-preview-06-05',
|
16
|
+
maxOutput: 65_536,
|
17
|
+
pricing: {
|
18
|
+
input: 1.25, // prompts <= 200k tokens
|
19
|
+
output: 10, // prompts <= 200k tokens
|
20
|
+
},
|
21
|
+
releasedAt: '2025-06-05',
|
22
|
+
settings: {
|
23
|
+
extendParams: ['enableReasoning', 'reasoningBudgetToken'],
|
24
|
+
searchImpl: 'params',
|
25
|
+
searchProvider: 'google',
|
26
|
+
},
|
27
|
+
type: 'chat',
|
28
|
+
},
|
4
29
|
{
|
5
30
|
abilities: {
|
6
31
|
functionCall: true,
|
@@ -25,6 +25,28 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
25
25
|
},
|
26
26
|
type: 'chat',
|
27
27
|
},
|
28
|
+
{
|
29
|
+
abilities: {
|
30
|
+
reasoning: true,
|
31
|
+
search: true,
|
32
|
+
},
|
33
|
+
contextWindowTokens: 92_000,
|
34
|
+
description:
|
35
|
+
'优化文本创作、作文写作,优化代码前端、数学、逻辑推理等理科能力,提升指令遵循能力。',
|
36
|
+
displayName: 'Hunyuan T1 20250529',
|
37
|
+
id: 'hunyuan-t1-20250529',
|
38
|
+
maxOutput: 64_000,
|
39
|
+
pricing: {
|
40
|
+
currency: 'CNY',
|
41
|
+
input: 1,
|
42
|
+
output: 4,
|
43
|
+
},
|
44
|
+
releasedAt: '2025-05-29',
|
45
|
+
settings: {
|
46
|
+
searchImpl: 'params',
|
47
|
+
},
|
48
|
+
type: 'chat',
|
49
|
+
},
|
28
50
|
{
|
29
51
|
abilities: {
|
30
52
|
reasoning: true,
|
@@ -258,6 +280,28 @@ const hunyuanChatModels: AIChatModelCard[] = [
|
|
258
280
|
},
|
259
281
|
type: 'chat',
|
260
282
|
},
|
283
|
+
{
|
284
|
+
abilities: {
|
285
|
+
functionCall: true,
|
286
|
+
search: true,
|
287
|
+
},
|
288
|
+
contextWindowTokens: 44_000,
|
289
|
+
description:
|
290
|
+
'预训练底座升级,写作、阅读理解能力提升,较大幅度提升代码和理科能力,复杂指令遵循等持续提升。',
|
291
|
+
displayName: 'Hunyuan TurboS 20250604',
|
292
|
+
id: 'hunyuan-turbos-20250604',
|
293
|
+
maxOutput: 16_000,
|
294
|
+
pricing: {
|
295
|
+
currency: 'CNY',
|
296
|
+
input: 0.8,
|
297
|
+
output: 2,
|
298
|
+
},
|
299
|
+
releasedAt: '2025-06-04',
|
300
|
+
settings: {
|
301
|
+
searchImpl: 'params',
|
302
|
+
},
|
303
|
+
type: 'chat',
|
304
|
+
},
|
261
305
|
{
|
262
306
|
abilities: {
|
263
307
|
functionCall: true,
|
@@ -43,6 +43,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
43
43
|
type: 'chat',
|
44
44
|
},
|
45
45
|
{
|
46
|
+
abilities: {
|
47
|
+
functionCall: true,
|
48
|
+
},
|
46
49
|
contextWindowTokens: 131_072,
|
47
50
|
displayName: 'Llama 3.3 70B Instruct',
|
48
51
|
id: 'meta-llama/llama-3.3-70b-instruct',
|
@@ -63,6 +66,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
63
66
|
type: 'chat',
|
64
67
|
},
|
65
68
|
{
|
69
|
+
abilities: {
|
70
|
+
functionCall: true,
|
71
|
+
},
|
66
72
|
contextWindowTokens: 131_072,
|
67
73
|
displayName: 'Llama 4 Scout 17B Instruct',
|
68
74
|
enabled: true,
|
@@ -74,6 +80,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
74
80
|
type: 'chat',
|
75
81
|
},
|
76
82
|
{
|
83
|
+
abilities: {
|
84
|
+
functionCall: true,
|
85
|
+
},
|
77
86
|
contextWindowTokens: 1_048_576,
|
78
87
|
displayName: 'Llama 4 Maverick 17B Instruct',
|
79
88
|
enabled: true,
|
@@ -129,7 +138,7 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
129
138
|
type: 'chat',
|
130
139
|
},
|
131
140
|
{
|
132
|
-
contextWindowTokens:
|
141
|
+
contextWindowTokens: 60_288,
|
133
142
|
description: 'Mistral Nemo 是多语言支持和高性能编程的7.3B参数模型。',
|
134
143
|
displayName: 'Mistral Nemo',
|
135
144
|
id: 'mistralai/mistral-nemo',
|
@@ -205,6 +214,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
205
214
|
type: 'chat',
|
206
215
|
},
|
207
216
|
{
|
217
|
+
abilities: {
|
218
|
+
functionCall: true,
|
219
|
+
},
|
208
220
|
contextWindowTokens: 64_000,
|
209
221
|
displayName: 'Deepseek V3 Turbo',
|
210
222
|
id: 'deepseek/deepseek-v3-turbo',
|
@@ -215,6 +227,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
215
227
|
type: 'chat',
|
216
228
|
},
|
217
229
|
{
|
230
|
+
abilities: {
|
231
|
+
functionCall: true,
|
232
|
+
},
|
218
233
|
contextWindowTokens: 128_000,
|
219
234
|
displayName: 'Deepseek V3 0324',
|
220
235
|
enabled: true,
|
@@ -242,7 +257,6 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
242
257
|
},
|
243
258
|
{
|
244
259
|
abilities: {
|
245
|
-
functionCall: true,
|
246
260
|
reasoning: true,
|
247
261
|
},
|
248
262
|
contextWindowTokens: 128_000,
|
@@ -256,6 +270,7 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
256
270
|
},
|
257
271
|
{
|
258
272
|
abilities: {
|
273
|
+
functionCall: true,
|
259
274
|
reasoning: true,
|
260
275
|
},
|
261
276
|
contextWindowTokens: 64_000,
|
@@ -330,6 +345,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
330
345
|
type: 'chat',
|
331
346
|
},
|
332
347
|
{
|
348
|
+
abilities: {
|
349
|
+
functionCall: true,
|
350
|
+
},
|
333
351
|
contextWindowTokens: 32_000,
|
334
352
|
displayName: 'Qwen2.5 72B Instruct',
|
335
353
|
id: 'qwen/qwen-2.5-72b-instruct',
|
@@ -373,7 +391,7 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
373
391
|
abilities: {
|
374
392
|
vision: true,
|
375
393
|
},
|
376
|
-
contextWindowTokens:
|
394
|
+
contextWindowTokens: 32_768,
|
377
395
|
displayName: 'Qwen2.5 VL 72B Instruct',
|
378
396
|
enabled: true,
|
379
397
|
id: 'qwen/qwen2.5-vl-72b-instruct',
|
@@ -394,6 +412,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
394
412
|
type: 'chat',
|
395
413
|
},
|
396
414
|
{
|
415
|
+
abilities: {
|
416
|
+
functionCall: true,
|
417
|
+
},
|
397
418
|
contextWindowTokens: 32_768,
|
398
419
|
displayName: 'Llama 3.2 3B Instruct',
|
399
420
|
id: 'meta-llama/llama-3.2-3b-instruct',
|
@@ -434,6 +455,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
434
455
|
type: 'chat',
|
435
456
|
},
|
436
457
|
{
|
458
|
+
abilities: {
|
459
|
+
functionCall: true,
|
460
|
+
},
|
437
461
|
contextWindowTokens: 32_000,
|
438
462
|
displayName: 'GLM 4 9B 0414',
|
439
463
|
id: 'thudm/glm-4-9b-0414',
|
@@ -444,6 +468,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
444
468
|
type: 'chat',
|
445
469
|
},
|
446
470
|
{
|
471
|
+
abilities: {
|
472
|
+
functionCall: true,
|
473
|
+
},
|
447
474
|
contextWindowTokens: 32_000,
|
448
475
|
displayName: 'GLM Z1 9B 0414',
|
449
476
|
id: 'thudm/glm-z1-9b-0414',
|
@@ -454,6 +481,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
454
481
|
type: 'chat',
|
455
482
|
},
|
456
483
|
{
|
484
|
+
abilities: {
|
485
|
+
functionCall: true,
|
486
|
+
},
|
457
487
|
contextWindowTokens: 32_000,
|
458
488
|
displayName: 'GLM Z1 32B 0414',
|
459
489
|
id: 'thudm/glm-z1-32b-0414',
|
@@ -464,6 +494,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
464
494
|
type: 'chat',
|
465
495
|
},
|
466
496
|
{
|
497
|
+
abilities: {
|
498
|
+
functionCall: true,
|
499
|
+
},
|
467
500
|
contextWindowTokens: 32_000,
|
468
501
|
displayName: 'GLM 4 32B 0414',
|
469
502
|
id: 'thudm/glm-4-32b-0414',
|
@@ -474,6 +507,9 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
474
507
|
type: 'chat',
|
475
508
|
},
|
476
509
|
{
|
510
|
+
abilities: {
|
511
|
+
functionCall: true,
|
512
|
+
},
|
477
513
|
contextWindowTokens: 32_000,
|
478
514
|
displayName: 'GLM Z1 Rumination 32B 0414',
|
479
515
|
id: 'thudm/glm-z1-rumination-32b-0414',
|
@@ -59,7 +59,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
59
59
|
contextWindowTokens: 131_072,
|
60
60
|
description:
|
61
61
|
'Qwen3是一款能力大幅提升的新一代通义千问大模型,在推理、通用、Agent和多语言等多个核心能力上均达到业界领先水平,并支持思考模式切换。',
|
62
|
-
displayName: 'Qwen3 30B',
|
62
|
+
displayName: 'Qwen3 30B A3B',
|
63
63
|
enabled: true,
|
64
64
|
id: 'qwen3-30b-a3b',
|
65
65
|
maxOutput: 8192,
|
@@ -543,7 +543,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
543
543
|
config: {
|
544
544
|
deploymentName: 'qvq-max-latest',
|
545
545
|
},
|
546
|
-
contextWindowTokens:
|
546
|
+
contextWindowTokens: 131_072,
|
547
547
|
description:
|
548
548
|
'通义千问QVQ视觉推理模型,支持视觉输入及思维链输出,在数学、编程、视觉分析、创作以及通用任务上都表现了更强的能力。',
|
549
549
|
displayName: 'QVQ Max',
|
@@ -555,7 +555,30 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
555
555
|
input: 8,
|
556
556
|
output: 32,
|
557
557
|
},
|
558
|
-
releasedAt: '2025-
|
558
|
+
releasedAt: '2025-05-15',
|
559
|
+
type: 'chat',
|
560
|
+
},
|
561
|
+
{
|
562
|
+
abilities: {
|
563
|
+
reasoning: true,
|
564
|
+
vision: true,
|
565
|
+
},
|
566
|
+
config: {
|
567
|
+
deploymentName: 'qvq-plus-latest',
|
568
|
+
},
|
569
|
+
contextWindowTokens: 131_072,
|
570
|
+
description:
|
571
|
+
'视觉推理模型。支持视觉输入及思维链输出,继qvq-max模型后推出的plus版本,相较于qvq-max模型,qvq-plus系列模型推理速度更快,效果和成本更均衡。',
|
572
|
+
displayName: 'QVQ Plus',
|
573
|
+
id: 'qvq-plus',
|
574
|
+
maxOutput: 8192,
|
575
|
+
organization: 'Qwen',
|
576
|
+
pricing: {
|
577
|
+
currency: 'CNY',
|
578
|
+
input: 2,
|
579
|
+
output: 5,
|
580
|
+
},
|
581
|
+
releasedAt: '2025-05-15',
|
559
582
|
type: 'chat',
|
560
583
|
},
|
561
584
|
{
|
@@ -795,9 +818,28 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
795
818
|
abilities: {
|
796
819
|
reasoning: true,
|
797
820
|
},
|
798
|
-
contextWindowTokens:
|
821
|
+
contextWindowTokens: 65_536,
|
822
|
+
description:
|
823
|
+
'685B 满血版模型,2025年5月28日发布。DeepSeek-R1 在后训练阶段大规模使用了强化学习技术,在仅有极少标注数据的情况下,极大提升了模型推理能力。在数学、代码、自然语言推理等任务上,性能较高,能力较强。',
|
824
|
+
displayName: 'DeepSeek R1 0528',
|
825
|
+
id: 'deepseek-r1-0528',
|
826
|
+
maxOutput: 8192,
|
827
|
+
organization: 'DeepSeek',
|
828
|
+
pricing: {
|
829
|
+
currency: 'CNY',
|
830
|
+
input: 4,
|
831
|
+
output: 16,
|
832
|
+
},
|
833
|
+
releasedAt: '2025-05-28',
|
834
|
+
type: 'chat',
|
835
|
+
},
|
836
|
+
{
|
837
|
+
abilities: {
|
838
|
+
reasoning: true,
|
839
|
+
},
|
840
|
+
contextWindowTokens: 65_536,
|
799
841
|
description:
|
800
|
-
'DeepSeek-R1 在后训练阶段大规模使用了强化学习技术,在仅有极少标注数据的情况下,极大提升了模型推理能力。在数学、代码、自然语言推理等任务上,性能较高,能力较强。',
|
842
|
+
'671B 满血版模型,2025年1月20日发布。DeepSeek-R1 在后训练阶段大规模使用了强化学习技术,在仅有极少标注数据的情况下,极大提升了模型推理能力。在数学、代码、自然语言推理等任务上,性能较高,能力较强。',
|
801
843
|
displayName: 'DeepSeek R1',
|
802
844
|
id: 'deepseek-r1',
|
803
845
|
maxOutput: 8192,
|
@@ -811,7 +853,7 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
811
853
|
type: 'chat',
|
812
854
|
},
|
813
855
|
{
|
814
|
-
contextWindowTokens:
|
856
|
+
contextWindowTokens: 65_536,
|
815
857
|
description:
|
816
858
|
'DeepSeek-V3 为自研 MoE 模型,671B 参数,激活 37B,在 14.8T token 上进行了预训练,在长文本、代码、数学、百科、中文能力上表现优秀。',
|
817
859
|
displayName: 'DeepSeek V3',
|
@@ -215,7 +215,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
215
215
|
},
|
216
216
|
{
|
217
217
|
abilities: {
|
218
|
-
functionCall: true,
|
219
218
|
reasoning: true,
|
220
219
|
},
|
221
220
|
contextWindowTokens: 131_072,
|
@@ -381,23 +380,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
381
380
|
},
|
382
381
|
type: 'chat',
|
383
382
|
},
|
384
|
-
{
|
385
|
-
abilities: {
|
386
|
-
functionCall: true,
|
387
|
-
reasoning: true,
|
388
|
-
},
|
389
|
-
contextWindowTokens: 131_072,
|
390
|
-
description:
|
391
|
-
'DeepSeek-R1-Distill-Qwen-1.5B 是基于 Qwen2.5-Math-1.5B 通过知识蒸馏得到的模型。该模型使用 DeepSeek-R1 生成的 80 万个精选样本进行微调,在多个基准测试中展现出不错的性能。作为一个轻量级模型,在 MATH-500 上达到了 83.9% 的准确率,在 AIME 2024 上达到了 28.9% 的通过率,在 CodeForces 上获得了 954 的评分,显示出超出其参数规模的推理能力。',
|
392
|
-
displayName: 'DeepSeek-R1-Distill-Qwen-1.5B (Free)',
|
393
|
-
id: 'deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B', // 将于 2025-06-05 下线
|
394
|
-
pricing: {
|
395
|
-
currency: 'CNY',
|
396
|
-
input: 0,
|
397
|
-
output: 0,
|
398
|
-
},
|
399
|
-
type: 'chat',
|
400
|
-
},
|
401
383
|
{
|
402
384
|
abilities: {
|
403
385
|
functionCall: true,
|
@@ -415,23 +397,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
415
397
|
},
|
416
398
|
type: 'chat',
|
417
399
|
},
|
418
|
-
{
|
419
|
-
abilities: {
|
420
|
-
functionCall: true,
|
421
|
-
reasoning: true,
|
422
|
-
},
|
423
|
-
contextWindowTokens: 131_072,
|
424
|
-
description:
|
425
|
-
'DeepSeek-R1-Distill-Qwen-1.5B 是基于 Qwen2.5-Math-1.5B 通过知识蒸馏得到的模型。该模型使用 DeepSeek-R1 生成的 80 万个精选样本进行微调,在多个基准测试中展现出不错的性能。作为一个轻量级模型,在 MATH-500 上达到了 83.9% 的准确率,在 AIME 2024 上达到了 28.9% 的通过率,在 CodeForces 上获得了 954 的评分,显示出超出其参数规模的推理能力。',
|
426
|
-
displayName: 'DeepSeek-R1-Distill-Qwen-1.5B (Pro)',
|
427
|
-
id: 'Pro/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B', // 将于 2025-06-05 下线
|
428
|
-
pricing: {
|
429
|
-
currency: 'CNY',
|
430
|
-
input: 0.14,
|
431
|
-
output: 0.14,
|
432
|
-
},
|
433
|
-
type: 'chat',
|
434
|
-
},
|
435
400
|
{
|
436
401
|
abilities: {
|
437
402
|
functionCall: true,
|
@@ -649,32 +614,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
649
614
|
},
|
650
615
|
type: 'chat',
|
651
616
|
},
|
652
|
-
{
|
653
|
-
contextWindowTokens: 32_768,
|
654
|
-
description:
|
655
|
-
'Qwen2-1.5B-Instruct 是 Qwen2 系列中的指令微调大语言模型,参数规模为 1.5B。该模型基于 Transformer 架构,采用了 SwiGLU 激活函数、注意力 QKV 偏置和组查询注意力等技术。它在语言理解、生成、多语言能力、编码、数学和推理等多个基准测试中表现出色,超越了大多数开源模型。与 Qwen1.5-1.8B-Chat 相比,Qwen2-1.5B-Instruct 在 MMLU、HumanEval、GSM8K、C-Eval 和 IFEval 等测试中均显示出显著的性能提升,尽管参数量略少',
|
656
|
-
displayName: 'Qwen2 1.5B Instruct (Free)',
|
657
|
-
id: 'Qwen/Qwen2-1.5B-Instruct', // 将于 2025-06-05 下线
|
658
|
-
pricing: {
|
659
|
-
currency: 'CNY',
|
660
|
-
input: 0,
|
661
|
-
output: 0,
|
662
|
-
},
|
663
|
-
type: 'chat',
|
664
|
-
},
|
665
|
-
{
|
666
|
-
contextWindowTokens: 32_768,
|
667
|
-
description:
|
668
|
-
'Qwen2-1.5B-Instruct 是 Qwen2 系列中的指令微调大语言模型,参数规模为 1.5B。该模型基于 Transformer 架构,采用了 SwiGLU 激活函数、注意力 QKV 偏置和组查询注意力等技术。它在语言理解、生成、多语言能力、编码、数学和推理等多个基准测试中表现出色,超越了大多数开源模型。与 Qwen1.5-1.8B-Chat 相比,Qwen2-1.5B-Instruct 在 MMLU、HumanEval、GSM8K、C-Eval 和 IFEval 等测试中均显示出显著的性能提升,尽管参数量略少',
|
669
|
-
displayName: 'Qwen2 1.5B Instruct (Pro)',
|
670
|
-
id: 'Pro/Qwen/Qwen2-1.5B-Instruct', // 将于 2025-06-05 下线
|
671
|
-
pricing: {
|
672
|
-
currency: 'CNY',
|
673
|
-
input: 0.14,
|
674
|
-
output: 0.14,
|
675
|
-
},
|
676
|
-
type: 'chat',
|
677
|
-
},
|
678
617
|
{
|
679
618
|
contextWindowTokens: 32_768,
|
680
619
|
description:
|
@@ -701,22 +640,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
701
640
|
},
|
702
641
|
type: 'chat',
|
703
642
|
},
|
704
|
-
{
|
705
|
-
abilities: {
|
706
|
-
vision: true,
|
707
|
-
},
|
708
|
-
contextWindowTokens: 32_768,
|
709
|
-
description:
|
710
|
-
'Qwen2-VL-7B-Instruct 是 Qwen-VL 模型的最新迭代版本,在视觉理解基准测试中达到了最先进的性能,包括 MathVista、DocVQA、RealWorldQA 和 MTVQA 等。Qwen2-VL 能够用于高质量的基于视频的问答、对话和内容创作,还具备复杂推理和决策能力,可以与移动设备、机器人等集成,基于视觉环境和文本指令进行自动操作。除了英语和中文,Qwen2-VL 现在还支持理解图像中不同语言的文本,包括大多数欧洲语言、日语、韩语、阿拉伯语和越南语等',
|
711
|
-
displayName: 'Qwen2 VL 7B Instruct (Pro)',
|
712
|
-
id: 'Pro/Qwen/Qwen2-VL-7B-Instruct', // 将于 2025-06-05 下线
|
713
|
-
pricing: {
|
714
|
-
currency: 'CNY',
|
715
|
-
input: 0.35,
|
716
|
-
output: 0.35,
|
717
|
-
},
|
718
|
-
type: 'chat',
|
719
|
-
},
|
720
643
|
{
|
721
644
|
abilities: {
|
722
645
|
vision: true,
|
@@ -797,22 +720,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
797
720
|
},
|
798
721
|
type: 'chat',
|
799
722
|
},
|
800
|
-
{
|
801
|
-
abilities: {
|
802
|
-
functionCall: true,
|
803
|
-
},
|
804
|
-
contextWindowTokens: 32_768,
|
805
|
-
description:
|
806
|
-
'InternLM2.5-20B-Chat 是一个开源的大规模对话模型,基于 InternLM2 架构开发。该模型拥有 200 亿参数,在数学推理方面表现出色,超越了同量级的 Llama3 和 Gemma2-27B 模型。InternLM2.5-20B-Chat 在工具调用能力方面有显著提升,支持从上百个网页收集信息进行分析推理,并具备更强的指令理解、工具选择和结果反思能力。它适用于构建复杂智能体,可进行多轮工具调用以完成复杂任务',
|
807
|
-
displayName: 'InternLM2.5 20B Chat',
|
808
|
-
id: 'internlm/internlm2_5-20b-chat', // 将于 2025-06-05 下线
|
809
|
-
pricing: {
|
810
|
-
currency: 'CNY',
|
811
|
-
input: 1,
|
812
|
-
output: 1,
|
813
|
-
},
|
814
|
-
type: 'chat',
|
815
|
-
},
|
816
723
|
{
|
817
724
|
abilities: {
|
818
725
|
functionCall: true,
|
@@ -845,19 +752,6 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
845
752
|
},
|
846
753
|
type: 'chat',
|
847
754
|
},
|
848
|
-
{
|
849
|
-
contextWindowTokens: 32_768,
|
850
|
-
description:
|
851
|
-
'ChatGLM3-6B 是 ChatGLM 系列的开源模型,由智谱 AI 开发。该模型保留了前代模型的优秀特性,如对话流畅和部署门槛低,同时引入了新的特性。它采用了更多样的训练数据、更充分的训练步数和更合理的训练策略,在 10B 以下的预训练模型中表现出色。ChatGLM3-6B 支持多轮对话、工具调用、代码执行和 Agent 任务等复杂场景。除对话模型外,还开源了基础模型 ChatGLM-6B-Base 和长文本对话模型 ChatGLM3-6B-32K。该模型对学术研究完全开放,在登记后也允许免费商业使用',
|
852
|
-
displayName: 'ChatGLM3 6B (Free)',
|
853
|
-
id: 'THUDM/chatglm3-6b', // 将于 2025-06-05 下线
|
854
|
-
pricing: {
|
855
|
-
currency: 'CNY',
|
856
|
-
input: 0,
|
857
|
-
output: 0,
|
858
|
-
},
|
859
|
-
type: 'chat',
|
860
|
-
},
|
861
755
|
];
|
862
756
|
|
863
757
|
export const allModels = [...siliconcloudChatModels];
|
@@ -33,6 +33,82 @@ afterEach(() => {
|
|
33
33
|
});
|
34
34
|
|
35
35
|
describe('userProfileSelectors', () => {
|
36
|
+
describe('displayUserName', () => {
|
37
|
+
it('should return default username when auth is disabled and not desktop', () => {
|
38
|
+
enableAuth = false;
|
39
|
+
isDesktop = false;
|
40
|
+
|
41
|
+
const store: UserStore = {
|
42
|
+
isSignedIn: false,
|
43
|
+
user: null,
|
44
|
+
enableAuth: () => false,
|
45
|
+
} as unknown as UserStore;
|
46
|
+
|
47
|
+
expect(userProfileSelectors.displayUserName(store)).toBe('LobeChat');
|
48
|
+
});
|
49
|
+
|
50
|
+
it('should return user username when auth is disabled and is desktop', () => {
|
51
|
+
enableAuth = false;
|
52
|
+
isDesktop = true;
|
53
|
+
|
54
|
+
const store: UserStore = {
|
55
|
+
isSignedIn: false,
|
56
|
+
user: { username: 'johndoe' },
|
57
|
+
enableAuth: () => false,
|
58
|
+
} as unknown as UserStore;
|
59
|
+
|
60
|
+
expect(userProfileSelectors.displayUserName(store)).toBe('johndoe');
|
61
|
+
});
|
62
|
+
|
63
|
+
it('should return user username when signed in', () => {
|
64
|
+
const store: UserStore = {
|
65
|
+
isSignedIn: true,
|
66
|
+
user: { username: 'johndoe' },
|
67
|
+
enableAuth: () => true,
|
68
|
+
} as UserStore;
|
69
|
+
|
70
|
+
expect(userProfileSelectors.displayUserName(store)).toBe('johndoe');
|
71
|
+
});
|
72
|
+
|
73
|
+
it('should return email when signed in but username is not existed in UserStore', () => {
|
74
|
+
const store: UserStore = {
|
75
|
+
isSignedIn: true,
|
76
|
+
user: { email: 'demo@lobehub.com' },
|
77
|
+
enableAuth: () => true,
|
78
|
+
} as UserStore;
|
79
|
+
|
80
|
+
expect(userProfileSelectors.displayUserName(store)).toBe('demo@lobehub.com');
|
81
|
+
});
|
82
|
+
|
83
|
+
it('should return "anonymous" when not signed in', () => {
|
84
|
+
const store: UserStore = {
|
85
|
+
enableAuth: () => true,
|
86
|
+
isSignedIn: false,
|
87
|
+
user: null,
|
88
|
+
} as unknown as UserStore;
|
89
|
+
|
90
|
+
expect(userProfileSelectors.displayUserName(store)).toBe('anonymous');
|
91
|
+
});
|
92
|
+
});
|
93
|
+
|
94
|
+
describe('email', () => {
|
95
|
+
it('should return user email if exist', () => {
|
96
|
+
const store: UserStore = {
|
97
|
+
user: { email: 'demo@lobehub.com' },
|
98
|
+
} as UserStore;
|
99
|
+
|
100
|
+
expect(userProfileSelectors.email(store)).toBe('demo@lobehub.com');
|
101
|
+
});
|
102
|
+
|
103
|
+
it('should return empty string if not exist', () => {
|
104
|
+
const store: UserStore = {
|
105
|
+
user: { email: undefined },
|
106
|
+
} as UserStore;
|
107
|
+
|
108
|
+
expect(userProfileSelectors.email(store)).toBe('');
|
109
|
+
});
|
110
|
+
});
|
111
|
+
|
36
112
|
describe('fullName', () => {
|
37
113
|
it('should return user fullName if exist', () => {
|
38
114
|
const store: UserStore = {
|
@@ -36,6 +36,8 @@ const username = (s: UserStore) => {
|
|
36
36
|
};
|
37
37
|
|
38
38
|
export const userProfileSelectors = {
|
39
|
+
displayUserName: (s: UserStore): string => username(s) || s.user?.email || '',
|
40
|
+
email: (s: UserStore): string => s.user?.email || '',
|
39
41
|
fullName: (s: UserStore): string => s.user?.fullName || '',
|
40
42
|
nickName,
|
41
43
|
userAvatar: (s: UserStore): string => s.user?.avatar || '',
|
@@ -1,35 +1,36 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
2
|
+
|
3
|
+
import { VARIABLE_GENERATORS, parsePlaceholderVariablesMessages } from './parserPlaceholder';
|
3
4
|
|
4
5
|
// Mock dependencies
|
5
6
|
vi.mock('@/utils/uuid', () => ({
|
6
|
-
uuid: () => 'mocked-uuid-12345'
|
7
|
+
uuid: () => 'mocked-uuid-12345',
|
7
8
|
}));
|
8
9
|
|
9
10
|
vi.mock('@/store/user', () => ({
|
10
11
|
useUserStore: {
|
11
|
-
getState: () => ({})
|
12
|
-
}
|
12
|
+
getState: () => ({}),
|
13
|
+
},
|
13
14
|
}));
|
14
15
|
|
15
16
|
vi.mock('@/store/user/selectors', () => ({
|
16
17
|
userProfileSelectors: {
|
18
|
+
displayUserName: () => 'testuser',
|
17
19
|
nickName: () => 'Test User',
|
18
|
-
|
19
|
-
|
20
|
-
}
|
20
|
+
fullName: () => 'Test Full Name',
|
21
|
+
},
|
21
22
|
}));
|
22
23
|
|
23
24
|
vi.mock('@/store/agent/store', () => ({
|
24
|
-
getAgentStoreState: () => ({})
|
25
|
+
getAgentStoreState: () => ({}),
|
25
26
|
}));
|
26
27
|
|
27
28
|
vi.mock('@/store/agent/selectors', () => ({
|
28
29
|
agentChatConfigSelectors: {
|
29
30
|
currentChatConfig: () => ({
|
30
|
-
inputTemplate: 'Hello {{username}}!'
|
31
|
-
})
|
32
|
-
}
|
31
|
+
inputTemplate: 'Hello {{username}}!',
|
32
|
+
}),
|
33
|
+
},
|
33
34
|
}));
|
34
35
|
|
35
36
|
describe('parsePlaceholderVariablesMessages', () => {
|
@@ -52,8 +53,8 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
52
53
|
const messages = [
|
53
54
|
{
|
54
55
|
id: '1',
|
55
|
-
content: 'Hello {{username}}, today is {{date}}'
|
56
|
-
}
|
56
|
+
content: 'Hello {{username}}, today is {{date}}',
|
57
|
+
},
|
57
58
|
];
|
58
59
|
|
59
60
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -66,8 +67,8 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
66
67
|
const messages = [
|
67
68
|
{
|
68
69
|
id: '1',
|
69
|
-
content: 'Time: {{time}}, Date: {{date}}, User: {{nickname}}'
|
70
|
-
}
|
70
|
+
content: 'Time: {{time}}, Date: {{date}}, User: {{nickname}}',
|
71
|
+
},
|
71
72
|
];
|
72
73
|
|
73
74
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -81,8 +82,8 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
81
82
|
{
|
82
83
|
id: '1',
|
83
84
|
role: 'user',
|
84
|
-
content: 'Hello {{username}}'
|
85
|
-
}
|
85
|
+
content: 'Hello {{username}}',
|
86
|
+
},
|
86
87
|
];
|
87
88
|
|
88
89
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -90,7 +91,7 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
90
91
|
expect(result[0]).toEqual({
|
91
92
|
id: '1',
|
92
93
|
role: 'user',
|
93
|
-
content: 'Hello testuser'
|
94
|
+
content: 'Hello testuser',
|
94
95
|
});
|
95
96
|
});
|
96
97
|
});
|
@@ -103,14 +104,14 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
103
104
|
content: [
|
104
105
|
{
|
105
106
|
type: 'text',
|
106
|
-
text: 'Hello {{username}}'
|
107
|
+
text: 'Hello {{username}}',
|
107
108
|
},
|
108
109
|
{
|
109
110
|
type: 'image_url',
|
110
|
-
image_url: 'image.jpg'
|
111
|
-
}
|
112
|
-
]
|
113
|
-
}
|
111
|
+
image_url: 'image.jpg',
|
112
|
+
},
|
113
|
+
],
|
114
|
+
},
|
114
115
|
];
|
115
116
|
|
116
117
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -118,7 +119,7 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
118
119
|
expect(result[0].content[0].text).toBe('Hello testuser');
|
119
120
|
expect(result[0].content[1]).toEqual({
|
120
121
|
type: 'image_url',
|
121
|
-
image_url: 'image.jpg'
|
122
|
+
image_url: 'image.jpg',
|
122
123
|
});
|
123
124
|
});
|
124
125
|
|
@@ -129,18 +130,18 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
129
130
|
content: [
|
130
131
|
{
|
131
132
|
type: 'text',
|
132
|
-
text: 'Date: {{date}}'
|
133
|
+
text: 'Date: {{date}}',
|
133
134
|
},
|
134
135
|
{
|
135
136
|
type: 'text',
|
136
|
-
text: 'Time: {{time}}'
|
137
|
+
text: 'Time: {{time}}',
|
137
138
|
},
|
138
139
|
{
|
139
140
|
type: 'image_url',
|
140
|
-
image_url: 'test.jpg'
|
141
|
-
}
|
142
|
-
]
|
143
|
-
}
|
141
|
+
image_url: 'test.jpg',
|
142
|
+
},
|
143
|
+
],
|
144
|
+
},
|
144
145
|
];
|
145
146
|
|
146
147
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -149,7 +150,7 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
149
150
|
expect(result[0].content[1].text).toContain(new Date().toLocaleTimeString());
|
150
151
|
expect(result[0].content[2]).toEqual({
|
151
152
|
type: 'image_url',
|
152
|
-
image_url: 'test.jpg'
|
153
|
+
image_url: 'test.jpg',
|
153
154
|
});
|
154
155
|
});
|
155
156
|
|
@@ -164,10 +165,10 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
164
165
|
},
|
165
166
|
{
|
166
167
|
type: 'image_url',
|
167
|
-
name: 'image2.jpg'
|
168
|
-
}
|
169
|
-
]
|
170
|
-
}
|
168
|
+
name: 'image2.jpg',
|
169
|
+
},
|
170
|
+
],
|
171
|
+
},
|
171
172
|
];
|
172
173
|
|
173
174
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -175,12 +176,12 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
175
176
|
expect(result[0].content).toEqual([
|
176
177
|
{
|
177
178
|
type: 'image_url',
|
178
|
-
image_url: 'image.jpg'
|
179
|
+
image_url: 'image.jpg',
|
179
180
|
},
|
180
181
|
{
|
181
182
|
type: 'image_url',
|
182
|
-
name: 'image2.jpg'
|
183
|
-
}
|
183
|
+
name: 'image2.jpg',
|
184
|
+
},
|
184
185
|
]);
|
185
186
|
});
|
186
187
|
});
|
@@ -192,25 +193,19 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
192
193
|
});
|
193
194
|
|
194
195
|
it('should handle messages without content', () => {
|
195
|
-
const messages = [
|
196
|
-
{ id: '1' },
|
197
|
-
{ id: '2', content: null },
|
198
|
-
{ id: '3', content: undefined }
|
199
|
-
];
|
196
|
+
const messages = [{ id: '1' }, { id: '2', content: null }, { id: '3', content: undefined }];
|
200
197
|
|
201
198
|
const result = parsePlaceholderVariablesMessages(messages);
|
202
199
|
|
203
200
|
expect(result).toEqual([
|
204
201
|
{ id: '1' },
|
205
202
|
{ id: '2', content: null },
|
206
|
-
{ id: '3', content: undefined }
|
203
|
+
{ id: '3', content: undefined },
|
207
204
|
]);
|
208
205
|
});
|
209
206
|
|
210
207
|
it('should handle empty string content', () => {
|
211
|
-
const messages = [
|
212
|
-
{ id: '1', content: '' }
|
213
|
-
];
|
208
|
+
const messages = [{ id: '1', content: '' }];
|
214
209
|
|
215
210
|
const result = parsePlaceholderVariablesMessages(messages);
|
216
211
|
|
@@ -220,13 +215,13 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
220
215
|
it('should handle content without variables', () => {
|
221
216
|
const messages = [
|
222
217
|
{ id: '1', content: 'Hello world!' },
|
223
|
-
{
|
224
|
-
id: '2',
|
218
|
+
{
|
219
|
+
id: '2',
|
225
220
|
content: [
|
226
221
|
{ type: 'text', text: 'No variables here' },
|
227
|
-
{ type: 'image_url', image_url: 'test.jpg' }
|
228
|
-
]
|
229
|
-
}
|
222
|
+
{ type: 'image_url', image_url: 'test.jpg' },
|
223
|
+
],
|
224
|
+
},
|
230
225
|
];
|
231
226
|
|
232
227
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -236,9 +231,7 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
236
231
|
});
|
237
232
|
|
238
233
|
it('should handle unknown variable types', () => {
|
239
|
-
const messages = [
|
240
|
-
{ id: '1', content: 'Hello {{unknown_variable}}!' }
|
241
|
-
];
|
234
|
+
const messages = [{ id: '1', content: 'Hello {{unknown_variable}}!' }];
|
242
235
|
|
243
236
|
const result = parsePlaceholderVariablesMessages(messages);
|
244
237
|
|
@@ -247,9 +240,7 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
247
240
|
});
|
248
241
|
|
249
242
|
it('should handle nested variables (input_template)', () => {
|
250
|
-
const messages = [
|
251
|
-
{ id: '1', content: 'Template: {{input_template}}' }
|
252
|
-
];
|
243
|
+
const messages = [{ id: '1', content: 'Template: {{input_template}}' }];
|
253
244
|
|
254
245
|
const result = parsePlaceholderVariablesMessages(messages);
|
255
246
|
|
@@ -261,10 +252,10 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
261
252
|
describe('specific variable types', () => {
|
262
253
|
it('should handle time variables', () => {
|
263
254
|
const messages = [
|
264
|
-
{
|
265
|
-
id: '1',
|
266
|
-
content: 'Year: {{year}}, Month: {{month}}, Day: {{day}}'
|
267
|
-
}
|
255
|
+
{
|
256
|
+
id: '1',
|
257
|
+
content: 'Year: {{year}}, Month: {{month}}, Day: {{day}}',
|
258
|
+
},
|
268
259
|
];
|
269
260
|
|
270
261
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -276,10 +267,10 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
276
267
|
|
277
268
|
it('should handle random variables', () => {
|
278
269
|
const messages = [
|
279
|
-
{
|
280
|
-
id: '1',
|
281
|
-
content: 'Random: {{random}}, Bool: {{random_bool}}, UUID: {{uuid}}'
|
282
|
-
}
|
270
|
+
{
|
271
|
+
id: '1',
|
272
|
+
content: 'Random: {{random}}, Bool: {{random_bool}}, UUID: {{uuid}}',
|
273
|
+
},
|
283
274
|
];
|
284
275
|
|
285
276
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -291,10 +282,10 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
291
282
|
|
292
283
|
it('should handle user variables', () => {
|
293
284
|
const messages = [
|
294
|
-
{
|
295
|
-
id: '1',
|
296
|
-
content: 'User: {{username}}, Nickname: {{nickname}}'
|
297
|
-
}
|
285
|
+
{
|
286
|
+
id: '1',
|
287
|
+
content: 'User: {{username}}, Nickname: {{nickname}}',
|
288
|
+
},
|
298
289
|
];
|
299
290
|
|
300
291
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -307,13 +298,11 @@ describe('parsePlaceholderVariablesMessages', () => {
|
|
307
298
|
it('should process multiple messages correctly', () => {
|
308
299
|
const messages = [
|
309
300
|
{ id: '1', content: 'Hello {{username}}' },
|
310
|
-
{
|
311
|
-
id: '2',
|
312
|
-
content: [
|
313
|
-
{ type: 'text', text: 'Today is {{date}}' }
|
314
|
-
]
|
301
|
+
{
|
302
|
+
id: '2',
|
303
|
+
content: [{ type: 'text', text: 'Today is {{date}}' }],
|
315
304
|
},
|
316
|
-
{ id: '3', content: 'Time: {{time}}' }
|
305
|
+
{ id: '3', content: 'Time: {{time}}' },
|
317
306
|
];
|
318
307
|
|
319
308
|
const result = parsePlaceholderVariablesMessages(messages);
|
@@ -53,12 +53,14 @@ export const VARIABLE_GENERATORS = {
|
|
53
53
|
*
|
54
54
|
* | Value | Example |
|
55
55
|
* |-------|---------|
|
56
|
+
* | `{{email}}` | demo@lobehub.com |
|
56
57
|
* | `{{nickname}}` | 社区版用户 |
|
57
58
|
* | `{{username}}` | LobeChat |
|
58
59
|
*
|
59
60
|
*/
|
61
|
+
email: () => userProfileSelectors.email(useUserStore.getState()) ?? '',
|
60
62
|
nickname: () => userProfileSelectors.nickName(useUserStore.getState()) ?? '',
|
61
|
-
username: () => userProfileSelectors.
|
63
|
+
username: () => userProfileSelectors.displayUserName(useUserStore.getState()) ?? userProfileSelectors.fullName(useUserStore.getState()) ?? '',
|
62
64
|
|
63
65
|
/**
|
64
66
|
* 随机值类模板变量
|