Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions packages/opencode/src/provider/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,29 @@ function normalizeMessages(
return result
}

// Deepseek requires all assistant messages to have reasoning on them
// DeepSeek requires reasoning_content in providerOptions for all assistant messages.
// Always include it even when empty to satisfy the API requirement.
if (model.api.id.includes("deepseek")) {
msgs = msgs.map((msg) => {
return msgs.map((msg) => {
if (msg.role !== "assistant") return msg
if (Array.isArray(msg.content)) {
if (msg.content.some((part) => part.type === "reasoning")) return msg
return { ...msg, content: [...msg.content, { type: "reasoning", text: "" }] }
}
const parts = Array.isArray(msg.content)
? msg.content
: msg.content
? [{ type: "text" as const, text: msg.content as string }]
: []
const reasoningParts = parts.filter((part: any) => part.type === "reasoning")
const reasoningText = reasoningParts.map((part: any) => part.text).join("")
const filteredContent = parts.filter((part: any) => part.type !== "reasoning")
return {
...msg,
content: [
...(msg.content ? [{ type: "text" as const, text: msg.content }] : []),
{ type: "reasoning" as const, text: "" },
],
content: filteredContent,
providerOptions: {
...msg.providerOptions,
openaiCompatible: {
...msg.providerOptions?.openaiCompatible,
reasoning_content: reasoningText,
},
},
}
})
}
Expand Down Expand Up @@ -907,6 +916,15 @@ export function options(input: {
result["enable_thinking"] = true
}

// Enable thinking for DeepSeek reasoning models.
// DeepSeek API requires thinking to be enabled to return reasoning_content.
if (
(input.model.api.id.includes("deepseek") || input.model.providerID.includes("deepseek")) &&
input.model.capabilities.reasoning
) {
result["thinking"] = { type: "enabled" }
}

if (input.model.api.id.includes("gpt-5") && !input.model.api.id.includes("gpt-5-chat")) {
if (!input.model.api.id.includes("gpt-5-pro")) {
result["reasoningEffort"] = "medium"
Expand Down
Loading