Skip to content

Commit 8bcbaf5

Browse files
committed
fix(openrouter): use extra_body for DeepSeek V3.1 Terminus reasoning control
1 parent 97331bc commit 8bcbaf5

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

src/api/providers/openrouter.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)