@@ -60,6 +60,8 @@ type OpenRouterChatCompletionParams = OpenAI.Chat.ChatCompletionCreateParams & {
6060 include_reasoning ?: boolean
6161 // https://openrouter.ai/docs/use-cases/reasoning-tokens
6262 reasoning ?: OpenRouterReasoningParams
63+ // OpenRouter vendor-specific additional body for special templates (e.g., DeepSeek V3.1 Terminus)
64+ extra_body ?: Record < string , unknown >
6365}
6466
6567// See `OpenAI.Chat.Completions.ChatCompletionChunk["usage"]`
@@ -140,6 +142,16 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
140142 }
141143
142144 const transforms = ( this . options . openRouterUseMiddleOutTransform ?? true ) ? [ "middle-out" ] : undefined
145+ const isDeepSeekV31Terminus = modelId . includes ( "DeepSeek-V3.1-Terminus" )
146+ // DeepSeek V3.1 Terminus uses chat_template_kwargs.thinking via extra_body on OpenRouter
147+ const extra_body = isDeepSeekV31Terminus
148+ ? {
149+ chat_template_kwargs : {
150+ // Default OFF unless explicitly requested via reasoning settings
151+ thinking : Boolean ( reasoning ) && ! ( reasoning as any ) ?. exclude ,
152+ } ,
153+ }
154+ : undefined
143155
144156 // https://openrouter.ai/docs/transforms
145157 const completionParams : OpenRouterChatCompletionParams = {
@@ -160,7 +172,9 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
160172 } ,
161173 } ) ,
162174 ...( transforms && { transforms } ) ,
163- ...( reasoning && { reasoning } ) ,
175+ ...( extra_body && { extra_body } ) ,
176+ // Do not pass OpenRouter "reasoning" param for DeepSeek V3.1 Terminus; use extra_body instead
177+ ...( ! isDeepSeekV31Terminus && reasoning ? { reasoning } : { } ) ,
164178 }
165179
166180 let stream
@@ -248,6 +262,16 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
248262 async completePrompt ( prompt : string ) {
249263 let { id : modelId , maxTokens, temperature, reasoning } = await this . fetchModel ( )
250264
265+ const isDeepSeekV31Terminus = modelId . includes ( "DeepSeek-V3.1-Terminus" )
266+ const extra_body = isDeepSeekV31Terminus
267+ ? {
268+ chat_template_kwargs : {
269+ // Default OFF unless explicitly requested via reasoning settings
270+ thinking : Boolean ( reasoning ) && ! ( reasoning as any ) ?. exclude ,
271+ } ,
272+ }
273+ : undefined
274+
251275 const completionParams : OpenRouterChatCompletionParams = {
252276 model : modelId ,
253277 max_tokens : maxTokens ,
@@ -263,7 +287,9 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
263287 allow_fallbacks : false ,
264288 } ,
265289 } ) ,
266- ...( reasoning && { reasoning } ) ,
290+ ...( extra_body && { extra_body } ) ,
291+ // Do not pass OpenRouter "reasoning" param for DeepSeek V3.1 Terminus; use extra_body instead
292+ ...( ! isDeepSeekV31Terminus && reasoning ? { reasoning } : { } ) ,
267293 }
268294
269295 let response
0 commit comments