Skip to content

Support DeepSeek V4 Thinking Mode with reasoning_content handling #24114

@LieGeee

Description

@LieGeee

Description

According to DeepSeek's official documentation (https://api-docs.deepseek.com/guides/thinking_mode), when thinking mode is enabled:

  1. The API returns both reasoning_content (thinking process) and content (final answer)
  2. In multi-turn conversations with tool calls, the reasoning_content must be passed back to the API in subsequent requests
  3. If reasoning_content is not properly preserved and returned, the API returns a 400 error
    Currently, OpenCode's AI SDK does not preserve or pass back the reasoning_content field in multi-turn conversations, causing this error.
    Expected Behavior
    OpenCode should:
  4. Capture reasoning_content from DeepSeek API responses
  5. Store it alongside the regular content in conversation history
  6. Pass it back in subsequent API calls when continuing the conversation
    Current Workaround
    Users must explicitly disable thinking mode in their configuration:
    { "provider": { "deepseekv4": { "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "https://api.deepseek.com", "apiKey": "sk-xxx" }, "models": { "deepseek-v4-pro": { "name": "deepseek-v4-pro", "extra_body": { "thinking": { "type": "disabled" } } } } } } }
    This works but disables the powerful thinking capabilities of DeepSeek V4.
    Proposed Solution
    Modify the message handling logic to:
  7. Check if the response contains a reasoning_content field
  8. Store it in the message object alongside content
  9. When constructing the next request, include reasoning_content for assistant messages that had it
    Example implementation (pseudo-code):
    // When receiving response
    const assistantMessage = {
    role: 'assistant',
    content: response.choices[0].message.content,
    reasoning_content: response.choices[0].message.reasoning_content, // Preserve this
    tool_calls: response.choices[0].message.tool_calls
    }
    // When sending next request
    messages.push(assistantMessage) // Include reasoning_content if present
    Reference Documentation

Plugins

No response

OpenCode version

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcoreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions