@lobehub/lobehub 2.1.3 → 2.1.4

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 (129) hide show
  1. package/.env.example +0 -3
  2. package/.env.example.development +0 -3
  3. package/CHANGELOG.md +34 -0
  4. package/changelog/v2.json +9 -0
  5. package/docker-compose/deploy/.env.example +3 -1
  6. package/docker-compose/deploy/.env.zh-CN.example +4 -1
  7. package/docker-compose/local/.env.example +0 -1
  8. package/docker-compose/local/.env.zh-CN.example +0 -1
  9. package/docker-compose/local/grafana/.env.example +0 -1
  10. package/docker-compose/local/grafana/.env.zh-CN.example +0 -1
  11. package/docker-compose/local/logto/docker-compose.yml +0 -1
  12. package/docker-compose/local/zitadel/.env.example +1 -2
  13. package/docker-compose/local/zitadel/.env.zh-CN.example +1 -2
  14. package/docker-compose/production/grafana/.env.example +0 -1
  15. package/docker-compose/production/grafana/.env.zh-CN.example +0 -1
  16. package/docker-compose/production/logto/.env.example +0 -2
  17. package/docker-compose/production/logto/.env.zh-CN.example +0 -2
  18. package/docker-compose/production/zitadel/.env.example +0 -2
  19. package/docker-compose/production/zitadel/.env.zh-CN.example +0 -2
  20. package/docker-compose/setup.sh +16 -2
  21. package/docs/development/basic/folder-structure.mdx +23 -14
  22. package/docs/development/basic/folder-structure.zh-CN.mdx +23 -14
  23. package/docs/development/basic/work-with-server-side-database.mdx +0 -1
  24. package/docs/development/basic/work-with-server-side-database.zh-CN.mdx +0 -1
  25. package/docs/development/start.mdx +19 -12
  26. package/docs/development/start.zh-CN.mdx +19 -12
  27. package/docs/self-hosting/advanced/s3/cloudflare-r2.mdx +0 -5
  28. package/docs/self-hosting/advanced/s3/cloudflare-r2.zh-CN.mdx +0 -5
  29. package/docs/self-hosting/advanced/s3/rustfs.mdx +0 -2
  30. package/docs/self-hosting/advanced/s3/rustfs.zh-CN.mdx +0 -2
  31. package/docs/self-hosting/advanced/s3/tencent-cloud.mdx +0 -1
  32. package/docs/self-hosting/advanced/s3/tencent-cloud.zh-CN.mdx +0 -2
  33. package/docs/self-hosting/advanced/s3.mdx +0 -9
  34. package/docs/self-hosting/advanced/s3.zh-CN.mdx +0 -8
  35. package/docs/self-hosting/environment-variables/s3.mdx +0 -7
  36. package/docs/self-hosting/environment-variables/s3.zh-CN.mdx +0 -7
  37. package/docs/self-hosting/platform/docker-compose.mdx +0 -1
  38. package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +0 -1
  39. package/docs/self-hosting/platform/docker.mdx +5 -3
  40. package/docs/self-hosting/platform/docker.zh-CN.mdx +5 -4
  41. package/docs/self-hosting/platform/dokploy.mdx +0 -2
  42. package/docs/self-hosting/platform/dokploy.zh-CN.mdx +0 -2
  43. package/docs/self-hosting/platform/vercel.mdx +0 -7
  44. package/docs/self-hosting/platform/vercel.zh-CN.mdx +0 -7
  45. package/e2e/src/steps/home/sidebarAgent.steps.ts +56 -24
  46. package/locales/ar/authError.json +1 -0
  47. package/locales/ar/models.json +25 -22
  48. package/locales/ar/providers.json +0 -1
  49. package/locales/ar/setting.json +16 -0
  50. package/locales/bg-BG/authError.json +1 -0
  51. package/locales/bg-BG/models.json +18 -21
  52. package/locales/bg-BG/providers.json +0 -1
  53. package/locales/bg-BG/setting.json +16 -0
  54. package/locales/de-DE/authError.json +1 -0
  55. package/locales/de-DE/models.json +20 -20
  56. package/locales/de-DE/providers.json +0 -1
  57. package/locales/de-DE/setting.json +16 -0
  58. package/locales/en-US/models.json +22 -22
  59. package/locales/en-US/providers.json +0 -1
  60. package/locales/es-ES/authError.json +1 -0
  61. package/locales/es-ES/models.json +84 -20
  62. package/locales/es-ES/providers.json +0 -1
  63. package/locales/es-ES/setting.json +16 -0
  64. package/locales/fa-IR/authError.json +1 -0
  65. package/locales/fa-IR/models.json +43 -20
  66. package/locales/fa-IR/providers.json +0 -1
  67. package/locales/fa-IR/setting.json +16 -0
  68. package/locales/fr-FR/authError.json +1 -0
  69. package/locales/fr-FR/models.json +19 -21
  70. package/locales/fr-FR/providers.json +0 -1
  71. package/locales/fr-FR/setting.json +16 -0
  72. package/locales/it-IT/authError.json +1 -0
  73. package/locales/it-IT/models.json +17 -19
  74. package/locales/it-IT/providers.json +0 -1
  75. package/locales/it-IT/setting.json +16 -0
  76. package/locales/ja-JP/authError.json +1 -0
  77. package/locales/ja-JP/models.json +43 -22
  78. package/locales/ja-JP/providers.json +0 -1
  79. package/locales/ja-JP/setting.json +16 -0
  80. package/locales/ko-KR/authError.json +1 -0
  81. package/locales/ko-KR/models.json +41 -20
  82. package/locales/ko-KR/providers.json +0 -1
  83. package/locales/ko-KR/setting.json +16 -0
  84. package/locales/nl-NL/authError.json +1 -0
  85. package/locales/nl-NL/models.json +48 -20
  86. package/locales/nl-NL/providers.json +0 -1
  87. package/locales/nl-NL/setting.json +16 -0
  88. package/locales/pl-PL/authError.json +1 -0
  89. package/locales/pl-PL/models.json +19 -22
  90. package/locales/pl-PL/providers.json +0 -1
  91. package/locales/pl-PL/setting.json +16 -0
  92. package/locales/pt-BR/authError.json +1 -0
  93. package/locales/pt-BR/models.json +21 -21
  94. package/locales/pt-BR/providers.json +0 -1
  95. package/locales/pt-BR/setting.json +16 -0
  96. package/locales/ru-RU/authError.json +1 -0
  97. package/locales/ru-RU/models.json +23 -20
  98. package/locales/ru-RU/providers.json +0 -1
  99. package/locales/ru-RU/setting.json +16 -0
  100. package/locales/tr-TR/authError.json +1 -0
  101. package/locales/tr-TR/models.json +37 -20
  102. package/locales/tr-TR/providers.json +0 -1
  103. package/locales/tr-TR/setting.json +16 -0
  104. package/locales/vi-VN/authError.json +1 -0
  105. package/locales/vi-VN/models.json +15 -19
  106. package/locales/vi-VN/providers.json +0 -1
  107. package/locales/vi-VN/setting.json +16 -0
  108. package/locales/zh-CN/models.json +20 -20
  109. package/locales/zh-CN/providers.json +0 -1
  110. package/locales/zh-TW/authError.json +1 -0
  111. package/locales/zh-TW/models.json +20 -20
  112. package/locales/zh-TW/providers.json +0 -1
  113. package/locales/zh-TW/setting.json +16 -0
  114. package/package.json +1 -1
  115. package/packages/model-bank/src/aiModels/google.ts +0 -19
  116. package/packages/model-bank/src/aiModels/moonshot.ts +56 -5
  117. package/packages/model-bank/src/aiModels/ollamacloud.ts +14 -0
  118. package/packages/model-bank/src/aiModels/openrouter.ts +0 -14
  119. package/packages/model-bank/src/aiModels/qwen.ts +105 -4
  120. package/packages/model-bank/src/aiModels/siliconcloud.ts +39 -0
  121. package/packages/model-bank/src/aiModels/wenxin.ts +0 -99
  122. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +24 -0
  123. package/packages/model-runtime/src/core/contextBuilders/openai.ts +22 -5
  124. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +10 -3
  125. package/packages/model-runtime/src/core/streams/google/google-ai.test.ts +54 -13
  126. package/packages/model-runtime/src/core/streams/google/index.ts +1 -4
  127. package/packages/model-runtime/src/providers/moonshot/index.ts +24 -2
  128. package/packages/model-runtime/src/providers/qwen/index.ts +16 -15
  129. package/src/server/routers/lambda/__tests__/integration/aiAgent/execAgent.integration.test.ts +3 -2
