@lobehub/chat 1.51.7 → 1.51.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.ja-JP.md +8 -8
  3. package/README.md +8 -8
  4. package/README.zh-CN.md +8 -8
  5. package/changelog/v1.json +9 -0
  6. package/package.json +1 -1
  7. package/src/app/(backend)/webapi/chat/models/[provider]/route.ts +1 -1
  8. package/src/libs/agent-runtime/ai360/index.ts +8 -1
  9. package/src/libs/agent-runtime/anthropic/index.ts +2 -1
  10. package/src/libs/agent-runtime/baichuan/index.ts +1 -1
  11. package/src/libs/agent-runtime/cloudflare/index.test.ts +0 -117
  12. package/src/libs/agent-runtime/cloudflare/index.ts +32 -11
  13. package/src/libs/agent-runtime/deepseek/index.ts +4 -1
  14. package/src/libs/agent-runtime/fireworksai/index.ts +8 -1
  15. package/src/libs/agent-runtime/giteeai/index.ts +9 -1
  16. package/src/libs/agent-runtime/github/index.test.ts +5 -16
  17. package/src/libs/agent-runtime/github/index.ts +31 -33
  18. package/src/libs/agent-runtime/google/index.ts +2 -1
  19. package/src/libs/agent-runtime/groq/index.ts +7 -1
  20. package/src/libs/agent-runtime/higress/index.ts +2 -1
  21. package/src/libs/agent-runtime/huggingface/index.ts +10 -1
  22. package/src/libs/agent-runtime/hunyuan/index.ts +3 -1
  23. package/src/libs/agent-runtime/internlm/index.ts +3 -1
  24. package/src/libs/agent-runtime/mistral/index.ts +2 -1
  25. package/src/libs/agent-runtime/moonshot/index.ts +3 -1
  26. package/src/libs/agent-runtime/novita/__snapshots__/index.test.ts.snap +48 -12
  27. package/src/libs/agent-runtime/novita/index.ts +9 -1
  28. package/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +70 -66
  29. package/src/libs/agent-runtime/openai/index.ts +37 -0
  30. package/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +172 -4
  31. package/src/libs/agent-runtime/openrouter/index.ts +17 -2
  32. package/src/libs/agent-runtime/qwen/index.ts +10 -1
  33. package/src/libs/agent-runtime/sensenova/index.ts +3 -1
  34. package/src/libs/agent-runtime/siliconcloud/index.ts +10 -1
  35. package/src/libs/agent-runtime/stepfun/index.ts +3 -1
  36. package/src/libs/agent-runtime/togetherai/__snapshots__/index.test.ts.snap +1309 -5
  37. package/src/libs/agent-runtime/togetherai/index.test.ts +0 -13
  38. package/src/libs/agent-runtime/togetherai/index.ts +25 -20
  39. package/src/libs/agent-runtime/utils/cloudflareHelpers.test.ts +0 -99
  40. package/src/libs/agent-runtime/utils/cloudflareHelpers.ts +0 -70
  41. package/src/libs/agent-runtime/xai/index.ts +3 -1
  42. package/src/libs/agent-runtime/zeroone/index.ts +3 -1
  43. package/src/libs/agent-runtime/zhipu/index.ts +3 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.51.8](https://github.com/lobehub/lobe-chat/compare/v1.51.7...v1.51.8)
6
+
7
+ <sup>Released on **2025-02-06**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor model fetch method.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor model fetch method, closes [#5768](https://github.com/lobehub/lobe-chat/issues/5768) ([e406908](https://github.com/lobehub/lobe-chat/commit/e406908))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ### [Version 1.51.7](https://github.com/lobehub/lobe-chat/compare/v1.51.6...v1.51.7)
6
31
 
7
32
  <sup>Released on **2025-02-06**</sup>
package/README.ja-JP.md CHANGED
@@ -302,14 +302,14 @@ LobeChat エージェントマーケットプレイスでは、クリエイタ
302
302
 
303
303
  <!-- AGENT LIST -->
304
304
 
305
- | 最近追加 | 説明 |
306
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
307
- | [鋭い評論家](https://lobechat.com/discover/assistant/ruipingshi)<br/><sup>By **[Zippland](https://github.com/Zippland)** on **2025-02-04**</sup> | 鋭い評論と深い問題分析が得意<br/>`評論` `社会的見解` `鋭い分析` |
308
- | [Python の天才](https://lobechat.com/discover/assistant/python-genius)<br/><sup>By **[novaspivack](https://github.com/novaspivack)** on **2025-02-04**</sup> | 高度な Python コーダー<br/>`コード` `python` |
309
- | [SAT マスター](https://lobechat.com/discover/assistant/sat-teaching)<br/><sup>By **[iBz-04](https://github.com/iBz-04)** on **2025-02-04**</sup> | 1300 点以上のスコアを目指すデジタル SAT コーチングの専門家<br/>`sat` `適性試験` |
310
- | [宇宙の啓示者](https://lobechat.com/discover/assistant/universal-god)<br/><sup>By **[GowayLee](https://github.com/GowayLee)** on **2025-02-04**</sup> | 時空を超えた知恵の神託、生命の本質を洞察する<br/>`キャラクターデザイン` `aiキャラクター` `メタバース` `ロールプレイング` `知恵システム` |
311
-
312
- > 📊 Total agents: [<kbd>**478**</kbd> ](https://lobechat.com/discover/assistants)
305
+ | 最近追加 | 説明 |
306
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
307
+ | [命理研究者](https://lobechat.com/discover/assistant/fate-researcher)<br/><sup>By **[Jack980506](https://github.com/Jack980506)** on **2025-02-06**</sup> | 八字命に精通<br/>`命理学` `八字` `伝統文化` |
308
+ | [言語の魅力学習メンター](https://lobechat.com/discover/assistant/bad-language-helper)<br/><sup>By **[Guducat](https://github.com/Guducat)** on **2025-02-06**</sup> | 言語の魅力と多様な応答を教えるのが得意<br/>`言語学習` `対話例` |
309
+ | [Allinone](https://lobechat.com/discover/assistant/allinone-v-1)<br/><sup>By **[AXuanCreator](https://github.com/AXuanCreator)** on **2025-02-06**</sup> | 革新・未来・卓越<br/>`プログラミング` `低コスト` `簡潔な回答` |
310
+ | [ディープシンカー](https://lobechat.com/discover/assistant/deep-thinker)<br/><sup>By **[prolapser](https://github.com/prolapser)** on **2025-02-06**</sup> | 深い人間のような思考と分析。<br/>`思考` `推論` `反省` `考え` `思索` |
311
+
312
+ > 📊 Total agents: [<kbd>**485**</kbd> ](https://lobechat.com/discover/assistants)
313
313
 
314
314
  <!-- AGENT LIST -->
315
315
 
package/README.md CHANGED
@@ -319,14 +319,14 @@ Our marketplace is not just a showcase platform but also a collaborative space.
319
319
 
320
320
  <!-- AGENT LIST -->
321
321
 
322
- | Recent Submits | Description |
323
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
324
- | [Sharp Commentator](https://lobechat.com/discover/assistant/ruipingshi)<br/><sup>By **[Zippland](https://github.com/Zippland)** on **2025-02-04**</sup> | Specializes in sharp commentary and in-depth analysis of issues<br/>`commentary` `social-perspectives` `sharp-analysis` |
325
- | [Python Genius](https://lobechat.com/discover/assistant/python-genius)<br/><sup>By **[novaspivack](https://github.com/novaspivack)** on **2025-02-04**</sup> | An advanced python coder<br/>`code` `python` |
326
- | [SAT master](https://lobechat.com/discover/assistant/sat-teaching)<br/><sup>By **[iBz-04](https://github.com/iBz-04)** on **2025-02-04**</sup> | Expert in Digital SAT coaching for 1300+ scores<br/>`sat` `aptitude-test` |
327
- | [Cosmic Oracle](https://lobechat.com/discover/assistant/universal-god)<br/><sup>By **[GowayLee](https://github.com/GowayLee)** on **2025-02-04**</sup> | Wisdom from across time and space, insight into the essence of life<br/>`character-design` `ai-characters` `metaverse` `role-playing` `wisdom-system` |
328
-
329
- > 📊 Total agents: [<kbd>**478**</kbd> ](https://lobechat.com/discover/assistants)
322
+ | Recent Submits | Description |
323
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
324
+ | [Astrology Researcher](https://lobechat.com/discover/assistant/fate-researcher)<br/><sup>By **[Jack980506](https://github.com/Jack980506)** on **2025-02-06**</sup> | Expert in BaZi astrology<br/>`astrology` `ba-zi` `traditional-culture` |
325
+ | [Language Charm Learning Mentor](https://lobechat.com/discover/assistant/bad-language-helper)<br/><sup>By **[Guducat](https://github.com/Guducat)** on **2025-02-06**</sup> | Specializes in teaching the charm of language and witty responses<br/>`language-learning` `dialogue-examples` |
326
+ | [Allinone](https://lobechat.com/discover/assistant/allinone-v-1)<br/><sup>By **[AXuanCreator](https://github.com/AXuanCreator)** on **2025-02-06**</sup> | Innovation · Future · Excellence<br/>`programming` `low-cost` `concise-answers` |
327
+ | [Deep Thinker](https://lobechat.com/discover/assistant/deep-thinker)<br/><sup>By **[prolapser](https://github.com/prolapser)** on **2025-02-06**</sup> | Deep, human-like thinking and analysis.<br/>`thinking` `reasoning` `reflection` `thought` `musings` |
328
+
329
+ > 📊 Total agents: [<kbd>**485**</kbd> ](https://lobechat.com/discover/assistants)
330
330
 
331
331
  <!-- AGENT LIST -->
332
332
 
package/README.zh-CN.md CHANGED
@@ -308,14 +308,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
308
308
 
309
309
  <!-- AGENT LIST -->
310
310
 
311
- | 最近新增 | 描述 |
312
- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
313
- | [锐评师](https://lobechat.com/discover/assistant/ruipingshi)<br/><sup>By **[Zippland](https://github.com/Zippland)** on **2025-02-04**</sup> | 擅长犀利点评与深度剖析问题<br/>`评论` `社会观点` `尖锐分析` |
314
- | [Python 天才](https://lobechat.com/discover/assistant/python-genius)<br/><sup>By **[novaspivack](https://github.com/novaspivack)** on **2025-02-04**</sup> | 一名高级 Python 编程者<br/>`代码` `python` |
315
- | [SAT 大师](https://lobechat.com/discover/assistant/sat-teaching)<br/><sup>By **[iBz-04](https://github.com/iBz-04)** on **2025-02-04**</sup> | 数字 SAT 辅导专家,帮助学生取得 1300 + 分数<br/>`sat` `能力测试` |
316
- | [宇宙启示者](https://lobechat.com/discover/assistant/universal-god)<br/><sup>By **[GowayLee](https://github.com/GowayLee)** on **2025-02-04**</sup> | 跨时空的智慧神谕,洞悉生命本质<br/>`角色设计` `ai角色` `元宇宙` `角色扮演` `智慧系统` |
317
-
318
- > 📊 Total agents: [<kbd>**478**</kbd> ](https://lobechat.com/discover/assistants)
311
+ | 最近新增 | 描述 |
312
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
313
+ | [命理研究员](https://lobechat.com/discover/assistant/fate-researcher)<br/><sup>By **[Jack980506](https://github.com/Jack980506)** on **2025-02-06**</sup> | 精通八字命<br/>`命理学` `八字` `传统文化` |
314
+ | [语言魅力学习导师](https://lobechat.com/discover/assistant/bad-language-helper)<br/><sup>By **[Guducat](https://github.com/Guducat)** on **2025-02-06**</sup> | 擅长教学语言的魅力与花样回复<br/>`语言学习` `对话示例` |
315
+ | [Allinone](https://lobechat.com/discover/assistant/allinone-v-1)<br/><sup>By **[AXuanCreator](https://github.com/AXuanCreator)** on **2025-02-06**</sup> | 创新・未来・卓越<br/>`编程` `低成本` `简洁回答` |
316
+ | [深思者](https://lobechat.com/discover/assistant/deep-thinker)<br/><sup>By **[prolapser](https://github.com/prolapser)** on **2025-02-06**</sup> | 深刻的人类思维和分析。<br/>`思考` `推理` `反思` `思想` `沉思` |
317
+
318
+ > 📊 Total agents: [<kbd>**485**</kbd> ](https://lobechat.com/discover/assistants)
319
319
 
320
320
  <!-- AGENT LIST -->
321
321
 
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Refactor model fetch method."
6
+ ]
7
+ },
8
+ "date": "2025-02-06",
9
+ "version": "1.51.8"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.51.7",
3
+ "version": "1.51.8",
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",
@@ -9,7 +9,7 @@ import { createErrorResponse } from '@/utils/errorResponse';
9
9
  export const runtime = 'edge';
10
10
 
11
11
  const noNeedAPIKey = (provider: string) =>
12
- [ModelProvider.OpenRouter, ModelProvider.TogetherAI].includes(provider as any);
12
+ [ModelProvider.OpenRouter].includes(provider as any);
13
13
 
14
14
  export const GET = checkAuth(async (req, { params, jwtPayload }) => {
15
15
  const { provider } = await params;
@@ -24,17 +24,24 @@ export const LobeAi360AI = LobeOpenAICompatibleFactory({
24
24
  },
25
25
  models: {
26
26
  transformModel: (m) => {
27
+ const reasoningKeywords = [
28
+ '360gpt2-o1',
29
+ '360zhinao2-o1',
30
+ ];
31
+
27
32
  const model = m as unknown as Ai360ModelCard;
28
33
 
29
34
  return {
30
35
  contextWindowTokens: model.total_tokens,
31
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
36
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
37
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
32
38
  functionCall: model.id === '360gpt-pro',
33
39
  id: model.id,
34
40
  maxTokens:
35
41
  typeof model.max_tokens === 'number'
36
42
  ? model.max_tokens
37
43
  : undefined,
44
+ reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
38
45
  };
39
46
  },
40
47
  },
@@ -129,8 +129,9 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
129
129
  return modelList
130
130
  .map((model) => {
131
131
  return {
132
+ contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined,
132
133
  displayName: model.display_name,
133
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
134
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
134
135
  functionCall: model.id.toLowerCase().includes('claude-3'),
135
136
  id: model.id,
136
137
  vision: model.id.toLowerCase().includes('claude-3') && !model.id.toLowerCase().includes('claude-3-5-haiku'),
@@ -40,7 +40,7 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({
40
40
  return {
41
41
  contextWindowTokens: model.max_input_length,
42
42
  displayName: model.model_show_name,
43
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.model.endsWith(m.id))?.enabled || false,
43
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.model === m.id)?.enabled || false,
44
44
  functionCall: model.function_call,
45
45
  id: model.model,
46
46
  maxTokens: model.max_tokens,
@@ -527,122 +527,5 @@ describe('LobeCloudflareAI', () => {
527
527
 
528
528
  expect(result).toHaveLength(2);
529
529
  });
530
-
531
- it('should set id to name', async () => {
532
- // Arrange
533
- const instance = new LobeCloudflareAI({
534
- apiKey: 'test_api_key',
535
- baseURLOrAccountID: accountID,
536
- });
537
-
538
- vi.spyOn(globalThis, 'fetch').mockResolvedValue(
539
- new Response(
540
- JSON.stringify({
541
- result: [
542
- {
543
- id: 'id1',
544
- name: 'name1',
545
- task: { name: 'Text Generation' },
546
- },
547
- ],
548
- }),
549
- ),
550
- );
551
-
552
- // Act
553
- const result = await instance.models();
554
-
555
- // Assert
556
- expect(result).toEqual([
557
- expect.objectContaining({
558
- displayName: 'name1',
559
- id: 'name1',
560
- }),
561
- ]);
562
- });
563
-
564
- it('should filter text generation models', async () => {
565
- // Arrange
566
- const instance = new LobeCloudflareAI({
567
- apiKey: 'test_api_key',
568
- baseURLOrAccountID: accountID,
569
- });
570
-
571
- vi.spyOn(globalThis, 'fetch').mockResolvedValue(
572
- new Response(
573
- JSON.stringify({
574
- result: [
575
- {
576
- id: '1',
577
- name: 'model1',
578
- task: { name: 'Text Generation' },
579
- },
580
- {
581
- id: '2',
582
- name: 'model2',
583
- task: { name: 'Text Classification' },
584
- },
585
- ],
586
- }),
587
- ),
588
- );
589
-
590
- // Act
591
- const result = await instance.models();
592
-
593
- // Assert
594
- expect(result).toEqual([
595
- expect.objectContaining({
596
- displayName: 'model1',
597
- id: 'model1',
598
- }),
599
- ]);
600
- });
601
-
602
- it('should enable non-beta models and mark beta models', async () => {
603
- // Arrange
604
- const instance = new LobeCloudflareAI({
605
- apiKey: 'test_api_key',
606
- baseURLOrAccountID: accountID,
607
- });
608
-
609
- vi.spyOn(globalThis, 'fetch').mockResolvedValue(
610
- new Response(
611
- JSON.stringify({
612
- result: [
613
- {
614
- id: '1',
615
- name: 'model1',
616
- task: { name: 'Text Generation' },
617
- properties: [{ property_id: 'beta', value: 'false' }],
618
- },
619
- {
620
- id: '2',
621
- name: 'model2',
622
- task: { name: 'Text Generation' },
623
- properties: [{ property_id: 'beta', value: 'true' }],
624
- },
625
- ],
626
- }),
627
- ),
628
- );
629
-
630
- // Act
631
- const result = await instance.models();
632
-
633
- // Assert
634
- expect(result).toEqual([
635
- expect.objectContaining({
636
- displayName: 'model1',
637
- enabled: true,
638
- id: 'model1',
639
- }),
640
- expect.objectContaining({
641
- displayName: 'model2 (Beta)',
642
- enabled: false,
643
- id: 'model2',
644
- }),
645
- ]);
646
- });
647
530
  });
648
531
  });
@@ -1,12 +1,9 @@
1
- import { ChatModelCard } from '@/types/llm';
2
-
3
1
  import { LobeRuntimeAI } from '../BaseAI';
4
2
  import { AgentRuntimeErrorType } from '../error';
5
3
  import { ChatCompetitionOptions, ChatStreamPayload, ModelProvider } from '../types';
6
4
  import {
7
5
  CloudflareStreamTransformer,
8
6
  DEFAULT_BASE_URL_PREFIX,
9
- convertModelManifest,
10
7
  desensitizeCloudflareUrl,
11
8
  fillUrl,
12
9
  } from '../utils/cloudflareHelpers';
@@ -15,6 +12,19 @@ import { debugStream } from '../utils/debugStream';
15
12
  import { StreamingResponse } from '../utils/response';
16
13
  import { createCallbacksTransformer } from '../utils/streams';
17
14
 
15
+ import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels';
16
+ import { ChatModelCard } from '@/types/llm';
17
+
18
+ export interface CloudflareModelCard {
19
+ description: string;
20
+ name: string;
21
+ properties?: Record<string, string>;
22
+ task?: {
23
+ description?: string;
24
+ name: string;
25
+ };
26
+ }
27
+
18
28
  export interface LobeCloudflareParams {
19
29
  apiKey?: string;
20
30
  baseURLOrAccountID?: string;
@@ -111,13 +121,24 @@ export class LobeCloudflareAI implements LobeRuntimeAI {
111
121
  },
112
122
  method: 'GET',
113
123
  });
114
- const j = await response.json();
115
- const models: any[] = j['result'].filter(
116
- (model: any) => model['task']['name'] === 'Text Generation',
117
- );
118
- const chatModels: ChatModelCard[] = models
119
- .map((model) => convertModelManifest(model))
120
- .sort((a, b) => a.displayName.localeCompare(b.displayName));
121
- return chatModels;
124
+ const json = await response.json();
125
+
126
+ const modelList: CloudflareModelCard[] = json.result;
127
+
128
+ return modelList
129
+ .map((model) => {
130
+ return {
131
+ contextWindowTokens: model.properties?.max_total_tokens
132
+ ? Number(model.properties.max_total_tokens)
133
+ : LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined,
134
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.displayName ?? (model.properties?.["beta"] === "true" ? `${model.name} (Beta)` : undefined),
135
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false,
136
+ functionCall: model.description.toLowerCase().includes('function call') || model.properties?.["function_calling"] === "true",
137
+ id: model.name,
138
+ reasoning: model.name.toLowerCase().includes('deepseek-r1'),
139
+ vision: model.name.toLowerCase().includes('vision') || model.task?.name.toLowerCase().includes('image-to-text') || model.description.toLowerCase().includes('vision'),
140
+ };
141
+ })
142
+ .filter(Boolean) as ChatModelCard[];
122
143
  }
123
144
  }
@@ -64,9 +64,12 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({
64
64
  const model = m as unknown as DeepSeekModelCard;
65
65
 
66
66
  return {
67
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
67
+ contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined,
68
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
69
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
68
70
  functionCall: !model.id.toLowerCase().includes('deepseek-reasoner'),
69
71
  id: model.id,
72
+ reasoning: model.id.toLowerCase().includes('deepseek-reasoner'),
70
73
  };
71
74
  },
72
75
  },
@@ -17,13 +17,20 @@ export const LobeFireworksAI = LobeOpenAICompatibleFactory({
17
17
  },
18
18
  models: {
19
19
  transformModel: (m) => {
20
+ const reasoningKeywords = [
21
+ 'deepseek-r1',
22
+ 'qwq',
23
+ ];
24
+
20
25
  const model = m as unknown as FireworksAIModelCard;
21
26
 
22
27
  return {
23
28
  contextWindowTokens: model.context_length,
24
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
29
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
30
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
25
31
  functionCall: model.supports_tools || model.id.toLowerCase().includes('function'),
26
32
  id: model.id,
33
+ reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
27
34
  vision: model.supports_image_input,
28
35
  };
29
36
  },
@@ -24,12 +24,20 @@ export const LobeGiteeAI = LobeOpenAICompatibleFactory({
24
24
  'qwen2-vl',
25
25
  ];
26
26
 
27
+ const reasoningKeywords = [
28
+ 'deepseek-r1',
29
+ 'qwq',
30
+ ];
31
+
27
32
  const model = m as unknown as GiteeAIModelCard;
28
33
 
29
34
  return {
30
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
35
+ contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined,
36
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
37
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
31
38
  functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('qwen2.5-coder'),
32
39
  id: model.id,
40
+ reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
33
41
  vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
34
42
  };
35
43
  },
@@ -217,22 +217,6 @@ describe('LobeGithubAI', () => {
217
217
  it('should return a list of models', async () => {
218
218
  // Arrange
219
219
  const arr = [
220
- {
221
- id: 'azureml://registries/azureml-ai21/models/AI21-Jamba-Instruct/versions/2',
222
- name: 'AI21-Jamba-Instruct',
223
- friendly_name: 'AI21-Jamba-Instruct',
224
- model_version: 2,
225
- publisher: 'AI21 Labs',
226
- model_family: 'AI21 Labs',
227
- model_registry: 'azureml-ai21',
228
- license: 'custom',
229
- task: 'chat-completion',
230
- description:
231
- "Jamba-Instruct is the world's first production-grade Mamba-based LLM model and leverages its hybrid Mamba-Transformer architecture to achieve best-in-class performance, quality, and cost efficiency.\n\n**Model Developer Name**: _AI21 Labs_\n\n## Model Architecture\n\nJamba-Instruct leverages a hybrid Mamba-Transformer architecture to achieve best-in-class performance, quality, and cost efficiency.\nAI21's Jamba architecture features a blocks-and-layers approach that allows Jamba to successfully integrate the two architectures. Each Jamba block contains either an attention or a Mamba layer, followed by a multi-layer perceptron (MLP), producing an overall ratio of one Transformer layer out of every eight total layers.\n",
232
- summary:
233
- "Jamba-Instruct is the world's first production-grade Mamba-based LLM model and leverages its hybrid Mamba-Transformer architecture to achieve best-in-class performance, quality, and cost efficiency.",
234
- tags: ['chat', 'rag'],
235
- },
236
220
  {
237
221
  id: 'azureml://registries/azureml-cohere/models/Cohere-command-r/versions/3',
238
222
  name: 'Cohere-command-r',
@@ -263,9 +247,14 @@ describe('LobeGithubAI', () => {
263
247
  for (let i = 0; i < arr.length; i++) {
264
248
  const model = models[i];
265
249
  expect(model).toEqual({
250
+ contextWindowTokens: undefined,
266
251
  description: arr[i].description,
267
252
  displayName: arr[i].friendly_name,
253
+ enabled: false,
254
+ functionCall: true,
268
255
  id: arr[i].name,
256
+ reasoning: false,
257
+ vision: false,
269
258
  });
270
259
  }
271
260
  });
@@ -1,34 +1,20 @@
1
- import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders';
2
- import type { ChatModelCard } from '@/types/llm';
3
-
4
1
  import { AgentRuntimeErrorType } from '../error';
5
2
  import { pruneReasoningPayload } from '../openai';
6
3
  import { ModelProvider } from '../types';
7
- import {
8
- CHAT_MODELS_BLOCK_LIST,
9
- LobeOpenAICompatibleFactory,
10
- } from '../utils/openaiCompatibleFactory';
4
+ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
11
5
 
12
- enum Task {
13
- 'chat-completion',
14
- 'embeddings',
15
- }
6
+ import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels';
7
+ import type { ChatModelCard } from '@/types/llm';
16
8
 
17
- /* eslint-disable typescript-sort-keys/interface */
18
- type Model = {
9
+ export interface GithubModelCard {
10
+ description: string;
11
+ friendly_name: string;
19
12
  id: string;
20
13
  name: string;
21
- friendly_name: string;
22
- model_version: number;
23
- publisher: string;
24
- model_family: string;
25
- model_registry: string;
26
- license: string;
27
- task: Task;
28
- description: string;
29
- summary: string;
30
14
  tags: string[];
31
- };
15
+ task: string;
16
+ }
17
+
32
18
  /* eslint-enable typescript-sort-keys/interface */
33
19
 
34
20
  export const LobeGithubAI = LobeOpenAICompatibleFactory({
@@ -52,23 +38,35 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({
52
38
  invalidAPIKey: AgentRuntimeErrorType.InvalidGithubToken,
53
39
  },
54
40
  models: async ({ client }) => {
41
+ const functionCallKeywords = [
42
+ 'function',
43
+ 'tool',
44
+ ];
45
+
46
+ const visionKeywords = [
47
+ 'vision',
48
+ ];
49
+
50
+ const reasoningKeywords = [
51
+ 'deepseek-r1',
52
+ 'o1',
53
+ 'o3',
54
+ ];
55
+
55
56
  const modelsPage = (await client.models.list()) as any;
56
- const modelList: Model[] = modelsPage.body;
57
+ const modelList: GithubModelCard[] = modelsPage.body;
58
+
57
59
  return modelList
58
- .filter((model) => {
59
- return CHAT_MODELS_BLOCK_LIST.every(
60
- (keyword) => !model.name.toLowerCase().includes(keyword),
61
- );
62
- })
63
60
  .map((model) => {
64
- const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => m.id === model.name);
65
-
66
- if (knownModel) return knownModel;
67
-
68
61
  return {
62
+ contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined,
69
63
  description: model.description,
70
64
  displayName: model.friendly_name,
65
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false,
66
+ functionCall: functionCallKeywords.some(keyword => model.description.toLowerCase().includes(keyword)),
71
67
  id: model.name,
68
+ reasoning: reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)),
69
+ vision: visionKeywords.some(keyword => model.description.toLowerCase().includes(keyword)),
72
70
  };
73
71
  })
74
72
  .filter(Boolean) as ChatModelCard[];
@@ -152,9 +152,10 @@ export class LobeGoogleAI implements LobeRuntimeAI {
152
152
  return {
153
153
  contextWindowTokens: model.inputTokenLimit + model.outputTokenLimit,
154
154
  displayName: model.displayName,
155
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => modelName.endsWith(m.id))?.enabled || false,
155
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => modelName === m.id)?.enabled || false,
156
156
  functionCall: modelName.toLowerCase().includes('gemini'),
157
157
  id: modelName,
158
+ reasoning: modelName.toLowerCase().includes('thinking'),
158
159
  vision:
159
160
  modelName.toLowerCase().includes('vision') ||
160
161
  (modelName.toLowerCase().includes('gemini') &&
@@ -42,13 +42,19 @@ export const LobeGroq = LobeOpenAICompatibleFactory({
42
42
  'gemma2-9b-it',
43
43
  ];
44
44
 
45
+ const reasoningKeywords = [
46
+ 'deepseek-r1',
47
+ ];
48
+
45
49
  const model = m as unknown as GroqModelCard;
46
50
 
47
51
  return {
48
52
  contextWindowTokens: model.context_window,
49
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
53
+ displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
54
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
50
55
  functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
51
56
  id: model.id,
57
+ reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
52
58
  vision: model.id.toLowerCase().includes('vision'),
53
59
  };
54
60
  },
@@ -26,7 +26,7 @@ export const LobeHigressAI = LobeOpenAICompatibleFactory({
26
26
  contextWindowTokens: model.context_length,
27
27
  description: model.description,
28
28
  displayName: model.name,
29
- enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.endsWith(m.id))?.enabled || false,
29
+ enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
30
30
  functionCall:
31
31
  model.description.includes('function calling') || model.description.includes('tools'),
32
32
  id: model.id,
@@ -34,6 +34,7 @@ export const LobeHigressAI = LobeOpenAICompatibleFactory({
34
34
  typeof model.top_provider.max_completion_tokens === 'number'
35
35
  ? model.top_provider.max_completion_tokens
36
36
  : undefined,
37
+ reasoning: model.description.includes('reasoning'),
37
38
  vision:
38
39
  model.description.includes('vision') ||
39
40
  model.description.includes('multimodal') ||