File tree 4 files changed +89
-3
lines changed
libs/agent-runtime/openrouter
4 files changed +89
-3
lines changed Original file line number Diff line number Diff line change @@ -137,6 +137,31 @@ const openrouterChatModels: AIChatModelCard[] = [
137
137
releasedAt : '2024-06-20' ,
138
138
type : 'chat' ,
139
139
} ,
140
+ {
141
+ abilities : {
142
+ functionCall : true ,
143
+ reasoning : true ,
144
+ vision : true ,
145
+ } ,
146
+ contextWindowTokens : 200_000 ,
147
+ description :
148
+ 'Claude 3.7 Sonnet 是 Anthropic 迄今为止最智能的模型,也是市场上首个混合推理模型。Claude 3.7 Sonnet 可以产生近乎即时的响应或延长的逐步思考,用户可以清晰地看到这些过程。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。' ,
149
+ displayName : 'Claude 3.7 Sonnet' ,
150
+ enabled : true ,
151
+ id : 'anthropic/claude-3.7-sonnet' ,
152
+ maxOutput : 8192 ,
153
+ pricing : {
154
+ cachedInput : 0.3 ,
155
+ input : 3 ,
156
+ output : 15 ,
157
+ writeCacheInput : 3.75 ,
158
+ } ,
159
+ releasedAt : '2025-02-24' ,
160
+ settings : {
161
+ extendParams : [ 'enableReasoning' , 'reasoningBudgetToken' ] ,
162
+ } ,
163
+ type : 'chat' ,
164
+ } ,
140
165
{
141
166
abilities : {
142
167
functionCall : true ,
@@ -258,7 +283,7 @@ const openrouterChatModels: AIChatModelCard[] = [
258
283
id : 'deepseek/deepseek-r1:free' ,
259
284
releasedAt : '2025-01-20' ,
260
285
type : 'chat' ,
261
- } ,
286
+ } ,
262
287
{
263
288
abilities : {
264
289
vision : true ,
Original file line number Diff line number Diff line change @@ -92,6 +92,39 @@ describe('LobeOpenRouterAI', () => {
92
92
expect ( result ) . toBeInstanceOf ( Response ) ;
93
93
} ) ;
94
94
95
+ it ( 'should add reasoning field when thinking is enabled' , async ( ) => {
96
+ // Arrange
97
+ const mockStream = new ReadableStream ( ) ;
98
+ const mockResponse = Promise . resolve ( mockStream ) ;
99
+
100
+ ( instance [ 'client' ] . chat . completions . create as Mock ) . mockResolvedValue ( mockResponse ) ;
101
+
102
+ // Act
103
+ const result = await instance . chat ( {
104
+ messages : [ { content : 'Hello' , role : 'user' } ] ,
105
+ model : 'mistralai/mistral-7b-instruct:free' ,
106
+ temperature : 0.7 ,
107
+ thinking : {
108
+ type : 'enabled' ,
109
+ budget_tokens : 1500 ,
110
+ } ,
111
+ } ) ;
112
+
113
+ // Assert
114
+ expect ( instance [ 'client' ] . chat . completions . create ) . toHaveBeenCalledWith (
115
+ expect . objectContaining ( {
116
+ messages : [ { content : 'Hello' , role : 'user' } ] ,
117
+ model : 'mistralai/mistral-7b-instruct:free' ,
118
+ reasoning : {
119
+ max_tokens : 1500 ,
120
+ } ,
121
+ temperature : 0.7 ,
122
+ } ) ,
123
+ { headers : { Accept : '*/*' } } ,
124
+ ) ;
125
+ expect ( result ) . toBeInstanceOf ( Response ) ;
126
+ } ) ;
127
+
95
128
describe ( 'Error' , ( ) => {
96
129
it ( 'should return OpenRouterBizError with an openai error response when OpenAI.APIError is thrown' , async ( ) => {
97
130
// Arrange
Original file line number Diff line number Diff line change @@ -2,7 +2,7 @@ import type { ChatModelCard } from '@/types/llm';
2
2
3
3
import { ModelProvider } from '../types' ;
4
4
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory' ;
5
- import { OpenRouterModelCard , OpenRouterModelExtraInfo } from './type' ;
5
+ import { OpenRouterModelCard , OpenRouterModelExtraInfo , OpenRouterReasoning } from './type' ;
6
6
7
7
const formatPrice = ( price : string ) => {
8
8
if ( price === '-1' ) return undefined ;
@@ -13,10 +13,19 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
13
13
baseURL : 'https://openrouter.ai/api/v1' ,
14
14
chatCompletion : {
15
15
handlePayload : ( payload ) => {
16
+ const { thinking } = payload ;
17
+
18
+ let reasoning : OpenRouterReasoning = { } ;
19
+ if ( thinking ?. type === 'enabled' ) {
20
+ reasoning = {
21
+ max_tokens : thinking . budget_tokens ,
22
+ } ;
23
+ }
24
+
16
25
return {
17
26
...payload ,
18
- include_reasoning : true ,
19
27
model : payload . enabledSearch ? `${ payload . model } :online` : payload . model ,
28
+ reasoning,
20
29
stream : payload . stream ?? true ,
21
30
} as any ;
22
31
} ,
Original file line number Diff line number Diff line change @@ -37,3 +37,22 @@ export interface OpenRouterModelExtraInfo {
37
37
endpoint ?: OpenRouterModelEndpoint ;
38
38
slug : string ;
39
39
}
40
+
41
+ interface OpenRouterOpenAIReasoning {
42
+ effort : 'high' | 'medium' | 'low' ;
43
+ exclude ?: boolean ;
44
+ }
45
+
46
+ interface OpenRouterAnthropicReasoning {
47
+ exclude ?: boolean ;
48
+ max_tokens : number ;
49
+ }
50
+
51
+ interface OpenRouterCommonReasoning {
52
+ exclude ?: boolean ;
53
+ }
54
+
55
+ export type OpenRouterReasoning =
56
+ | OpenRouterOpenAIReasoning
57
+ | OpenRouterAnthropicReasoning
58
+ | OpenRouterCommonReasoning ;
You can’t perform that action at this time.
0 commit comments