@@ -29,7 +29,6 @@
29
29
  "internlm.description": "一個專注於大型模型研究與工具的開源組織,提供高效、易用的平台,讓尖端模型與演算法更易於取得。",
30
30
  "jina.description": "Jina AI 成立於 2020 年,是領先的搜尋 AI 公司。其搜尋技術堆疊包含向量模型、重排序器與小型語言模型,打造可靠且高品質的生成式與多模態搜尋應用。",
31
31
  "lmstudio.description": "LM Studio 是一款桌面應用程式,可在本機開發與實驗大型語言模型。",
32
- "lobehub.description": "LobeHub Cloud 使用官方 API 存取 AI 模型,並以與模型代幣相關的點數(Credits)來計算使用量。",
33
32
  "minimax.description": "MiniMax 成立於 2021 年,致力於打造通用 AI,擁有多模態基礎模型,包括兆級參數的 MoE 文本模型、語音模型與視覺模型,並推出如海螺 AI 等應用。",
34
33
  "mistral.description": "Mistral 提供先進的通用、專業與研究模型,支援複雜推理、多語言任務與程式碼生成,並支援函式呼叫以實現自訂整合。",
35
34
  "modelscope.description": "ModelScope 是阿里雲的模型即服務平台,提供多樣化的 AI 模型與推理服務。",
