11import { Anthropic } from "@anthropic-ai/sdk"
22import { BetaThinkingConfigParam } from "@anthropic-ai/sdk/resources/beta"
3- import axios , { AxiosRequestConfig } from "axios"
3+ import axios from "axios"
44import OpenAI from "openai"
5- import delay from "delay"
65
76import { ApiHandlerOptions , ModelInfo , openRouterDefaultModelId , openRouterDefaultModelInfo } from "../../shared/api"
87import { parseApiPrice } from "../../utils/cost"
@@ -22,6 +21,12 @@ type OpenRouterChatCompletionParams = OpenAI.Chat.ChatCompletionCreateParams & {
2221 transforms ?: string [ ]
2322 include_reasoning ?: boolean
2423 thinking ?: BetaThinkingConfigParam
24+ // https://openrouter.ai/docs/use-cases/reasoning-tokens
25+ reasoning ?: {
26+ effort ?: "high" | "medium" | "low"
27+ max_tokens ?: number
28+ exclude ?: boolean
29+ }
2530}
2631
2732export class OpenRouterHandler extends BaseProvider implements SingleCompletionHandler {
@@ -42,7 +47,7 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
4247 systemPrompt : string ,
4348 messages : Anthropic . Messages . MessageParam [ ] ,
4449 ) : AsyncGenerator < ApiStreamChunk > {
45- let { id : modelId , maxTokens, thinking, temperature, topP } = this . getModel ( )
50+ let { id : modelId , maxTokens, thinking, temperature, topP, reasoningEffort } = this . getModel ( )
4651
4752 // Convert Anthropic messages to OpenAI format.
4853 let openAiMessages : OpenAI . Chat . ChatCompletionMessageParam [ ] = [
@@ -70,13 +75,16 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
7075 } ,
7176 ] ,
7277 }
78+
7379 // Add cache_control to the last two user messages
7480 // (note: this works because we only ever add one user message at a time, but if we added multiple we'd need to mark the user message before the last assistant message)
7581 const lastTwoUserMessages = openAiMessages . filter ( ( msg ) => msg . role === "user" ) . slice ( - 2 )
82+
7683 lastTwoUserMessages . forEach ( ( msg ) => {
7784 if ( typeof msg . content === "string" ) {
7885 msg . content = [ { type : "text" , text : msg . content } ]
7986 }
87+
8088 if ( Array . isArray ( msg . content ) ) {
8189 // NOTE: this is fine since env details will always be added at the end. but if it weren't there, and the user added a image_url type message, it would pop a text part before it and then move it after to the end.
8290 let lastTextPart = msg . content . filter ( ( part ) => part . type === "text" ) . pop ( )
@@ -113,6 +121,7 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
113121 } ) ,
114122 // This way, the transforms field will only be included in the parameters when openRouterUseMiddleOutTransform is true.
115123 ...( ( this . options . openRouterUseMiddleOutTransform ?? true ) && { transforms : [ "middle-out" ] } ) ,
124+ ...( reasoningEffort && { reasoning : { effort : reasoningEffort } } ) ,
116125 }
117126
118127 const stream = await this . client . chat . completions . create ( completionParams )
0 commit comments