@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 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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Improve {{username}} placeholder variable, Update Gemini & Qwen models."
6
+ ]
7
+ },
8
+ "date": "2025-06-07",
9
+ "version": "1.92.1"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "features": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.92.0",
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 ellipsis>{model.displayName || model.id}</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: 64_000,
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: 96_000,
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',
@@ -518,7 +518,6 @@ const openrouterChatModels: AIChatModelCard[] = [
518
518
  },
519
519
  {
520
520
  abilities: {
521
- functionCall: true,
522
521
  reasoning: true,
523
522
  },
524
523
  contextWindowTokens: 163_840,
@@ -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: 122_880,
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-03-25',
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: 65_792,
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: 65_792,
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 { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import { parsePlaceholderVariablesMessages, VARIABLE_GENERATORS } from './parserPlaceholder';
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
- username: () => 'testuser',
19
- fullName: () => 'Test Full Name'
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.username(useUserStore.getState()) ?? userProfileSelectors.fullName(useUserStore.getState()) ?? '',
63
+ username: () => userProfileSelectors.displayUserName(useUserStore.getState()) ?? userProfileSelectors.fullName(useUserStore.getState()) ?? '',
62
64
 
63
65
  /**
64
66
  * 随机值类模板变量