@@ -34,11 +34,20 @@
34
34
  "agentCronJobs.empty.description": "建立您的第一個排程任務以自動化代理程式",
35
35
  "agentCronJobs.empty.title": "尚無排程任務",
36
36
  "agentCronJobs.enable": "啟用",
37
+ "agentCronJobs.form.at": "在",
37
38
  "agentCronJobs.form.content.placeholder": "輸入給代理程式的提示或指令",
39
+ "agentCronJobs.form.every": "每",
40
+ "agentCronJobs.form.frequency": "頻率",
41
+ "agentCronJobs.form.hours": "小時",
42
+ "agentCronJobs.form.maxExecutions": "執行次數上限",
38
43
  "agentCronJobs.form.maxExecutions.placeholder": "留空表示無限制",
39
44
  "agentCronJobs.form.name.placeholder": "輸入任務名稱",
45
+ "agentCronJobs.form.time": "時間",
40
46
  "agentCronJobs.form.timeRange.end": "結束時間",
41
47
  "agentCronJobs.form.timeRange.start": "開始時間",
48
+ "agentCronJobs.form.times": "次",
49
+ "agentCronJobs.form.timezone": "時區",
50
+ "agentCronJobs.form.unlimited": "持續執行",
42
51
  "agentCronJobs.form.validation.contentRequired": "任務內容為必填",
43
52
  "agentCronJobs.form.validation.invalidTimeRange": "開始時間必須早於結束時間",
44
53
  "agentCronJobs.form.validation.nameRequired": "任務名稱為必填",
@@ -83,6 +92,13 @@
83
92
  "agentCronJobs.weekday.tuesday": "星期二",
84
93
  "agentCronJobs.weekday.wednesday": "星期三",
85
94
  "agentCronJobs.weekdays": "平日",
95
+ "agentCronJobs.weekdays.fri": "週五",
96
+ "agentCronJobs.weekdays.mon": "週一",
97
+ "agentCronJobs.weekdays.sat": "週六",
98
+ "agentCronJobs.weekdays.sun": "週日",
99
+ "agentCronJobs.weekdays.thu": "週四",
100
+ "agentCronJobs.weekdays.tue": "週二",
101
+ "agentCronJobs.weekdays.wed": "週三",
86
102
  "agentInfoDescription.basic.avatar": "頭像",
87
103
  "agentInfoDescription.basic.description": "描述",
88
104
  "agentInfoDescription.basic.name": "名稱",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -651,25 +651,6 @@ const googleChatModels: AIChatModelCard[] = [
651
651
  releasedAt: '2025-02-05',
652
652
  type: 'chat',
653
653
  },
654
- {
655
- abilities: {
656
- imageOutput: true,
657
- vision: true,
658
- },
659
- contextWindowTokens: 1_048_576 + 8192,
660
- description: 'A Gemini 2.0 Flash variant optimized for cost efficiency and low latency.',
661
- displayName: 'Gemini 2.0 Flash Exp',
662
- id: 'gemini-2.0-flash-exp',
663
- maxOutput: 8192,
664
- pricing: {
665
- units: [
666
- { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
667
- { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
668
- ],
669
- },
670
- releasedAt: '2025-02-05',
671
- type: 'chat',
672
- },
673
654
  {
674
655
  abilities: {
675
656
  vision: true,
@@ -2,6 +2,34 @@ import { AIChatModelCard } from '../types/aiModel';
2
2
 
3
3
  // https://platform.moonshot.cn/docs/pricing/chat
4
4
  const moonshotChatModels: AIChatModelCard[] = [
5
+ {
6
+ abilities: {
7
+ functionCall: true,
8
+ reasoning: true,
9
+ structuredOutput: true,
10
+ vision: true,
11
+ },
12
+ contextWindowTokens: 262_144,
13
+ description:
14
+ 'Kimi K2.5 is Kimi\'s most versatile model to date, featuring a native multimodal architecture that supports both vision and text inputs, "thinking" and "non-thinking" modes, and both conversational and agent tasks.',
15
+ displayName: 'Kimi K2.5',
16
+ enabled: true,
17
+ id: 'kimi-k2.5',
18
+ maxOutput: 32_768,
19
+ pricing: {
20
+ currency: 'CNY',
21
+ units: [
22
+ { name: 'textInput_cacheRead', rate: 0.7, strategy: 'fixed', unit: 'millionTokens' },
23
+ { name: 'textInput', rate: 4, strategy: 'fixed', unit: 'millionTokens' },
24
+ { name: 'textOutput', rate: 21, strategy: 'fixed', unit: 'millionTokens' },
25
+ ],
26
+ },
27
+ releasedAt: '2026-01-27',
28
+ settings: {
29
+ extendParams: ['enableReasoning'],
30
+ },
31
+ type: 'chat',
32
+ },
5
33
  {
6
34
  abilities: {
7
35
  functionCall: true,
@@ -12,7 +40,6 @@ const moonshotChatModels: AIChatModelCard[] = [
12
40
  description:
13
41
  'K2 long-thinking model with 256k context, supporting multi-step tool use and reasoning for complex problems.',
14
42
  displayName: 'Kimi K2 Thinking',
15
- enabled: true,
16
43
  id: 'kimi-k2-thinking',
17
44
  maxOutput: 65_536,
18
45
  pricing: {
@@ -58,7 +85,6 @@ const moonshotChatModels: AIChatModelCard[] = [
58
85
  description:
59
86
  'kimi-k2-0905-preview offers a 256k context window, stronger agentic coding, better front-end code quality, and improved context understanding.',
60
87
  displayName: 'Kimi K2 0905',
61
- enabled: true,
62
88
  id: 'kimi-k2-0905-preview',
63
89
  pricing: {
64
90
  currency: 'CNY',
@@ -126,8 +152,32 @@ const moonshotChatModels: AIChatModelCard[] = [
126
152
  currency: 'CNY',
127
153
  units: [
128
154
  { name: 'textInput_cacheRead', rate: 1, strategy: 'fixed', unit: 'millionTokens' },
129
- { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
130
- { name: 'textOutput', rate: 30, strategy: 'fixed', unit: 'millionTokens' },
155
+ {
156
+ lookup: {
157
+ prices: {
158
+ '[0, 0.008_192]': 2,
159
+ '[0.008_193, 0.032_768]': 5,
160
+ '[0.032_769, 0.131_072]': 10,
161
+ },
162
+ pricingParams: ['textInput'],
163
+ },
164
+ name: 'textInput',
165
+ strategy: 'lookup',
166
+ unit: 'millionTokens',
167
+ },
168
+ {
169
+ lookup: {
170
+ prices: {
171
+ '[0, 0.008_192]': 10,
172
+ '[0.008_193, 0.032_768]': 20,
173
+ '[0.032_769, 0.131_072]': 30,
174
+ },
175
+ pricingParams: ['textInput'],
176
+ },
177
+ name: 'textOutput',
178
+ strategy: 'lookup',
179
+ unit: 'millionTokens',
180
+ },
131
181
  ],
132
182
  },
133
183
  releasedAt: '2025-02-17',
@@ -138,7 +188,8 @@ const moonshotChatModels: AIChatModelCard[] = [
138
188
  functionCall: true,
139
189
  },
140
190
  contextWindowTokens: 131_072,
141
- description: 'Moonshot V1 Auto selects the appropriate model based on current context token usage.',
191
+ description:
192
+ 'Moonshot V1 Auto selects the appropriate model based on current context token usage.',
142
193
  displayName: 'Moonshot V1 Auto',
143
194
  id: 'moonshot-v1-auto',
144
195
  pricing: {
@@ -1,6 +1,20 @@
1
1
  import { AIChatModelCard } from '../types/aiModel';
2
2
 
3
3
  const ollamaCloudModels: AIChatModelCard[] = [
4
+ {
5
+ abilities: {
6
+ functionCall: true,
7
+ reasoning: true,
8
+ vision: true,
9
+ },
10
+ contextWindowTokens: 262_144,
11
+ description:
12
+ 'Kimi K2.5 is an open-source, native multimodal agentic model that seamlessly integrates vision and language understanding with advanced agentic capabilities, instant and thinking modes, as well as conversational and agentic paradigms.',
13
+ displayName: 'Kimi K2.5',
14
+ enabled: true,
15
+ id: 'kimi-k2.5',
16
+ type: 'chat',
17
+ },
4
18
  {
5
19
  abilities: {
6
20
  functionCall: true,
@@ -1079,20 +1079,6 @@ const openrouterChatModels: AIChatModelCard[] = [
1079
1079
  id: 'google/gemma-2-9b-it:free',
1080
1080
  type: 'chat',
1081
1081
  },
1082
- {
1083
- abilities: {
1084
- functionCall: true,
1085
- vision: true,
1086
- },
1087
- contextWindowTokens: 1_048_576 + 8192,
1088
- description:
1089
- 'Gemini 2.0 Flash Experimental is Google’s latest experimental multimodal AI model with quality improvements over prior versions, especially in world knowledge, code, and long context.',
1090
- displayName: 'Gemini 2.0 Flash Experimental (Free)',
1091
- id: 'google/gemini-2.0-flash-exp:free',
1092
- maxOutput: 8192,
1093
- releasedAt: '2024-12-11',
1094
- type: 'chat',
1095
- },
1096
1082
  ];
1097
1083
 
1098
1084
  export const allModels = [...openrouterChatModels];
@@ -3,6 +3,55 @@ import { AIChatModelCard, AIImageModelCard } from '../types/aiModel';
3
3
  // https://help.aliyun.com/zh/model-studio/models?spm=a2c4g.11186623
4
4
 
5
5
  const qwenChatModels: AIChatModelCard[] = [
6
+ {
7
+ abilities: {
8
+ functionCall: true,
9
+ reasoning: true,
10
+ vision: true,
11
+ },
12
+ contextWindowTokens: 262_144,
13
+ description:
14
+ 'Kimi K2.5 is the most capable Kimi model, delivering open-source SOTA in agent tasks, coding, and vision understanding. It supports multimodal inputs and both thinking and non-thinking modes.',
15
+ displayName: 'Kimi K2.5',
16
+ id: 'kimi-k2.5',
17
+ maxOutput: 32_768,
18
+ organization: 'Qwen',
19
+ pricing: {
20
+ currency: 'CNY',
21
+ units: [
22
+ { name: 'textInput', rate: 4, strategy: 'fixed', unit: 'millionTokens' },
23
+ { name: 'textOutput', rate: 21, strategy: 'fixed', unit: 'millionTokens' },
24
+ ],
25
+ },
26
+ settings: {
27
+ extendParams: ['enableReasoning', 'reasoningBudgetToken'],
28
+ },
29
+ type: 'chat',
30
+ },
31
+ {
32
+ abilities: {
33
+ functionCall: true,
34
+ reasoning: true,
35
+ search: true,
36
+ },
37
+ contextWindowTokens: 204_800,
38
+ description:
39
+ 'MiniMax-M2.1 is a flagship open-source large model from MiniMax, focusing on solving complex real-world tasks. Its core strengths are multi-language programming capabilities and the ability to solve complex tasks as an Agent.',
40
+ displayName: 'MiniMax-M2.1',
41
+ id: 'MiniMax-M2.1',
42
+ maxOutput: 32_768,
43
+ pricing: {
44
+ currency: 'CNY',
45
+ units: [
46
+ { name: 'textInput', rate: 2.1, strategy: 'fixed', unit: 'millionTokens' },
47
+ { name: 'textOutput', rate: 8.4, strategy: 'fixed', unit: 'millionTokens' },
48
+ ],
49
+ },
50
+ settings: {
51
+ searchImpl: 'params',
52
+ },
53
+ type: 'chat',
54
+ },
6
55
  {
7
56
  abilities: {
8
57
  reasoning: true,
@@ -61,7 +110,7 @@ const qwenChatModels: AIChatModelCard[] = [
61
110
  vision: true,
62
111
  },
63
112
  config: {
64
- deploymentName: 'qwen3-vl-flash-2025-10-15',
113
+ deploymentName: 'qwen3-vl-flash-2026-01-22',
65
114
  },
66
115
  contextWindowTokens: 262_144,
67
116
  description:
@@ -101,7 +150,6 @@ const qwenChatModels: AIChatModelCard[] = [
101
150
  },
102
151
  ],
103
152
  },
104
- releasedAt: '2025-10-15',
105
153
  settings: {
106
154
  extendParams: ['enableReasoning', 'reasoningBudgetToken'],
107
155
  },
@@ -1019,7 +1067,8 @@ const qwenChatModels: AIChatModelCard[] = [
1019
1067
  deploymentName: 'qwen-plus-2025-12-01',
1020
1068
  },
1021
1069
  contextWindowTokens: 1_000_000,
1022
- description: 'Enhanced ultra-large Qwen model supporting Chinese, English, and other languages.',
1070
+ description:
1071
+ 'Enhanced ultra-large Qwen model supporting Chinese, English, and other languages.',
1023
1072
  displayName: 'Qwen Plus',
1024
1073
  enabled: true,
1025
1074
  id: 'qwen-plus',
@@ -1078,6 +1127,57 @@ const qwenChatModels: AIChatModelCard[] = [
1078
1127
  },
1079
1128
  type: 'chat',
1080
1129
  },
1130
+ {
1131
+ abilities: {
1132
+ functionCall: true,
1133
+ search: true,
1134
+ reasoning: true,
1135
+ },
1136
+ contextWindowTokens: 262_144,
1137
+ description:
1138
+ 'Qwen3 Max models deliver large gains over the 2.5 series in general ability, Chinese/English understanding, complex instruction following, subjective open tasks, multilingual ability, and tool use, with fewer hallucinations. The latest qwen3-max improves agentic programming and tool use over qwen3-max-preview. This release reaches field SOTA and targets more complex agent needs.',
1139
+ displayName: 'Qwen3 Max Thinking',
1140
+ id: 'qwen3-max-2026-01-23',
1141
+ maxOutput: 65_536,
1142
+ organization: 'Qwen',
1143
+ pricing: {
1144
+ currency: 'CNY',
1145
+ units: [
1146
+ {
1147
+ lookup: {
1148
+ prices: {
1149
+ '[0, 0.032]': 2.5,
1150
+ '[0.032, 0.128]': 4,
1151
+ '[0.128, 0.252]': 7,
1152
+ },
1153
+ pricingParams: ['textInputRange'],
1154
+ },
1155
+ name: 'textInput',
1156
+ strategy: 'lookup',
1157
+ unit: 'millionTokens',
1158
+ },
1159
+ {
1160
+ lookup: {
1161
+ prices: {
1162
+ '[0, 0.032]': 10,
1163
+ '[0.032, 0.128]': 16,
1164
+ '[0.128, 0.252]': 28,
1165
+ },
1166
+ pricingParams: ['textInputRange'],
1167
+ },
1168
+ name: 'textOutput',
1169
+ strategy: 'lookup',
1170
+ unit: 'millionTokens',
1171
+ },
1172
+ ],
1173
+ },
1174
+ releasedAt: '2026-01-23',
1175
+ settings: {
1176
+ extendParams: ['enableReasoning', 'reasoningBudgetToken'],
1177
+ searchImpl: 'params',
1178
+ },
1179
+ type: 'chat',
1180
+ },
1081
1181
  {
1082
1182
  abilities: {
1083
1183
  functionCall: true,
@@ -1477,7 +1577,8 @@ const qwenChatModels: AIChatModelCard[] = [
1477
1577
  vision: true,
1478
1578
  },
1479
1579
  contextWindowTokens: 131_072,
1480
- description: 'Qwen3 VL 8B non-thinking mode (Instruct) for standard multimodal generation and recognition.',
1580
+ description:
1581
+ 'Qwen3 VL 8B non-thinking mode (Instruct) for standard multimodal generation and recognition.',
1481
1582
  displayName: 'Qwen3 VL 8B Instruct',
1482
1583
  id: 'qwen3-vl-8b-instruct',
1483
1584
  maxOutput: 32_768,
@@ -2,6 +2,45 @@ import { AIChatModelCard, AIImageModelCard } from '../types/aiModel';
2
2
 
3
3
  // https://siliconflow.cn/zh-cn/models
4
4
  const siliconcloudChatModels: AIChatModelCard[] = [
5
+ {
6
+ abilities: {
7
+ functionCall: true,
8
+ reasoning: true,
9
+ vision: true,
10
+ },
11
+ contextWindowTokens: 262_144,
12
+ description:
13
+ 'Kimi K2.5 is an open-source native multimodal agent model, built on Kimi-K2-Base, trained on approximately 1.5 trillion mixed vision and text tokens. The model adopts an MoE architecture with 1T total parameters and 32B active parameters, supporting a 256K context window, seamlessly integrating vision and language understanding capabilities.',
14
+ displayName: 'Kimi-K2.5 (Pro)',
15
+ id: 'Pro/moonshotai/Kimi-K2.5',
16
+ pricing: {
17
+ currency: 'CNY',
18
+ units: [
19
+ { name: 'textInput', rate: 4, strategy: 'fixed', unit: 'millionTokens' },
20
+ { name: 'textOutput', rate: 21, strategy: 'fixed', unit: 'millionTokens' },
21
+ ],
22
+ },
23
+ releasedAt: '2026-01-27',
24
+ type: 'chat',
25
+ },
26
+ {
27
+ abilities: {
28
+ vision: true,
29
+ },
30
+ description:
31
+ 'PaddleOCR-VL-1.5 is an upgraded version of the PaddleOCR-VL series, achieving 94.5% accuracy on the OmniDocBench v1.5 document parsing benchmark, surpassing leading general large models and specialized document parsing models. It innovatively supports irregular bounding box localization for document elements, handling scanned, tilted, and screen-captured images effectively.',
32
+ displayName: 'PaddleOCR-VL 1.5',
33
+ id: 'PaddlePaddle/PaddleOCR-VL-1.5',
34
+ pricing: {
35
+ currency: 'CNY',
36
+ units: [
37
+ { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
38
+ { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
39
+ ],
40
+ },
41
+ releasedAt: '2026-01-29',
42
+ type: 'chat',
43
+ },
5
44
  {
6
45
  abilities: {
7
46
  functionCall: true,
@@ -191,37 +191,6 @@ const wenxinChatModels: AIChatModelCard[] = [
191
191
  },
192
192
  type: 'chat',
193
193
  },
194
- {
195
- contextWindowTokens: 131_072,
196
- description:
197
- 'ERNIE Speed 128K is a no-I/O-fee model for long-text understanding and large-scale trials.',
198
- displayName: 'ERNIE Speed 128K',
199
- id: 'ernie-speed-128k',
200
- maxOutput: 4096,
201
- pricing: {
202
- currency: 'CNY',
203
- units: [
204
- { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
205
- { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
206
- ],
207
- },
208
- type: 'chat',
209
- },
210
- {
211
- contextWindowTokens: 8192,
212
- description: 'ERNIE Speed 8K is a free, fast model for daily chat and light text tasks.',
213
- displayName: 'ERNIE Speed 8K',
214
- id: 'ernie-speed-8k',
215
- maxOutput: 2048,
216
- pricing: {
217
- currency: 'CNY',
218
- units: [
219
- { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
220
- { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
221
- ],
222
- },
223
- type: 'chat',
224
- },
225
194
  {
226
195
  contextWindowTokens: 131_072,
227
196
  description:
@@ -238,22 +207,6 @@ const wenxinChatModels: AIChatModelCard[] = [
238
207
  },
239
208
  type: 'chat',
240
209
  },
241
- {
242
- contextWindowTokens: 8192,
243
- description:
244
- 'ERNIE Lite 8K is a lightweight general model for cost-sensitive daily QA and content generation.',
245
- displayName: 'ERNIE Lite 8K',
246
- id: 'ernie-lite-8k',
247
- maxOutput: 2048,
248
- pricing: {
249
- currency: 'CNY',
250
- units: [
251
- { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
252
- { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
253
- ],
254
- },
255
- type: 'chat',
256
- },
257
210
  {
258
211
  abilities: {
259
212
  functionCall: true,
@@ -273,22 +226,6 @@ const wenxinChatModels: AIChatModelCard[] = [
273
226
  },
274
227
  type: 'chat',
275
228
  },
276
- {
277
- contextWindowTokens: 8192,
278
- description:
279
- 'ERNIE Tiny 8K is ultra-lightweight for simple QA, classification, and low-cost inference.',
280
- displayName: 'ERNIE Tiny 8K',
281
- id: 'ernie-tiny-8k',
282
- maxOutput: 2048,
283
- pricing: {
284
- currency: 'CNY',
285
- units: [
286
- { name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
287
- { name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
288
- ],
289
- },
290
- type: 'chat',
291
- },
292
229
  {
293
230
  contextWindowTokens: 8192,
294
231
  description:
@@ -486,24 +423,6 @@ const wenxinChatModels: AIChatModelCard[] = [
486
423
  maxOutput: 2048,
487
424
  type: 'chat',
488
425
  },
489
- {
490
- contextWindowTokens: 32_768,
491
- description:
492
- 'Qianfan Agent Speed 32K is a high-throughput agent model for large-scale, multi-task agent apps.',
493
- displayName: 'Qianfan Agent Speed 32K',
494
- id: 'qianfan-agent-speed-32k',
495
- maxOutput: 4096,
496
- type: 'chat',
497
- },
498
- {
499
- contextWindowTokens: 8192,
500
- description:
501
- 'Qianfan Agent Speed 8K is a high-concurrency agent model for short-to-mid conversations and fast response.',
502
- displayName: 'Qianfan Agent Speed 8K',
503
- id: 'qianfan-agent-speed-8k',
504
- maxOutput: 2048,
505
- type: 'chat',
506
- },
507
426
  {
508
427
  abilities: {
509
428
  vision: true,
@@ -1616,24 +1535,6 @@ const wenxinChatModels: AIChatModelCard[] = [
1616
1535
  },
1617
1536
  type: 'chat',
1618
1537
  },
1619
- {
1620
- contextWindowTokens: 32_768,
1621
- description: 'Qwen3 235B A22B is a general large model for complex tasks.',
1622
- displayName: 'Qwen3 235B A22B',
1623
- id: 'qwen3-235b-a22b',
1624
- maxOutput: 8192,
1625
- pricing: {
1626
- currency: 'CNY',
1627
- units: [
1628
- { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' },
1629
- { name: 'textOutput', rate: 8, strategy: 'fixed', unit: 'millionTokens' },
1630
- ],
1631
- },
1632
- settings: {
1633
- extendParams: ['enableReasoning', 'reasoningBudgetToken'],
1634
- },
1635
- type: 'chat',
1636
- },
1637
1538
  {
1638
1539
  contextWindowTokens: 32_768,
1639
1540
  description: 'Qwen3 30B A3B is a mid-large general model balancing cost and quality.',
@@ -73,6 +73,30 @@ describe('convertMessageContent', () => {
73
73
  expect(result).toEqual(content);
74
74
  expect(imageUrlToBase64).not.toHaveBeenCalled();
75
75
  });
76
+
77
+ it('should convert image URL when forceImageBase64 is true', async () => {
78
+ process.env.LLM_VISION_IMAGE_USE_BASE64 = undefined;
79
+
80
+ const content = {
81
+ type: 'image_url',
82
+ image_url: { url: 'https://example.com/image.jpg' },
83
+ } as OpenAI.ChatCompletionContentPart;
84
+
85
+ vi.mocked(parseDataUri).mockReturnValue({ type: 'url', base64: null, mimeType: null });
86
+ vi.mocked(imageUrlToBase64).mockResolvedValue({
87
+ base64: 'forcedBase64',
88
+ mimeType: 'image/jpeg',
89
+ });
90
+
91
+ const result = await convertMessageContent(content, { forceImageBase64: true });
92
+
93
+ expect(result).toEqual({
94
+ type: 'image_url',
95
+ image_url: { url: 'data:image/jpeg;base64,forcedBase64' },
96
+ });
97
+
98
+ expect(imageUrlToBase64).toHaveBeenCalledWith('https://example.com/image.jpg');
99
+ });
76
100
  });
77
101
 
78
102
  describe('convertOpenAIMessages', () => {
@@ -5,13 +5,21 @@ import { disableStreamModels, systemToUserModels } from '../../const/models';
5
5
  import { ChatStreamPayload, OpenAIChatMessage } from '../../types';
6
6
  import { parseDataUri } from '../../utils/uriParser';
7
7
 
8
+ type ConvertMessageContentOptions = {
9
+ forceImageBase64?: boolean;
10
+ };
11
+
8
12
  export const convertMessageContent = async (
9
13
  content: OpenAI.ChatCompletionContentPart,
14
+ options?: ConvertMessageContentOptions,
10
15
  ): Promise<OpenAI.ChatCompletionContentPart> => {
11
16
  if (content.type === 'image_url') {
12
17
  const { type } = parseDataUri(content.image_url.url);
13
18
 
14
- if (type === 'url' && process.env.LLM_VISION_IMAGE_USE_BASE64 === '1') {
19
+ const shouldUseBase64 =
20
+ options?.forceImageBase64 || process.env.LLM_VISION_IMAGE_USE_BASE64 === '1';
21
+
22
+ if (type === 'url' && shouldUseBase64) {
15
23
  const { base64, mimeType } = await imageUrlToBase64(content.image_url.url);
16
24
 
17
25
  return {
@@ -24,7 +32,10 @@ export const convertMessageContent = async (
24
32
  return content;
25
33
  };
26
34
 
27
- export const convertOpenAIMessages = async (messages: OpenAI.ChatCompletionMessageParam[]) => {
35
+ export const convertOpenAIMessages = async (
36
+ messages: OpenAI.ChatCompletionMessageParam[],
37
+ options?: ConvertMessageContentOptions,
38
+ ) => {
28
39
  return (await Promise.all(
29
40
  messages.map(async (message) => {
30
41
  const msg = message as any;
@@ -37,7 +48,7 @@ export const convertOpenAIMessages = async (messages: OpenAI.ChatCompletionMessa
37
48
  ? message.content
38
49
  : await Promise.all(
39
50
  (message.content || []).map((c) =>
40
- convertMessageContent(c as OpenAI.ChatCompletionContentPart),
51
+ convertMessageContent(c as OpenAI.ChatCompletionContentPart, options),
41
52
  ),
42
53
  ),
43
54
  role: msg.role,
@@ -59,7 +70,10 @@ export const convertOpenAIMessages = async (messages: OpenAI.ChatCompletionMessa
59
70
  )) as OpenAI.ChatCompletionMessageParam[];
60
71
  };
61
72
 
62
- export const convertOpenAIResponseInputs = async (messages: OpenAIChatMessage[]) => {
73
+ export const convertOpenAIResponseInputs = async (
74
+ messages: OpenAIChatMessage[],
75
+ options?: ConvertMessageContentOptions,
76
+ ) => {
63
77
  let input: OpenAI.Responses.ResponseInputItem[] = [];
64
78
  await Promise.all(
65
79
  messages.map(async (message) => {
@@ -113,7 +127,10 @@ export const convertOpenAIResponseInputs = async (messages: OpenAIChatMessage[])
113
127
  return { ...c, type: 'input_text' };
114
128
  }
115
129
 
116
- const image = await convertMessageContent(c as OpenAI.ChatCompletionContentPart);
130
+ const image = await convertMessageContent(
131
+ c as OpenAI.ChatCompletionContentPart,
132
+ options,
133
+ );
117
134
  return {
118
135
  image_url: (image as OpenAI.ChatCompletionContentPartImage).image_url?.url,
119
136
  type: 'input_image',