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
- Configure DeepSeek V4 Pro (
deepseek/deepseek-v4-pro) with thinking mode
- Run a multi-turn conversation with tool calls (e.g., Sisyphus agent making multiple delegate_task calls)
- 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)
Bug Description
PR #24146 fixed empty reasoning_content for DeepSeek V4 by unconditionally setting
providerOptions[sdk][field] = reasoningTextin 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), soreasoningTextis empty. The unconditional set overwrites the previously correctproviderOptions.reasoning_content, causing DeepSeek 400:Steps to Reproduce
deepseek/deepseek-v4-pro) with thinking modeRoot Cause
The interleaved transform runs on every request:
providerOptions→ removes from content ✅reasoningText = ""→ unconditionally overwritesproviderOptions.reasoning_content→ reasoning lost ❌Expected Behavior
On the second pass, when
reasoningTextis empty, fall back to the existingproviderOptions[sdk][field]value instead of overwriting with empty string.Related
Environment
deepseek-v4-pro)@ai-sdk/openai-compatible)