DeepSeek 3.2: Missing reasoning_content #3229

Closed
opened 2026-02-16 17:39:14 -05:00 by yindo · 12 comments
Owner

Originally created by @gasatrya on GitHub (Dec 1, 2025).

Originally assigned to: @rekram1-node on GitHub.

Description

Missing `reasoning_content` field in the assistant message at message index 3. For more information, please refer to https://api-docs.deepseek.com/guides/thinking_with_tools

DeepSeek just upgraded the model, and I got an error message when using the Reasoner model.

OpenCode version

1.0.125

Steps to reproduce

  1. Switch to DeepSeek reasoner

Screenshot and/or share link

Image

Operating System

WSL 2

Terminal

Windows Terminal

Originally created by @gasatrya on GitHub (Dec 1, 2025). Originally assigned to: @rekram1-node on GitHub. ### Description ``` Missing `reasoning_content` field in the assistant message at message index 3. For more information, please refer to https://api-docs.deepseek.com/guides/thinking_with_tools ``` DeepSeek just upgraded the model, and I got an error message when using the Reasoner model. ### OpenCode version 1.0.125 ### Steps to reproduce 1. Switch to DeepSeek reasoner ### Screenshot and/or share link <img width="1633" height="972" alt="Image" src="https://github.com/user-attachments/assets/c7b8082f-ec18-4bc2-a02c-5e01c74ce065" /> ### Operating System WSL 2 ### Terminal Windows Terminal
yindo added the bug label 2026-02-16 17:39:14 -05:00
yindo closed this issue 2026-02-16 17:39:14 -05:00
Author
Owner

@matjanos commented on GitHub (Dec 1, 2025):

Context from DeepSeek documentation: https://api-docs.deepseek.com/guides/reasoning_model

@matjanos commented on GitHub (Dec 1, 2025): Context from DeepSeek documentation: https://api-docs.deepseek.com/guides/reasoning_model
Author
Owner

@xiaofeifeiovo commented on GitHub (Dec 1, 2025):

same question on mac

@xiaofeifeiovo commented on GitHub (Dec 1, 2025): same question on mac
Author
Owner

@monotykamary commented on GitHub (Dec 2, 2025):

https://github.com/vercel/ai/issues/10778. This is likely an upstream ai-sdk thing and there is some work started to handle this: https://github.com/vercel/ai/pull/10785

@monotykamary commented on GitHub (Dec 2, 2025): https://github.com/vercel/ai/issues/10778. This is likely an upstream ai-sdk thing and there is some work started to handle this: https://github.com/vercel/ai/pull/10785
Author
Owner

@monotykamary commented on GitHub (Dec 2, 2025):

In the meantime you can patch this part up to make it work:

diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts
index abe269d5d..00c20bc44 100644
--- a/packages/opencode/src/provider/transform.ts
+++ b/packages/opencode/src/provider/transform.ts
@@ -4,6 +4,46 @@ import type { JSONSchema } from "zod/v4/core"
 
 export namespace ProviderTransform {
   function normalizeMessages(msgs: ModelMessage[], providerID: string, modelID: string): ModelMessage[] {
+    // DeepSeek: Handle reasoning_content for tool call continuations
+    // - With tool calls: Include reasoning_content in providerOptions so model can continue reasoning
+    // - Without tool calls: Strip reasoning (new turn doesn't need previous reasoning)
+    // See: https://api-docs.deepseek.com/guides/thinking_mode
+    if (providerID === "deepseek" || modelID.toLowerCase().includes("deepseek")) {
+      return msgs.map((msg) => {
+        if (msg.role === "assistant" && Array.isArray(msg.content)) {
+          const reasoningParts = msg.content.filter((part: any) => part.type === "reasoning")
+          const hasToolCalls = msg.content.some((part: any) => part.type === "tool-call")
+          const reasoningText = reasoningParts.map((part: any) => part.text).join("")
+
+          // Filter out reasoning parts from content
+          const filteredContent = msg.content.filter((part: any) => part.type !== "reasoning")
+
+          // If this message has tool calls and reasoning, include reasoning_content
+          // so DeepSeek can continue reasoning after tool execution
+          if (hasToolCalls && reasoningText) {
+            return {
+              ...msg,
+              content: filteredContent,
+              providerOptions: {
+                ...msg.providerOptions,
+                openaiCompatible: {
+                  ...(msg.providerOptions as any)?.openaiCompatible,
+                  reasoning_content: reasoningText,
+                },
+              },
+            }
+          }
+
+          // For final answers (no tool calls), just strip reasoning
+          return {
+            ...msg,
+            content: filteredContent,
+          }
+        }
+        return msg
+      })
+    }
+
     if (modelID.includes("claude")) {
       return msgs.map((msg) => {
         if ((msg.role === "assistant" || msg.role === "tool") && Array.isArray(msg.content)) {
Image
@monotykamary commented on GitHub (Dec 2, 2025): In the meantime you can patch this part up to make it work: ```diff diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index abe269d5d..00c20bc44 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -4,6 +4,46 @@ import type { JSONSchema } from "zod/v4/core" export namespace ProviderTransform { function normalizeMessages(msgs: ModelMessage[], providerID: string, modelID: string): ModelMessage[] { + // DeepSeek: Handle reasoning_content for tool call continuations + // - With tool calls: Include reasoning_content in providerOptions so model can continue reasoning + // - Without tool calls: Strip reasoning (new turn doesn't need previous reasoning) + // See: https://api-docs.deepseek.com/guides/thinking_mode + if (providerID === "deepseek" || modelID.toLowerCase().includes("deepseek")) { + return msgs.map((msg) => { + if (msg.role === "assistant" && Array.isArray(msg.content)) { + const reasoningParts = msg.content.filter((part: any) => part.type === "reasoning") + const hasToolCalls = msg.content.some((part: any) => part.type === "tool-call") + const reasoningText = reasoningParts.map((part: any) => part.text).join("") + + // Filter out reasoning parts from content + const filteredContent = msg.content.filter((part: any) => part.type !== "reasoning") + + // If this message has tool calls and reasoning, include reasoning_content + // so DeepSeek can continue reasoning after tool execution + if (hasToolCalls && reasoningText) { + return { + ...msg, + content: filteredContent, + providerOptions: { + ...msg.providerOptions, + openaiCompatible: { + ...(msg.providerOptions as any)?.openaiCompatible, + reasoning_content: reasoningText, + }, + }, + } + } + + // For final answers (no tool calls), just strip reasoning + return { + ...msg, + content: filteredContent, + } + } + return msg + }) + } + if (modelID.includes("claude")) { return msgs.map((msg) => { if ((msg.role === "assistant" || msg.role === "tool") && Array.isArray(msg.content)) { ``` <img width="727" height="875" alt="Image" src="https://github.com/user-attachments/assets/1f73d03f-8cc9-4ff2-8c42-596770deb4e8" />
Author
Owner

@matjanos commented on GitHub (Dec 2, 2025):

https://github.com/sst/opencode/pull/4975 - Thanks @monotykamary .

There is a PR that solves the problem

@matjanos commented on GitHub (Dec 2, 2025): https://github.com/sst/opencode/pull/4975 - Thanks @monotykamary . There is a PR that solves the problem
Author
Owner

@Tim-Rambo commented on GitHub (Dec 3, 2025):

Very nice, I had the same issue awesome to see it already being solved and pushed.

@Tim-Rambo commented on GitHub (Dec 3, 2025): Very nice, I had the same issue awesome to see it already being solved and pushed.
Author
Owner

@rekram1-node commented on GitHub (Dec 3, 2025):

I merged the fix, release is going out now

@rekram1-node commented on GitHub (Dec 3, 2025): I merged the fix, release is going out now
Author
Owner

@rekram1-node commented on GitHub (Dec 3, 2025):

If it is still an issue on 1.0.130 lmk and we can reopen

@rekram1-node commented on GitHub (Dec 3, 2025): If it is still an issue on 1.0.130 lmk and we can reopen
Author
Owner

@monotykamary commented on GitHub (Dec 3, 2025):

Image
@monotykamary commented on GitHub (Dec 3, 2025): <img width="474" height="274" alt="Image" src="https://github.com/user-attachments/assets/7aa6d211-ffdd-496a-baf0-c58c5c4f666f" />
Author
Owner

@rekram1-node commented on GitHub (Dec 4, 2025):

hahaha

@rekram1-node commented on GitHub (Dec 4, 2025): hahaha
Author
Owner

@9p15p commented on GitHub (Jan 27, 2026):

v1.1.36 still has this bug.

@9p15p commented on GitHub (Jan 27, 2026): v1.1.36 still has this bug.
Author
Owner

@9p15p commented on GitHub (Jan 27, 2026):

this is my opencode.json

Operating System: ubuntu
Terminal: zsh

  "provider": {
    "deepseek": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "DeepSeek",
      "options": {
        "baseURL": "https://api.deepseek.com/v1",
        "apiKey": "{env:DEEPSEEK_API_KEY}"
      },
      "models": {
        "deepseek-chat": {
          "name": "DeepSeek V3",
          "limit": {
            "context": 128000,
            "output": 8192
          }
        },
        "deepseek-reasoner": {
          "name": "DeepSeek R1",
          "limit": {
            "context": 128000,
            "output": 65536
          }
        }
      }
    },
@9p15p commented on GitHub (Jan 27, 2026): this is my opencode.json Operating System: ubuntu Terminal: zsh ``` "provider": { "deepseek": { "npm": "@ai-sdk/openai-compatible", "name": "DeepSeek", "options": { "baseURL": "https://api.deepseek.com/v1", "apiKey": "{env:DEEPSEEK_API_KEY}" }, "models": { "deepseek-chat": { "name": "DeepSeek V3", "limit": { "context": 128000, "output": 8192 } }, "deepseek-reasoner": { "name": "DeepSeek R1", "limit": { "context": 128000, "output": 65536 } } } }, ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3229