Skip to content

DeepSeek V4: reasoning_content lost on second interleaved pass (regression from #24146) #24442

@claudianus

Description

@claudianus

Bug Description

PR #24146 fixed empty reasoning_content for DeepSeek V4 by unconditionally setting providerOptions[sdk][field] = reasoningText in the interleaved transform. However, this introduced a regression: on the second pass through the transform (after DB storage), content parts no longer have reasoning blocks (already extracted in first pass), so reasoningText is empty. The unconditional set overwrites the previously correct providerOptions.reasoning_content, causing DeepSeek 400:

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

Steps to Reproduce

  1. Configure DeepSeek V4 Pro (deepseek/deepseek-v4-pro) with thinking mode
  2. Run a multi-turn conversation with tool calls (e.g., Sisyphus agent making multiple delegate_task calls)
  3. After the first tool-result → assistant response round-trip, the second request to DeepSeek will fail with 400

Root Cause

The interleaved transform runs on every request:

  • First pass: Content has reasoning parts → extracts reasoning → stores in providerOptions → removes from content ✅
  • Second pass (after DB round-trip): Content has no reasoning parts → reasoningText = "" → unconditionally overwrites providerOptions.reasoning_content → reasoning lost ❌

Expected Behavior

On the second pass, when reasoningText is empty, fall back to the existing providerOptions[sdk][field] value instead of overwriting with empty string.

Related

Environment

  • DeepSeek V4 Pro (deepseek-v4-pro)
  • OpenCode dev branch
  • models.dev provider (@ai-sdk/openai-compatible)

Metadata

Metadata

Assignees

Labels

coreAnything 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