@lobehub/lobehub 2.0.9 → 2.0.10
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 +25 -0
- package/changelog/v2.json +9 -0
- package/package.json +1 -1
- package/packages/model-bank/src/aiModels/cerebras.ts +2 -22
- package/packages/model-bank/src/aiModels/google.ts +1 -44
- package/packages/model-bank/src/aiModels/nvidia.ts +12 -16
- package/packages/model-bank/src/aiModels/siliconcloud.ts +20 -0
- package/packages/model-bank/src/aiModels/volcengine.ts +69 -0
- package/packages/model-bank/src/aiModels/wenxin.ts +41 -38
- package/packages/model-bank/src/aiModels/zhipu.ts +58 -28
- package/packages/model-bank/src/types/aiModel.ts +29 -0
- package/packages/model-runtime/src/core/usageConverters/utils/computeChatCost.test.ts +2 -2
- package/packages/model-runtime/src/providers/google/createImage.test.ts +12 -12
- package/packages/model-runtime/src/providers/openrouter/index.test.ts +102 -0
- package/packages/model-runtime/src/providers/openrouter/index.ts +19 -7
- package/packages/model-runtime/src/providers/vercelaigateway/index.test.ts +47 -0
- package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 2.0.10](https://github.com/lobehub/lobe-chat/compare/v2.0.9...v2.0.10)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-29**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Add ExtendParamsTypeSchema for enhanced model settings.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Add ExtendParamsTypeSchema for enhanced model settings, closes [#11437](https://github.com/lobehub/lobe-chat/issues/11437) ([f58c980](https://github.com/lobehub/lobe-chat/commit/f58c980))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
### [Version 2.0.9](https://github.com/lobehub/lobe-chat/compare/v2.0.8...v2.0.9)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2026-01-29**</sup>
|
package/changelog/v2.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
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",
|
|
@@ -1,27 +1,6 @@
|
|
|
1
1
|
import { AIChatModelCard } from '../types/aiModel';
|
|
2
2
|
|
|
3
3
|
const cerebrasModels: AIChatModelCard[] = [
|
|
4
|
-
{
|
|
5
|
-
abilities: {
|
|
6
|
-
functionCall: true,
|
|
7
|
-
reasoning: true,
|
|
8
|
-
structuredOutput: true,
|
|
9
|
-
},
|
|
10
|
-
contextWindowTokens: 131_072,
|
|
11
|
-
description:
|
|
12
|
-
'Performs well on coding and reasoning tasks, supports streaming and tool calls, and fits agentic coding and complex reasoning.',
|
|
13
|
-
displayName: 'GLM-4.6',
|
|
14
|
-
enabled: true,
|
|
15
|
-
id: 'zai-glm-4.6',
|
|
16
|
-
maxOutput: 40_000,
|
|
17
|
-
pricing: {
|
|
18
|
-
units: [
|
|
19
|
-
{ name: 'textInput', rate: 2.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
20
|
-
{ name: 'textOutput', rate: 2.75, strategy: 'fixed', unit: 'millionTokens' },
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
type: 'chat',
|
|
24
|
-
},
|
|
25
4
|
{
|
|
26
5
|
abilities: {
|
|
27
6
|
functionCall: true,
|
|
@@ -96,7 +75,8 @@ const cerebrasModels: AIChatModelCard[] = [
|
|
|
96
75
|
functionCall: true,
|
|
97
76
|
},
|
|
98
77
|
contextWindowTokens: 32_768,
|
|
99
|
-
description:
|
|
78
|
+
description:
|
|
79
|
+
'Llama 3.1 8B: a small, low-latency Llama variant for lightweight online inference and chat.',
|
|
100
80
|
displayName: 'Llama 3.1 8B',
|
|
101
81
|
id: 'llama3.1-8b',
|
|
102
82
|
pricing: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ModelParamsSchema } from '../standard-parameters';
|
|
2
2
|
import { AIChatModelCard, AIImageModelCard } from '../types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -485,32 +485,6 @@ const googleChatModels: AIChatModelCard[] = [
|
|
|
485
485
|
},
|
|
486
486
|
type: 'chat',
|
|
487
487
|
},
|
|
488
|
-
{
|
|
489
|
-
abilities: {
|
|
490
|
-
imageOutput: true,
|
|
491
|
-
vision: true,
|
|
492
|
-
},
|
|
493
|
-
contextWindowTokens: 32_768 + 8192,
|
|
494
|
-
description:
|
|
495
|
-
'Nano Banana is Google’s newest, fastest, and most efficient native multimodal model, enabling conversational image generation and editing.',
|
|
496
|
-
displayName: 'Nano Banana (Preview)',
|
|
497
|
-
id: 'gemini-2.5-flash-image-preview',
|
|
498
|
-
maxOutput: 8192,
|
|
499
|
-
pricing: {
|
|
500
|
-
approximatePricePerImage: 0.039,
|
|
501
|
-
units: [
|
|
502
|
-
{ name: 'textInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' },
|
|
503
|
-
{ name: 'imageInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' },
|
|
504
|
-
{ name: 'textOutput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' },
|
|
505
|
-
{ name: 'imageOutput', rate: 30, strategy: 'fixed', unit: 'millionTokens' },
|
|
506
|
-
],
|
|
507
|
-
},
|
|
508
|
-
releasedAt: '2025-08-26',
|
|
509
|
-
settings: {
|
|
510
|
-
extendParams: ['imageAspectRatio'],
|
|
511
|
-
},
|
|
512
|
-
type: 'chat',
|
|
513
|
-
},
|
|
514
488
|
{
|
|
515
489
|
abilities: {
|
|
516
490
|
functionCall: true,
|
|
@@ -967,23 +941,6 @@ const googleImageModels: AIImageModelCard[] = [
|
|
|
967
941
|
],
|
|
968
942
|
},
|
|
969
943
|
},
|
|
970
|
-
{
|
|
971
|
-
displayName: 'Nano Banana (Preview)',
|
|
972
|
-
id: 'gemini-2.5-flash-image-preview:image',
|
|
973
|
-
type: 'image',
|
|
974
|
-
description:
|
|
975
|
-
'Nano Banana is Google’s newest, fastest, and most efficient native multimodal model, enabling conversational image generation and editing.',
|
|
976
|
-
releasedAt: '2025-08-26',
|
|
977
|
-
parameters: CHAT_MODEL_IMAGE_GENERATION_PARAMS,
|
|
978
|
-
pricing: {
|
|
979
|
-
approximatePricePerImage: 0.039,
|
|
980
|
-
units: [
|
|
981
|
-
{ name: 'textInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' },
|
|
982
|
-
{ name: 'textOutput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' },
|
|
983
|
-
{ name: 'imageOutput', rate: 30, strategy: 'fixed', unit: 'millionTokens' },
|
|
984
|
-
],
|
|
985
|
-
},
|
|
986
|
-
},
|
|
987
944
|
{
|
|
988
945
|
displayName: 'Imagen 4',
|
|
989
946
|
id: 'imagen-4.0-generate-001',
|
|
@@ -79,7 +79,8 @@ const nvidiaChatModels: AIChatModelCard[] = [
|
|
|
79
79
|
vision: true,
|
|
80
80
|
},
|
|
81
81
|
contextWindowTokens: 128_000,
|
|
82
|
-
description:
|
|
82
|
+
description:
|
|
83
|
+
'A frontier vision-language model that excels at high-quality reasoning from images.',
|
|
83
84
|
displayName: 'Llama 3.2 11B Vision Instruct',
|
|
84
85
|
id: 'meta/llama-3.2-11b-vision-instruct',
|
|
85
86
|
type: 'chat',
|
|
@@ -89,7 +90,8 @@ const nvidiaChatModels: AIChatModelCard[] = [
|
|
|
89
90
|
vision: true,
|
|
90
91
|
},
|
|
91
92
|
contextWindowTokens: 128_000,
|
|
92
|
-
description:
|
|
93
|
+
description:
|
|
94
|
+
'A frontier vision-language model that excels at high-quality reasoning from images.',
|
|
93
95
|
displayName: 'Llama 3.2 90B Vision Instruct',
|
|
94
96
|
id: 'meta/llama-3.2-90b-vision-instruct',
|
|
95
97
|
type: 'chat',
|
|
@@ -151,41 +153,35 @@ const nvidiaChatModels: AIChatModelCard[] = [
|
|
|
151
153
|
},
|
|
152
154
|
{
|
|
153
155
|
contextWindowTokens: 8192,
|
|
154
|
-
description:
|
|
156
|
+
description:
|
|
157
|
+
'A frontier text generation model strong in understanding, transformation, and code generation.',
|
|
155
158
|
displayName: 'Gemma 2 9B Instruct',
|
|
156
159
|
id: 'google/gemma-2-9b-it',
|
|
157
160
|
type: 'chat',
|
|
158
161
|
},
|
|
159
162
|
{
|
|
160
163
|
contextWindowTokens: 8192,
|
|
161
|
-
description:
|
|
164
|
+
description:
|
|
165
|
+
'A frontier text generation model strong in understanding, transformation, and code generation.',
|
|
162
166
|
displayName: 'Gemma 2 27B Instruct',
|
|
163
167
|
id: 'google/gemma-2-27b-it',
|
|
164
168
|
type: 'chat',
|
|
165
169
|
},
|
|
166
|
-
{
|
|
167
|
-
abilities: {
|
|
168
|
-
reasoning: true,
|
|
169
|
-
},
|
|
170
|
-
contextWindowTokens: 128_000,
|
|
171
|
-
description: 'A state-of-the-art efficient LLM strong in reasoning, math, and programming.',
|
|
172
|
-
displayName: 'DeepSeek R1',
|
|
173
|
-
id: 'deepseek-ai/deepseek-r1',
|
|
174
|
-
type: 'chat',
|
|
175
|
-
},
|
|
176
170
|
{
|
|
177
171
|
abilities: {
|
|
178
172
|
functionCall: true,
|
|
179
173
|
},
|
|
180
174
|
contextWindowTokens: 32_768,
|
|
181
|
-
description:
|
|
175
|
+
description:
|
|
176
|
+
'A bilingual LLM for Chinese and English across language, coding, math, and reasoning.',
|
|
182
177
|
displayName: 'Qwen2.5 7B Instruct',
|
|
183
178
|
id: 'qwen/qwen2.5-7b-instruct',
|
|
184
179
|
type: 'chat',
|
|
185
180
|
},
|
|
186
181
|
{
|
|
187
182
|
contextWindowTokens: 32_768,
|
|
188
|
-
description:
|
|
183
|
+
description:
|
|
184
|
+
'A strong mid-sized code model with 32K context, excelling at multilingual programming.',
|
|
189
185
|
displayName: 'Qwen2.5 Coder 7B Instruct',
|
|
190
186
|
id: 'qwen/qwen2.5-coder-7b-instruct',
|
|
191
187
|
type: 'chat',
|
|
@@ -2,6 +2,26 @@ 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
|
+
},
|
|
10
|
+
contextWindowTokens: 192_000,
|
|
11
|
+
description:
|
|
12
|
+
'MiniMax-M2.1 is an open-source large language model optimized for agent capabilities, excelling in programming, tool usage, instruction following, and long-term planning. The model supports multilingual software development and complex multi-step workflow execution, achieving a score of 74.0 on SWE-bench Verified and surpassing Claude Sonnet 4.5 in multilingual scenarios.',
|
|
13
|
+
displayName: 'MiniMax-M2.1 (Pro)',
|
|
14
|
+
id: 'Pro/MiniMaxAI/MiniMax-M2.1',
|
|
15
|
+
pricing: {
|
|
16
|
+
currency: 'CNY',
|
|
17
|
+
units: [
|
|
18
|
+
{ name: 'textInput', rate: 2.1, strategy: 'fixed', unit: 'millionTokens' },
|
|
19
|
+
{ name: 'textOutput', rate: 8.4, strategy: 'fixed', unit: 'millionTokens' },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
releasedAt: '2025-12-23',
|
|
23
|
+
type: 'chat',
|
|
24
|
+
},
|
|
5
25
|
{
|
|
6
26
|
abilities: {
|
|
7
27
|
functionCall: true,
|
|
@@ -117,6 +117,75 @@ const doubaoChatModels: AIChatModelCard[] = [
|
|
|
117
117
|
},
|
|
118
118
|
type: 'chat',
|
|
119
119
|
},
|
|
120
|
+
{
|
|
121
|
+
abilities: {
|
|
122
|
+
functionCall: true,
|
|
123
|
+
reasoning: true,
|
|
124
|
+
},
|
|
125
|
+
config: {
|
|
126
|
+
deploymentName: 'glm-4-7-251222',
|
|
127
|
+
},
|
|
128
|
+
contextWindowTokens: 200_000,
|
|
129
|
+
description:
|
|
130
|
+
'GLM-4.7 is the latest flagship model from Zhipu AI. GLM-4.7 enhances coding capabilities, long-term task planning, and tool collaboration for Agentic Coding scenarios, achieving leading performance among open-source models in multiple public benchmarks. General capabilities are improved, with more concise and natural responses, and more immersive writing. In complex agent tasks, instruction following is stronger during tool calls, and the aesthetics of Artifacts and Agentic Coding frontend, as well as long-term task completion efficiency, are further enhanced. • Stronger programming capabilities: Significantly improved multi-language coding and terminal agent performance; GLM-4.7 can now implement "think first, then act" mechanisms in programming frameworks like Claude Code, Kilo Code, TRAE, Cline, and Roo Code, with more stable performance on complex tasks. • Frontend aesthetics improvement: GLM-4.7 shows significant progress in frontend generation quality, capable of generating websites, PPTs, and posters with better visual appeal. • Stronger tool calling capabilities: GLM-4.7 enhances tool calling abilities, scoring 67 in BrowseComp web task evaluation; achieving 84.7 in τ²-Bench interactive tool calling evaluation, surpassing Claude Sonnet 4.5 as the open-source SOTA. • Reasoning capability improvement: Significantly enhanced math and reasoning abilities, scoring 42.8% in the HLE ("Humanity\'s Last Exam") benchmark, a 41% improvement over GLM-4.6, surpassing GPT-5.1. • General capability enhancement: GLM-4.7 conversations are more concise, intelligent, and humane; writing and role-playing are more literary and immersive.',
|
|
131
|
+
displayName: 'GLM-4.7',
|
|
132
|
+
id: 'glm-4-7',
|
|
133
|
+
maxOutput: 128_000,
|
|
134
|
+
pricing: {
|
|
135
|
+
currency: 'CNY',
|
|
136
|
+
units: [
|
|
137
|
+
{
|
|
138
|
+
lookup: {
|
|
139
|
+
prices: {
|
|
140
|
+
'[0, 0.032]_[0, 0.0002]': 2,
|
|
141
|
+
'[0, 0.032]_[0.0002, infinity]': 3,
|
|
142
|
+
'[0.032, 0.2]_[0, infinity]': 4,
|
|
143
|
+
},
|
|
144
|
+
pricingParams: ['textInputRange', 'textOutputRange'],
|
|
145
|
+
},
|
|
146
|
+
name: 'textInput',
|
|
147
|
+
strategy: 'lookup',
|
|
148
|
+
unit: 'millionTokens',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
lookup: {
|
|
152
|
+
prices: {
|
|
153
|
+
'[0, 0.032]_[0, 0.0002]': 8,
|
|
154
|
+
'[0, 0.032]_[0.0002, infinity]': 14,
|
|
155
|
+
'[0.032, 0.2]_[0, infinity]': 16,
|
|
156
|
+
},
|
|
157
|
+
pricingParams: ['textInputRange', 'textOutputRange'],
|
|
158
|
+
},
|
|
159
|
+
name: 'textOutput',
|
|
160
|
+
strategy: 'lookup',
|
|
161
|
+
unit: 'millionTokens',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
lookup: {
|
|
165
|
+
prices: {
|
|
166
|
+
'[0, 0.032]_[0, 0.0002]': 0.4,
|
|
167
|
+
'[0, 0.032]_[0.0002, infinity]': 0.6,
|
|
168
|
+
'[0.032, 0.2]_[0, infinity]': 0.8,
|
|
169
|
+
},
|
|
170
|
+
pricingParams: ['textInputRange', 'textOutputRange'],
|
|
171
|
+
},
|
|
172
|
+
name: 'textInput_cacheRead',
|
|
173
|
+
strategy: 'lookup',
|
|
174
|
+
unit: 'millionTokens',
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
lookup: { prices: { '1h': 0.017 }, pricingParams: ['ttl'] },
|
|
178
|
+
name: 'textInput_cacheWrite',
|
|
179
|
+
strategy: 'lookup',
|
|
180
|
+
unit: 'millionTokens',
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
settings: {
|
|
185
|
+
extendParams: ['enableReasoning'],
|
|
186
|
+
},
|
|
187
|
+
type: 'chat',
|
|
188
|
+
},
|
|
120
189
|
{
|
|
121
190
|
abilities: {
|
|
122
191
|
functionCall: true,
|
|
@@ -193,7 +193,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
contextWindowTokens: 131_072,
|
|
196
|
-
description:
|
|
196
|
+
description:
|
|
197
|
+
'ERNIE Speed 128K is a no-I/O-fee model for long-text understanding and large-scale trials.',
|
|
197
198
|
displayName: 'ERNIE Speed 128K',
|
|
198
199
|
id: 'ernie-speed-128k',
|
|
199
200
|
maxOutput: 4096,
|
|
@@ -274,7 +275,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
274
275
|
},
|
|
275
276
|
{
|
|
276
277
|
contextWindowTokens: 8192,
|
|
277
|
-
description:
|
|
278
|
+
description:
|
|
279
|
+
'ERNIE Tiny 8K is ultra-lightweight for simple QA, classification, and low-cost inference.',
|
|
278
280
|
displayName: 'ERNIE Tiny 8K',
|
|
279
281
|
id: 'ernie-tiny-8k',
|
|
280
282
|
maxOutput: 2048,
|
|
@@ -337,7 +339,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
337
339
|
},
|
|
338
340
|
{
|
|
339
341
|
contextWindowTokens: 8192,
|
|
340
|
-
description:
|
|
342
|
+
description:
|
|
343
|
+
'ERNIE Novel 8K is built for long-form novels and IP plots with multi-character narratives.',
|
|
341
344
|
displayName: 'ERNIE Novel 8K',
|
|
342
345
|
id: 'ernie-novel-8k',
|
|
343
346
|
maxOutput: 2048,
|
|
@@ -352,7 +355,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
352
355
|
},
|
|
353
356
|
{
|
|
354
357
|
contextWindowTokens: 131_072,
|
|
355
|
-
description:
|
|
358
|
+
description:
|
|
359
|
+
'ERNIE 4.5 0.3B is an open-source lightweight model for local and customized deployment.',
|
|
356
360
|
displayName: 'ERNIE 4.5 0.3B',
|
|
357
361
|
id: 'ernie-4.5-0.3b',
|
|
358
362
|
maxOutput: 8192,
|
|
@@ -443,7 +447,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
443
447
|
},
|
|
444
448
|
{
|
|
445
449
|
contextWindowTokens: 32_768,
|
|
446
|
-
description:
|
|
450
|
+
description:
|
|
451
|
+
'Qianfan 70B is a large Chinese model for high-quality generation and complex reasoning.',
|
|
447
452
|
displayName: 'Qianfan 70B',
|
|
448
453
|
id: 'qianfan-70b',
|
|
449
454
|
maxOutput: 16_384,
|
|
@@ -628,7 +633,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
628
633
|
vision: true,
|
|
629
634
|
},
|
|
630
635
|
contextWindowTokens: 32_768,
|
|
631
|
-
description:
|
|
636
|
+
description:
|
|
637
|
+
'Qianfan Composition is a multimodal creation model for mixed image-text understanding and generation.',
|
|
632
638
|
displayName: 'Qianfan Composition',
|
|
633
639
|
id: 'qianfan-composition',
|
|
634
640
|
maxOutput: 8192,
|
|
@@ -758,7 +764,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
758
764
|
vision: true,
|
|
759
765
|
},
|
|
760
766
|
contextWindowTokens: 4096,
|
|
761
|
-
description:
|
|
767
|
+
description:
|
|
768
|
+
'Qianfan EngCard VL is a multimodal recognition model focused on English scenarios.',
|
|
762
769
|
displayName: 'Qianfan EngCard VL',
|
|
763
770
|
id: 'qianfan-engcard-vl',
|
|
764
771
|
maxOutput: 4000,
|
|
@@ -776,7 +783,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
776
783
|
vision: true,
|
|
777
784
|
},
|
|
778
785
|
contextWindowTokens: 4096,
|
|
779
|
-
description:
|
|
786
|
+
description:
|
|
787
|
+
'Qianfan SinglePicOCR is a single-image OCR model with high-accuracy character recognition.',
|
|
780
788
|
displayName: 'Qianfan SinglePicOCR',
|
|
781
789
|
id: 'qianfan-singlepicocr',
|
|
782
790
|
maxOutput: 4096,
|
|
@@ -794,7 +802,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
794
802
|
vision: true,
|
|
795
803
|
},
|
|
796
804
|
contextWindowTokens: 32_768,
|
|
797
|
-
description:
|
|
805
|
+
description:
|
|
806
|
+
'InternVL3 38B is a large open-source multimodal model for high-accuracy image-text understanding.',
|
|
798
807
|
displayName: 'InternVL3 38B',
|
|
799
808
|
id: 'internvl3-38b',
|
|
800
809
|
maxOutput: 8192,
|
|
@@ -830,7 +839,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
830
839
|
vision: true,
|
|
831
840
|
},
|
|
832
841
|
contextWindowTokens: 32_768,
|
|
833
|
-
description:
|
|
842
|
+
description:
|
|
843
|
+
'InternVL3 1B is a lightweight multimodal model for resource-constrained deployment.',
|
|
834
844
|
displayName: 'InternVL3 1B',
|
|
835
845
|
id: 'internvl3-1b',
|
|
836
846
|
maxOutput: 8192,
|
|
@@ -848,7 +858,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
848
858
|
vision: true,
|
|
849
859
|
},
|
|
850
860
|
contextWindowTokens: 32_768,
|
|
851
|
-
description:
|
|
861
|
+
description:
|
|
862
|
+
'InternVL2.5 38B MPO is a multimodal pretrained model for complex image-text reasoning.',
|
|
852
863
|
displayName: 'InternVL2.5 38B MPO',
|
|
853
864
|
id: 'internvl2.5-38b-mpo',
|
|
854
865
|
maxOutput: 4096,
|
|
@@ -1056,7 +1067,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1056
1067
|
vision: true,
|
|
1057
1068
|
},
|
|
1058
1069
|
contextWindowTokens: 65_536,
|
|
1059
|
-
description:
|
|
1070
|
+
description:
|
|
1071
|
+
'GLM-4.5V is a multimodal vision-language model for general image understanding and QA.',
|
|
1060
1072
|
displayName: 'GLM-4.5V',
|
|
1061
1073
|
id: 'glm-4.5v',
|
|
1062
1074
|
maxOutput: 16_384,
|
|
@@ -1096,7 +1108,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1096
1108
|
vision: true,
|
|
1097
1109
|
},
|
|
1098
1110
|
contextWindowTokens: 4096,
|
|
1099
|
-
description:
|
|
1111
|
+
description:
|
|
1112
|
+
'DeepSeek VL2 is a multimodal model for image-text understanding and fine-grained visual QA.',
|
|
1100
1113
|
displayName: 'DeepSeek VL2',
|
|
1101
1114
|
id: 'deepseek-vl2',
|
|
1102
1115
|
maxOutput: 2048,
|
|
@@ -1114,7 +1127,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1114
1127
|
vision: true,
|
|
1115
1128
|
},
|
|
1116
1129
|
contextWindowTokens: 4096,
|
|
1117
|
-
description:
|
|
1130
|
+
description:
|
|
1131
|
+
'DeepSeek VL2 Small is a lightweight multimodal version for resource-constrained and high-concurrency use.',
|
|
1118
1132
|
displayName: 'DeepSeek VL2 Small',
|
|
1119
1133
|
id: 'deepseek-vl2-small',
|
|
1120
1134
|
maxOutput: 2048,
|
|
@@ -1181,7 +1195,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1181
1195
|
search: true,
|
|
1182
1196
|
},
|
|
1183
1197
|
contextWindowTokens: 144_000,
|
|
1184
|
-
description:
|
|
1198
|
+
description:
|
|
1199
|
+
'DeepSeek V3.2 Think is a full deep-thinking model with stronger long-chain reasoning.',
|
|
1185
1200
|
displayName: 'DeepSeek V3.2 Think',
|
|
1186
1201
|
enabled: true,
|
|
1187
1202
|
id: 'deepseek-v3.2-think',
|
|
@@ -1334,8 +1349,7 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1334
1349
|
reasoning: true,
|
|
1335
1350
|
},
|
|
1336
1351
|
contextWindowTokens: 32_768,
|
|
1337
|
-
description:
|
|
1338
|
-
'DeepSeek R1 Distill Llama 70B combines R1 reasoning with the Llama ecosystem.',
|
|
1352
|
+
description: 'DeepSeek R1 Distill Llama 70B combines R1 reasoning with the Llama ecosystem.',
|
|
1339
1353
|
displayName: 'DeepSeek R1 Distill Llama 70B',
|
|
1340
1354
|
id: 'deepseek-r1-distill-llama-70b',
|
|
1341
1355
|
maxOutput: 8192,
|
|
@@ -1440,7 +1454,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1440
1454
|
reasoning: true,
|
|
1441
1455
|
},
|
|
1442
1456
|
contextWindowTokens: 131_072,
|
|
1443
|
-
description:
|
|
1457
|
+
description:
|
|
1458
|
+
'Qwen3 235B A22B Thinking 2507 is an ultra-large thinking model for hard reasoning.',
|
|
1444
1459
|
displayName: 'Qwen3 235B A22B Thinking 2507',
|
|
1445
1460
|
id: 'qwen3-235b-a22b-thinking-2507',
|
|
1446
1461
|
maxOutput: 32_768,
|
|
@@ -1675,7 +1690,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1675
1690
|
},
|
|
1676
1691
|
{
|
|
1677
1692
|
contextWindowTokens: 32_768,
|
|
1678
|
-
description:
|
|
1693
|
+
description:
|
|
1694
|
+
'Qwen3 8B is a lightweight model with flexible deployment for high-concurrency workloads.',
|
|
1679
1695
|
displayName: 'Qwen3 8B',
|
|
1680
1696
|
id: 'qwen3-8b',
|
|
1681
1697
|
maxOutput: 8192,
|
|
@@ -1729,7 +1745,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1729
1745
|
},
|
|
1730
1746
|
{
|
|
1731
1747
|
contextWindowTokens: 32_768,
|
|
1732
|
-
description:
|
|
1748
|
+
description:
|
|
1749
|
+
'Qwen3 0.6B is an entry-level model for simple reasoning and very constrained environments.',
|
|
1733
1750
|
displayName: 'Qwen3 0.6B',
|
|
1734
1751
|
id: 'qwen3-0.6b',
|
|
1735
1752
|
maxOutput: 8192,
|
|
@@ -1747,7 +1764,8 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1747
1764
|
},
|
|
1748
1765
|
{
|
|
1749
1766
|
contextWindowTokens: 32_768,
|
|
1750
|
-
description:
|
|
1767
|
+
description:
|
|
1768
|
+
'Qwen2.5 7B Instruct is a mature open-source instruct model for multi-scenario chat and generation.',
|
|
1751
1769
|
displayName: 'Qwen2.5 7B Instruct',
|
|
1752
1770
|
id: 'qwen2.5-7b-instruct',
|
|
1753
1771
|
maxOutput: 8192,
|
|
@@ -1760,22 +1778,6 @@ const wenxinChatModels: AIChatModelCard[] = [
|
|
|
1760
1778
|
},
|
|
1761
1779
|
type: 'chat',
|
|
1762
1780
|
},
|
|
1763
|
-
{
|
|
1764
|
-
contextWindowTokens: 32_768,
|
|
1765
|
-
description:
|
|
1766
|
-
'GLM-4 32B 0414 is a general GLM model supporting multi-task text generation and understanding.',
|
|
1767
|
-
displayName: 'GLM-4 32B 0414',
|
|
1768
|
-
id: 'glm-4-32b-0414',
|
|
1769
|
-
maxOutput: 8192,
|
|
1770
|
-
pricing: {
|
|
1771
|
-
currency: 'CNY',
|
|
1772
|
-
units: [
|
|
1773
|
-
{ name: 'textInput', rate: 1, strategy: 'fixed', unit: 'millionTokens' },
|
|
1774
|
-
{ name: 'textOutput', rate: 4, strategy: 'fixed', unit: 'millionTokens' },
|
|
1775
|
-
],
|
|
1776
|
-
},
|
|
1777
|
-
type: 'chat',
|
|
1778
|
-
},
|
|
1779
1781
|
];
|
|
1780
1782
|
|
|
1781
1783
|
const wenxinImageModels: AIImageModelCard[] = [
|
|
@@ -1851,7 +1853,8 @@ const wenxinImageModels: AIImageModelCard[] = [
|
|
|
1851
1853
|
type: 'image',
|
|
1852
1854
|
},
|
|
1853
1855
|
{
|
|
1854
|
-
description:
|
|
1856
|
+
description:
|
|
1857
|
+
'FLUX.1-schnell is a high-performance image generation model for fast multi-style outputs.',
|
|
1855
1858
|
displayName: 'FLUX.1-schnell',
|
|
1856
1859
|
enabled: true,
|
|
1857
1860
|
id: 'flux.1-schnell',
|
|
@@ -67,6 +67,60 @@ const zhipuChatModels: AIChatModelCard[] = [
|
|
|
67
67
|
},
|
|
68
68
|
type: 'chat',
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
abilities: {
|
|
72
|
+
functionCall: true,
|
|
73
|
+
reasoning: true,
|
|
74
|
+
search: true,
|
|
75
|
+
},
|
|
76
|
+
contextWindowTokens: 200_000,
|
|
77
|
+
description:
|
|
78
|
+
'GLM-4.7-Flash, as a 30B-level SOTA model, offers a new choice that balances performance and efficiency. It enhances coding capabilities, long-term task planning, and tool collaboration for Agentic Coding scenarios, achieving leading performance among open-source models of the same size in multiple current benchmark leaderboards. In executing complex intelligent agent tasks, it has stronger instruction compliance during tool calls, and further improves the aesthetics of front-end and the efficiency of long-term task completion for Artifacts and Agentic Coding.',
|
|
79
|
+
displayName: 'GLM-4.7-Flash',
|
|
80
|
+
enabled: true,
|
|
81
|
+
id: 'glm-4.7-flash',
|
|
82
|
+
maxOutput: 131_072,
|
|
83
|
+
pricing: {
|
|
84
|
+
currency: 'CNY',
|
|
85
|
+
units: [
|
|
86
|
+
{ name: 'textInput_cacheRead', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
87
|
+
{ name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
88
|
+
{ name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
settings: {
|
|
92
|
+
extendParams: ['enableReasoning'],
|
|
93
|
+
searchImpl: 'params',
|
|
94
|
+
},
|
|
95
|
+
type: 'chat',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
abilities: {
|
|
99
|
+
functionCall: true,
|
|
100
|
+
reasoning: true,
|
|
101
|
+
search: true,
|
|
102
|
+
},
|
|
103
|
+
contextWindowTokens: 200_000,
|
|
104
|
+
description:
|
|
105
|
+
'GLM-4.7-Flash, as a 30B-level SOTA model, offers a new choice that balances performance and efficiency. It enhances coding capabilities, long-term task planning, and tool collaboration for Agentic Coding scenarios, achieving leading performance among open-source models of the same size in multiple current benchmark leaderboards. In executing complex intelligent agent tasks, it has stronger instruction compliance during tool calls, and further improves the aesthetics of front-end and the efficiency of long-term task completion for Artifacts and Agentic Coding.',
|
|
106
|
+
displayName: 'GLM-4.7-FlashX',
|
|
107
|
+
enabled: true,
|
|
108
|
+
id: 'glm-4.7-flashx',
|
|
109
|
+
maxOutput: 131_072,
|
|
110
|
+
pricing: {
|
|
111
|
+
currency: 'CNY',
|
|
112
|
+
units: [
|
|
113
|
+
{ name: 'textInput_cacheRead', rate: 0.1, strategy: 'fixed', unit: 'millionTokens' },
|
|
114
|
+
{ name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' },
|
|
115
|
+
{ name: 'textOutput', rate: 3, strategy: 'fixed', unit: 'millionTokens' },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
settings: {
|
|
119
|
+
extendParams: ['enableReasoning'],
|
|
120
|
+
searchImpl: 'params',
|
|
121
|
+
},
|
|
122
|
+
type: 'chat',
|
|
123
|
+
},
|
|
70
124
|
{
|
|
71
125
|
abilities: {
|
|
72
126
|
functionCall: true,
|
|
@@ -433,32 +487,6 @@ const zhipuChatModels: AIChatModelCard[] = [
|
|
|
433
487
|
},
|
|
434
488
|
type: 'chat',
|
|
435
489
|
},
|
|
436
|
-
{
|
|
437
|
-
abilities: {
|
|
438
|
-
functionCall: true,
|
|
439
|
-
reasoning: true,
|
|
440
|
-
search: true,
|
|
441
|
-
},
|
|
442
|
-
contextWindowTokens: 131_072,
|
|
443
|
-
description: 'Free GLM-4.5 tier with strong performance in reasoning, coding, and agent tasks.',
|
|
444
|
-
displayName: 'GLM-4.5-Flash',
|
|
445
|
-
enabled: true,
|
|
446
|
-
id: 'glm-4.5-flash',
|
|
447
|
-
maxOutput: 98_304,
|
|
448
|
-
pricing: {
|
|
449
|
-
currency: 'CNY',
|
|
450
|
-
units: [
|
|
451
|
-
{ name: 'textInput_cacheRead', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
452
|
-
{ name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
453
|
-
{ name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
|
|
454
|
-
],
|
|
455
|
-
},
|
|
456
|
-
settings: {
|
|
457
|
-
extendParams: ['enableReasoning'],
|
|
458
|
-
searchImpl: 'params',
|
|
459
|
-
},
|
|
460
|
-
type: 'chat',
|
|
461
|
-
},
|
|
462
490
|
{
|
|
463
491
|
abilities: {
|
|
464
492
|
reasoning: true,
|
|
@@ -567,7 +595,8 @@ const zhipuChatModels: AIChatModelCard[] = [
|
|
|
567
595
|
search: true,
|
|
568
596
|
},
|
|
569
597
|
contextWindowTokens: 131_072,
|
|
570
|
-
description:
|
|
598
|
+
description:
|
|
599
|
+
'Fast and low-cost: Flash-enhanced with ultra-fast reasoning and higher concurrency.',
|
|
571
600
|
displayName: 'GLM-Z1-FlashX',
|
|
572
601
|
id: 'glm-z1-flashx',
|
|
573
602
|
maxOutput: 32_768,
|
|
@@ -789,7 +818,8 @@ const zhipuChatModels: AIChatModelCard[] = [
|
|
|
789
818
|
vision: true,
|
|
790
819
|
},
|
|
791
820
|
contextWindowTokens: 16_000,
|
|
792
|
-
description:
|
|
821
|
+
description:
|
|
822
|
+
'GLM-4V-Plus understands video and multiple images, suitable for multimodal tasks.',
|
|
793
823
|
displayName: 'GLM-4V-Plus-0111',
|
|
794
824
|
id: 'glm-4v-plus-0111',
|
|
795
825
|
pricing: {
|
|
@@ -259,6 +259,33 @@ export interface AiModelSettings {
|
|
|
259
259
|
searchProvider?: string;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
export const ExtendParamsTypeSchema = z.enum([
|
|
263
|
+
'reasoningBudgetToken',
|
|
264
|
+
'enableReasoning',
|
|
265
|
+
'disableContextCaching',
|
|
266
|
+
'reasoningEffort',
|
|
267
|
+
'gpt5ReasoningEffort',
|
|
268
|
+
'gpt5_1ReasoningEffort',
|
|
269
|
+
'gpt5_2ReasoningEffort',
|
|
270
|
+
'gpt5_2ProReasoningEffort',
|
|
271
|
+
'textVerbosity',
|
|
272
|
+
'thinking',
|
|
273
|
+
'thinkingBudget',
|
|
274
|
+
'thinkingLevel',
|
|
275
|
+
'thinkingLevel2',
|
|
276
|
+
'imageAspectRatio',
|
|
277
|
+
'imageResolution',
|
|
278
|
+
'urlContext',
|
|
279
|
+
]);
|
|
280
|
+
|
|
281
|
+
export const ModelSearchImplementTypeSchema = z.enum(['tool', 'params', 'internal']);
|
|
282
|
+
|
|
283
|
+
export const AiModelSettingsSchema = z.object({
|
|
284
|
+
extendParams: z.array(ExtendParamsTypeSchema).optional(),
|
|
285
|
+
searchImpl: ModelSearchImplementTypeSchema.optional(),
|
|
286
|
+
searchProvider: z.string().optional(),
|
|
287
|
+
});
|
|
288
|
+
|
|
262
289
|
export interface AIChatModelCard extends AIBaseModelCard {
|
|
263
290
|
abilities?: ModelAbilities;
|
|
264
291
|
config?: AiModelConfig;
|
|
@@ -344,6 +371,7 @@ export const CreateAiModelSchema = z.object({
|
|
|
344
371
|
id: z.string(),
|
|
345
372
|
providerId: z.string(),
|
|
346
373
|
releasedAt: z.string().optional(),
|
|
374
|
+
settings: AiModelSettingsSchema.optional(),
|
|
347
375
|
type: AiModelTypeSchema.optional(),
|
|
348
376
|
|
|
349
377
|
// checkModel: z.string().optional(),
|
|
@@ -380,6 +408,7 @@ export const UpdateAiModelSchema = z.object({
|
|
|
380
408
|
.optional(),
|
|
381
409
|
contextWindowTokens: z.number().nullable().optional(),
|
|
382
410
|
displayName: z.string().nullable().optional(),
|
|
411
|
+
settings: AiModelSettingsSchema.optional(),
|
|
383
412
|
type: AiModelTypeSchema.optional(),
|
|
384
413
|
});
|
|
385
414
|
|
|
@@ -179,7 +179,7 @@ describe('computeChatPricing', () => {
|
|
|
179
179
|
|
|
180
180
|
it('supports multi-modal fixed units for Gemini 2.5 Flash Image Preview', () => {
|
|
181
181
|
const pricing = googleChatModels.find(
|
|
182
|
-
(model: { id: string }) => model.id === 'gemini-2.5-flash-image
|
|
182
|
+
(model: { id: string }) => model.id === 'gemini-2.5-flash-image',
|
|
183
183
|
)?.pricing;
|
|
184
184
|
expect(pricing).toBeDefined();
|
|
185
185
|
|
|
@@ -207,7 +207,7 @@ describe('computeChatPricing', () => {
|
|
|
207
207
|
|
|
208
208
|
it('handles multi-modal image generation for Nano Banana', () => {
|
|
209
209
|
const pricing = googleChatModels.find(
|
|
210
|
-
(model: { id: string }) => model.id === 'gemini-2.5-flash-image
|
|
210
|
+
(model: { id: string }) => model.id === 'gemini-2.5-flash-image',
|
|
211
211
|
)?.pricing;
|
|
212
212
|
expect(pricing).toBeDefined();
|
|
213
213
|
|
|
@@ -12,7 +12,7 @@ const noImageErrorType = 'ProviderNoImageGenerated';
|
|
|
12
12
|
const invalidErrorType = 'InvalidProviderAPIKey';
|
|
13
13
|
|
|
14
14
|
// Mock the console.error to avoid polluting test output
|
|
15
|
-
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
15
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
16
16
|
|
|
17
17
|
let mockClient: GoogleGenAI;
|
|
18
18
|
|
|
@@ -361,7 +361,7 @@ describe('createGoogleImage', () => {
|
|
|
361
361
|
vi.spyOn(mockClient.models, 'generateContent').mockResolvedValue(mockContentResponse as any);
|
|
362
362
|
|
|
363
363
|
const payload: CreateImagePayload = {
|
|
364
|
-
model: 'gemini-2.5-flash-image
|
|
364
|
+
model: 'gemini-2.5-flash-image:image',
|
|
365
365
|
params: {
|
|
366
366
|
prompt: 'Create a beautiful sunset landscape',
|
|
367
367
|
},
|
|
@@ -378,7 +378,7 @@ describe('createGoogleImage', () => {
|
|
|
378
378
|
parts: [{ text: 'Create a beautiful sunset landscape' }],
|
|
379
379
|
},
|
|
380
380
|
],
|
|
381
|
-
model: 'gemini-2.5-flash-image
|
|
381
|
+
model: 'gemini-2.5-flash-image',
|
|
382
382
|
config: {
|
|
383
383
|
responseModalities: ['Image'],
|
|
384
384
|
},
|
|
@@ -414,7 +414,7 @@ describe('createGoogleImage', () => {
|
|
|
414
414
|
vi.spyOn(mockClient.models, 'generateContent').mockResolvedValue(mockContentResponse as any);
|
|
415
415
|
|
|
416
416
|
const payload: CreateImagePayload = {
|
|
417
|
-
model: 'gemini-2.5-flash-image
|
|
417
|
+
model: 'gemini-2.5-flash-image:image',
|
|
418
418
|
params: {
|
|
419
419
|
prompt: 'Add a red rose to this image',
|
|
420
420
|
imageUrl: `data:image/png;base64,${inputImageBase64}`,
|
|
@@ -440,7 +440,7 @@ describe('createGoogleImage', () => {
|
|
|
440
440
|
],
|
|
441
441
|
},
|
|
442
442
|
],
|
|
443
|
-
model: 'gemini-2.5-flash-image
|
|
443
|
+
model: 'gemini-2.5-flash-image',
|
|
444
444
|
config: {
|
|
445
445
|
responseModalities: ['Image'],
|
|
446
446
|
},
|
|
@@ -482,7 +482,7 @@ describe('createGoogleImage', () => {
|
|
|
482
482
|
vi.spyOn(mockClient.models, 'generateContent').mockResolvedValue(mockContentResponse as any);
|
|
483
483
|
|
|
484
484
|
const payload: CreateImagePayload = {
|
|
485
|
-
model: 'gemini-2.5-flash-image
|
|
485
|
+
model: 'gemini-2.5-flash-image:image',
|
|
486
486
|
params: {
|
|
487
487
|
prompt: 'Change the background to blue sky',
|
|
488
488
|
imageUrl: 'https://example.com/image.jpg',
|
|
@@ -511,7 +511,7 @@ describe('createGoogleImage', () => {
|
|
|
511
511
|
],
|
|
512
512
|
},
|
|
513
513
|
],
|
|
514
|
-
model: 'gemini-2.5-flash-image
|
|
514
|
+
model: 'gemini-2.5-flash-image',
|
|
515
515
|
config: {
|
|
516
516
|
responseModalities: ['Image'],
|
|
517
517
|
},
|
|
@@ -545,7 +545,7 @@ describe('createGoogleImage', () => {
|
|
|
545
545
|
vi.spyOn(mockClient.models, 'generateContent').mockResolvedValue(mockContentResponse as any);
|
|
546
546
|
|
|
547
547
|
const payload: CreateImagePayload = {
|
|
548
|
-
model: 'gemini-2.5-flash-image
|
|
548
|
+
model: 'gemini-2.5-flash-image:image',
|
|
549
549
|
params: {
|
|
550
550
|
prompt: 'Generate a colorful abstract pattern',
|
|
551
551
|
imageUrl: null,
|
|
@@ -563,7 +563,7 @@ describe('createGoogleImage', () => {
|
|
|
563
563
|
parts: [{ text: 'Generate a colorful abstract pattern' }],
|
|
564
564
|
},
|
|
565
565
|
],
|
|
566
|
-
model: 'gemini-2.5-flash-image
|
|
566
|
+
model: 'gemini-2.5-flash-image',
|
|
567
567
|
config: {
|
|
568
568
|
responseModalities: ['Image'],
|
|
569
569
|
},
|
|
@@ -594,7 +594,7 @@ describe('createGoogleImage', () => {
|
|
|
594
594
|
);
|
|
595
595
|
|
|
596
596
|
const payload: CreateImagePayload = {
|
|
597
|
-
model: 'gemini-2.5-flash-image
|
|
597
|
+
model: 'gemini-2.5-flash-image:image',
|
|
598
598
|
params: {
|
|
599
599
|
prompt: 'Create inappropriate content',
|
|
600
600
|
},
|
|
@@ -619,7 +619,7 @@ describe('createGoogleImage', () => {
|
|
|
619
619
|
);
|
|
620
620
|
|
|
621
621
|
const payload: CreateImagePayload = {
|
|
622
|
-
model: 'gemini-2.5-flash-image
|
|
622
|
+
model: 'gemini-2.5-flash-image:image',
|
|
623
623
|
params: {
|
|
624
624
|
prompt: 'Generate an image',
|
|
625
625
|
},
|
|
@@ -637,7 +637,7 @@ describe('createGoogleImage', () => {
|
|
|
637
637
|
it('should throw error for unsupported image URL format', async () => {
|
|
638
638
|
// Arrange
|
|
639
639
|
const payload: CreateImagePayload = {
|
|
640
|
-
model: 'gemini-2.5-flash-image
|
|
640
|
+
model: 'gemini-2.5-flash-image:image',
|
|
641
641
|
params: {
|
|
642
642
|
prompt: 'Edit this image',
|
|
643
643
|
imageUrl: 'ftp://example.com/image.jpg',
|
|
@@ -34,6 +34,7 @@ beforeEach(() => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
afterEach(() => {
|
|
37
|
+
vi.unstubAllGlobals();
|
|
37
38
|
vi.clearAllMocks();
|
|
38
39
|
});
|
|
39
40
|
|
|
@@ -333,6 +334,107 @@ describe('LobeOpenRouterAI - custom features', () => {
|
|
|
333
334
|
expect.anything(),
|
|
334
335
|
);
|
|
335
336
|
});
|
|
337
|
+
|
|
338
|
+
it('should map thinkingLevel to reasoning effort', async () => {
|
|
339
|
+
await instance.chat({
|
|
340
|
+
messages: [{ content: 'Think level', role: 'user' }],
|
|
341
|
+
model: 'openai/gpt-4',
|
|
342
|
+
thinkingLevel: 'medium',
|
|
343
|
+
} as any);
|
|
344
|
+
|
|
345
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
|
346
|
+
expect.objectContaining({ reasoning: { effort: 'medium' } }),
|
|
347
|
+
expect.anything(),
|
|
348
|
+
);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe('models mapping', () => {
|
|
353
|
+
it('should map extendParams for gpt-5.x reasoning and verbosity', async () => {
|
|
354
|
+
const mockModels = [
|
|
355
|
+
{
|
|
356
|
+
architecture: { input_modalities: ['text'] },
|
|
357
|
+
created: 1_700_000_000,
|
|
358
|
+
description: 'Test model',
|
|
359
|
+
id: 'openai/gpt-5.2-mini',
|
|
360
|
+
name: 'openai/gpt-5.2-mini',
|
|
361
|
+
pricing: { completion: '0.00001', prompt: '0.00001' },
|
|
362
|
+
supported_parameters: ['reasoning'],
|
|
363
|
+
top_provider: { context_length: 8192, max_completion_tokens: 1024 },
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
architecture: { input_modalities: ['text'] },
|
|
367
|
+
created: 1_700_000_000,
|
|
368
|
+
description: 'Test model',
|
|
369
|
+
id: 'openai/gpt-5.1-mini',
|
|
370
|
+
name: 'openai/gpt-5.1-mini',
|
|
371
|
+
pricing: { completion: '0.00001', prompt: '0.00001' },
|
|
372
|
+
supported_parameters: ['reasoning'],
|
|
373
|
+
top_provider: { context_length: 8192, max_completion_tokens: 1024 },
|
|
374
|
+
},
|
|
375
|
+
];
|
|
376
|
+
|
|
377
|
+
vi.stubGlobal(
|
|
378
|
+
'fetch',
|
|
379
|
+
vi.fn().mockResolvedValue({
|
|
380
|
+
ok: true,
|
|
381
|
+
json: async () => ({ data: mockModels }),
|
|
382
|
+
} as any),
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
const models = await params.models();
|
|
386
|
+
const gpt52 = models.find((m) => m.id === 'openai/gpt-5.2-mini');
|
|
387
|
+
const gpt51 = models.find((m) => m.id === 'openai/gpt-5.1-mini');
|
|
388
|
+
|
|
389
|
+
expect(gpt52?.settings?.extendParams).toEqual(
|
|
390
|
+
expect.arrayContaining(['gpt5_2ReasoningEffort', 'textVerbosity']),
|
|
391
|
+
);
|
|
392
|
+
expect(gpt51?.settings?.extendParams).toEqual(
|
|
393
|
+
expect.arrayContaining(['gpt5_1ReasoningEffort', 'textVerbosity']),
|
|
394
|
+
);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('should map thinkingLevel for gemini-3 flash/pro reasoning', async () => {
|
|
398
|
+
const mockModels = [
|
|
399
|
+
{
|
|
400
|
+
architecture: { input_modalities: ['text'] },
|
|
401
|
+
created: 1_700_000_000,
|
|
402
|
+
description: 'Test model',
|
|
403
|
+
id: 'google/gemini-3-pro',
|
|
404
|
+
name: 'google/gemini-3-pro',
|
|
405
|
+
pricing: { completion: '0.00001', prompt: '0.00001' },
|
|
406
|
+
supported_parameters: ['reasoning'],
|
|
407
|
+
top_provider: { context_length: 8192, max_completion_tokens: 1024 },
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
architecture: { input_modalities: ['text'] },
|
|
411
|
+
created: 1_700_000_000,
|
|
412
|
+
description: 'Test model',
|
|
413
|
+
id: 'google/gemini-3-flash',
|
|
414
|
+
name: 'google/gemini-3-flash',
|
|
415
|
+
pricing: { completion: '0.00001', prompt: '0.00001' },
|
|
416
|
+
supported_parameters: ['reasoning'],
|
|
417
|
+
top_provider: { context_length: 8192, max_completion_tokens: 1024 },
|
|
418
|
+
},
|
|
419
|
+
];
|
|
420
|
+
|
|
421
|
+
vi.stubGlobal(
|
|
422
|
+
'fetch',
|
|
423
|
+
vi.fn().mockResolvedValue({
|
|
424
|
+
ok: true,
|
|
425
|
+
json: async () => ({ data: mockModels }),
|
|
426
|
+
} as any),
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
const models = await params.models();
|
|
430
|
+
const geminiPro = models.find((m) => m.id === 'google/gemini-3-pro');
|
|
431
|
+
const geminiFlash = models.find((m) => m.id === 'google/gemini-3-flash');
|
|
432
|
+
|
|
433
|
+
expect(geminiPro?.settings?.extendParams).toEqual(expect.arrayContaining(['thinkingLevel2']));
|
|
434
|
+
expect(geminiFlash?.settings?.extendParams).toEqual(
|
|
435
|
+
expect.arrayContaining(['thinkingLevel']),
|
|
436
|
+
);
|
|
437
|
+
});
|
|
336
438
|
});
|
|
337
439
|
|
|
338
440
|
describe('models', () => {
|
|
@@ -17,11 +17,11 @@ export const params = {
|
|
|
17
17
|
chatCompletion: {
|
|
18
18
|
handlePayload: (payload) => {
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
|
-
const { reasoning_effort, thinking, reasoning: _reasoning, ...rest } = payload;
|
|
20
|
+
const { reasoning_effort, thinking, reasoning: _reasoning, thinkingLevel, ...rest } = payload;
|
|
21
21
|
|
|
22
22
|
let reasoning: OpenRouterReasoning | undefined;
|
|
23
23
|
|
|
24
|
-
if (thinking?.type || thinking?.budget_tokens !== undefined || reasoning_effort) {
|
|
24
|
+
if (thinking?.type || thinking?.budget_tokens !== undefined || reasoning_effort || thinkingLevel) {
|
|
25
25
|
if (thinking?.type === 'disabled') {
|
|
26
26
|
reasoning = { enabled: false };
|
|
27
27
|
} else if (thinking?.budget_tokens !== undefined) {
|
|
@@ -31,6 +31,9 @@ export const params = {
|
|
|
31
31
|
} else if (reasoning_effort) {
|
|
32
32
|
reasoning = { effort: reasoning_effort };
|
|
33
33
|
}
|
|
34
|
+
else if (thinkingLevel) {
|
|
35
|
+
reasoning = { effort: thinkingLevel };
|
|
36
|
+
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
return {
|
|
@@ -126,11 +129,14 @@ export const params = {
|
|
|
126
129
|
if (model.description && model.description.includes('`reasoning` `enabled`')) {
|
|
127
130
|
extendParams.push('enableReasoning');
|
|
128
131
|
}
|
|
129
|
-
if (hasReasoning && model.id.includes('gpt-5')) {
|
|
130
|
-
extendParams.push('
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
if (hasReasoning && model.id.includes('gpt-5.2')) {
|
|
133
|
+
extendParams.push('gpt5_2ReasoningEffort', 'textVerbosity');
|
|
134
|
+
} else if (hasReasoning && model.id.includes('gpt-5.1')) {
|
|
135
|
+
extendParams.push('gpt5_1ReasoningEffort', 'textVerbosity');
|
|
136
|
+
} else if (hasReasoning && model.id.includes('gpt-5')) {
|
|
137
|
+
extendParams.push('gpt5ReasoningEffort', 'textVerbosity');
|
|
138
|
+
} else if (hasReasoning && model.id.includes('openai')) {
|
|
139
|
+
extendParams.push('reasoningEffort', 'textVerbosity');
|
|
134
140
|
}
|
|
135
141
|
if (hasReasoning && model.id.includes('claude')) {
|
|
136
142
|
extendParams.push('enableReasoning', 'reasoningBudgetToken');
|
|
@@ -141,6 +147,12 @@ export const params = {
|
|
|
141
147
|
if (hasReasoning && model.id.includes('gemini-2.5')) {
|
|
142
148
|
extendParams.push('reasoningBudgetToken');
|
|
143
149
|
}
|
|
150
|
+
if (hasReasoning && model.id.includes('gemini-3-pro')) {
|
|
151
|
+
extendParams.push('thinkingLevel2');
|
|
152
|
+
}
|
|
153
|
+
if (hasReasoning && model.id.includes('gemini-3-flash')) {
|
|
154
|
+
extendParams.push('thinkingLevel');
|
|
155
|
+
}
|
|
144
156
|
return extendParams.length > 0 ? { settings: { extendParams } } : {};
|
|
145
157
|
})(),
|
|
146
158
|
};
|
|
@@ -245,6 +245,53 @@ describe('LobeVercelAIGatewayAI - custom features', () => {
|
|
|
245
245
|
expect(Array.isArray(model?.pricing?.units)).toBe(true);
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
+
it('should map extendParams for gpt-5.x reasoning models', async () => {
|
|
249
|
+
const mockModelData: VercelAIGatewayModelCard[] = [
|
|
250
|
+
{
|
|
251
|
+
id: 'openai/gpt-5.2-mini',
|
|
252
|
+
name: 'GPT-5.2 Mini',
|
|
253
|
+
pricing: { input: 0.000_003, output: 0.000_015 },
|
|
254
|
+
tags: ['reasoning'],
|
|
255
|
+
type: 'chat',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: 'openai/gpt-5.1-mini',
|
|
259
|
+
name: 'GPT-5.1 Mini',
|
|
260
|
+
pricing: { input: 0.000_003, output: 0.000_015 },
|
|
261
|
+
tags: ['reasoning'],
|
|
262
|
+
type: 'chat',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
id: 'openai/gpt-5-mini',
|
|
266
|
+
name: 'GPT-5 Mini',
|
|
267
|
+
pricing: { input: 0.000_003, output: 0.000_015 },
|
|
268
|
+
tags: ['reasoning'],
|
|
269
|
+
type: 'chat',
|
|
270
|
+
},
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
const mockClient = {
|
|
274
|
+
models: {
|
|
275
|
+
list: vi.fn().mockResolvedValue({ data: mockModelData }),
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const models = await params.models({ client: mockClient as any });
|
|
280
|
+
const gpt52 = models.find((m) => m.id === 'openai/gpt-5.2-mini');
|
|
281
|
+
const gpt51 = models.find((m) => m.id === 'openai/gpt-5.1-mini');
|
|
282
|
+
const gpt5 = models.find((m) => m.id === 'openai/gpt-5-mini');
|
|
283
|
+
|
|
284
|
+
expect(gpt52?.settings?.extendParams).toEqual(
|
|
285
|
+
expect.arrayContaining(['gpt5_2ReasoningEffort', 'textVerbosity']),
|
|
286
|
+
);
|
|
287
|
+
expect(gpt51?.settings?.extendParams).toEqual(
|
|
288
|
+
expect.arrayContaining(['gpt5_1ReasoningEffort', 'textVerbosity']),
|
|
289
|
+
);
|
|
290
|
+
expect(gpt5?.settings?.extendParams).toEqual(
|
|
291
|
+
expect.arrayContaining(['gpt5ReasoningEffort', 'textVerbosity']),
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
|
|
248
295
|
it('should handle models with missing pricing', async () => {
|
|
249
296
|
const mockModelData: VercelAIGatewayModelCard[] = [
|
|
250
297
|
{
|
|
@@ -125,9 +125,15 @@ export const params = {
|
|
|
125
125
|
// Merge all applicable extendParams for settings
|
|
126
126
|
...(() => {
|
|
127
127
|
const extendParams: string[] = [];
|
|
128
|
-
if (tags.includes('reasoning') && m.id.includes('gpt-5')) {
|
|
128
|
+
if (tags.includes('reasoning') && m.id.includes('gpt-5') && !m.id.includes('gpt-5.1') && !m.id.includes('gpt-5.2')) {
|
|
129
129
|
extendParams.push('gpt5ReasoningEffort', 'textVerbosity');
|
|
130
130
|
}
|
|
131
|
+
if (tags.includes('reasoning') && m.id.includes('gpt-5.1') && !m.id.includes('gpt-5.2')) {
|
|
132
|
+
extendParams.push('gpt5_1ReasoningEffort', 'textVerbosity');
|
|
133
|
+
}
|
|
134
|
+
if (tags.includes('reasoning') && m.id.includes('gpt-5.2')) {
|
|
135
|
+
extendParams.push('gpt5_2ReasoningEffort', 'textVerbosity');
|
|
136
|
+
}
|
|
131
137
|
if (tags.includes('reasoning') && m.id.includes('openai') && !m.id.includes('gpt-5')) {
|
|
132
138
|
extendParams.push('reasoningEffort', 'textVerbosity');
|
|
133
139
|
}
|