Skip to content

[Solution] How to enable DeepSeek V4 thinking mode in OpenCode using Anthropic API #24122

Closed as not planned

Description

@LieGeee

Problem

When using DeepSeek V4 with thinking mode enabled in OpenCode, you may encounter this error:

The reasoning_content in the thinking mode must be passed back to the API

This happens because:

  1. DeepSeek V4 returns reasoning_content (thinking process) in addition to content (final answer)
  2. In multi-turn conversations with tool calls, reasoning_content must be passed back to the API
  3. The @ai-sdk/openai-compatible package doesn't preserve and pass back reasoning_content

Solution

Use DeepSeek's Anthropic-compatible API instead of the OpenAI-compatible one. The @ai-sdk/anthropic package natively supports reasoning mode (Claude extended thinking).

Configuration

Edit ~/.config/opencode/opencode.json:

"deepseekv4": {
  "npm": "@ai-sdk/anthropic",
  "name": "DeepSeek",
  "options": {
    "baseURL": "https://api.deepseek.com/anthropic",
    "apiKey": "your-deepseek-api-key"
  },
  "models": {
    "deepseek-v4-pro": {
      "name": "DeepSeek-V4-Pro",
      "limit": {
        "context": 1048576,
        "output": 262144
      },
      "options": {
        "thinking": {
          "type": "enabled",
          "budgetTokens": 8192
        }
      }
    }
  }
}

Key Changes

  1. npm: Change from @ai-sdk/openai-compatible to @ai-sdk/anthropic
  2. baseURL: Change from https://api.deepseek.com to https://api.deepseek.com/anthropic
  3. thinking.type: Set to "enabled" to activate thinking mode

Why This Works

  • DeepSeek provides two API formats: OpenAI-compatible and Anthropic-compatible
  • The Anthropic SDK has native support for reasoning mode (used by Claude's extended thinking)
  • By switching to the Anthropic API format, OpenCode can properly handle reasoning_content without code changes

Usage

After restarting OpenCode, DeepSeek V4 will work with thinking mode enabled. You'll see the reasoning process in the model's responses.

References

Tested Environment

  • OpenCode version: Latest (as of 2026-04-24)
  • DeepSeek API: v4-pro
  • OS: Windows 11

Activity

  1. github-actions commented on Apr 24, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • This issue doesn't use one of the required templates (Bug Report, Feature Request, or Question). It appears to be a workaround/solution post, which doesn't fit the issue tracker format. If you want to share this as a bug report about missing reasoning_content support, please use the Bug Report template. If you're requesting a fix, use the Feature Request template (with a [FEATURE]: title prefix).

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.


    This issue might be a duplicate of existing issues. Please check:

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. AutumnSun1996 commented on Apr 24, 2026

    @AutumnSun1996

    @ai-sdk/anthropic still fails sometimes. here's a better workaround i'm using now:
    using transformRequestBody to add all missing strings

          if (body.messages) {
            for (const msg of body.messages) {
              if (msg.role === 'assistant') {
                if (msg.tool_calls && msg.tool_calls.length > 0) {
                  if (!msg.content) {
                    msg.content = 'call tool';
                  }
                  if (!msg.reasoning_content) {
                    msg.reasoning_content = 'call tool';
                  }
                } else {
                  if (!msg.content) {
                    msg.content = 'wait user input';
                  }
                  if (!msg.reasoning_content) {
                    msg.reasoning_content = 'answer';
                  }
                }
              }
            }
          }
  3. LieGeee commented on Apr 24, 2026

    @LieGeee
    Author
    Image

    Image使用和token记录

  4. LieGeee commented on Apr 24, 2026

    @LieGeee
    Author

    @ai-sdk/anthropic still fails sometimes. here's a better workaround i'm using now:@ai-SDK/Anthropic 有时还是会失败。这里有我现在用的更好的变通方法: using transformRequestBody to add all missing strings使用 transformRequestBody 添加所有缺失字符串

      if (body.messages) {
        for (const msg of body.messages) {
          if (msg.role === 'assistant') {
            if (msg.tool_calls && msg.tool_calls.length > 0) {
              if (!msg.content) {
                msg.content = 'call tool';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'call tool';
              }
            } else {
              if (!msg.content) {
                msg.content = 'wait user input';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'answer';
              }
            }
          }
        }
      }
    

    @ai-sdk/anthropic still fails sometimes. here's a better workaround i'm using now:@ai-SDK/Anthropic 有时还是会失败。这里有我现在用的更好的变通方法: using transformRequestBody to add all missing strings使用 transformRequestBody 添加所有缺失字符串

      if (body.messages) {
        for (const msg of body.messages) {
          if (msg.role === 'assistant') {
            if (msg.tool_calls && msg.tool_calls.length > 0) {
              if (!msg.content) {
                msg.content = 'call tool';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'call tool';
              }
            } else {
              if (!msg.content) {
                msg.content = 'wait user input';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'answer';
              }
            }
          }
        }
      }
    

    是的这个方案更佳

  5. LieGeee commented on Apr 24, 2026

    @LieGeee
    Author

    Closing to recreate with proper template format.

  6. CycSpring commented on Apr 24, 2026

    @CycSpring

    在openclaw调用deepseekV4的时候,我也遇到了;openclaw.json里应该怎么改?

  7. LieGeee commented on Apr 24, 2026

    @LieGeee
    Author

    上面有

  8. arjunp1120 commented on May 29, 2026

    @arjunp1120

    @ai-sdk/anthropic still fails sometimes. here's a better workaround i'm using now: using transformRequestBody to add all missing strings

      if (body.messages) {
        for (const msg of body.messages) {
          if (msg.role === 'assistant') {
            if (msg.tool_calls && msg.tool_calls.length > 0) {
              if (!msg.content) {
                msg.content = 'call tool';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'call tool';
              }
            } else {
              if (!msg.content) {
                msg.content = 'wait user input';
              }
              if (!msg.reasoning_content) {
                msg.reasoning_content = 'answer';
              }
            }
          }
        }
      }
    

    What does that mean?? where do you use that? i defined my plugin but it doesn't work; can you please clarify what you mean by this code???

  9. LieGeee commented on May 29, 2026

    @LieGeee
    Author

    你发给ai吧,我已经开始用pi了,很久没用opencode了不记得,你有web_search吗,直接把链接发过去,没有就直接粘贴吧,应该ai可以改的

  10. CycSpring commented on Jun 1, 2026

    @CycSpring

    哈哈,挺久前的问题了;AI几天一个样,我现在都用的codex、cc、hermes了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions