DeepSeek 3.2: Missing `reasoning_content`
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
- Switch to DeepSeek reasoner
Screenshot and/or share link
Operating System
WSL 2
Terminal
Windows Terminal
Context from DeepSeek documentation: https://api-docs.deepseek.com/guides/reasoning_model
same question on mac
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
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)) {
https://github.com/sst/opencode/pull/4975 - Thanks @monotykamary .
There is a PR that solves the problem
Very nice, I had the same issue awesome to see it already being solved and pushed.
I merged the fix, release is going out now
If it is still an issue on 1.0.130 lmk and we can reopen
hahaha