fix: port 3 upstream DeepSeek transform fixes

Closed
AN
3mo ago
+48-16

What does this PR do?

Cherry-picks (manual port — no merge base with upstream-opencode) 3 DeepSeek-specific transform.ts fixes that landed in upstream-opencode but never made it into altimate-code's main:

  1. DeepSeek assistant messages always carry a reasoning part — upstream 86715fecc4 / #24180. DeepSeek's OpenAI-compatible protocol rejects multi-turn assistant messages that lack a reasoning part; the fix inserts an empty one before the interleaved-field normalization.

  2. Always emit the interleaved reasoning field, even when empty — upstream 923af96d26 / #24146. DeepSeek V4 thinking mode may emit empty reasoning_content; the field must still be present in subsequent requests or the API rejects the message. Removes the if (reasoningText) guard around the providerOptions set so the field is always written.

  3. DeepSeek-v4 supports max reasoning effort — upstream f8e939d96f / #24163. Adds "max" to the @ai-sdk/openai-compatible variant cascade when the model id contains deepseek-v4.

A fourth upstream fix (9d6718131e — remove deepseek-chat/deepseek-reasoner from a variants include list) is not ported because our equivalent block already excludes all deepseek model ids from variant calculation via the broader id.includes("deepseek") check at transform.ts:380.

Also wraps the altimate-specific altimate-backend / google-vertex-anthropic providerID entries in altimate_change markers (pre-existing oversight from PR #850 that the marker guard now flags).

All three ported changes are marked with the upstream_fix: tag so they can be dropped when upstream finally ships the same shape via a normal merge.

Type of change

fix: (provider compat with DeepSeek V4 / Reasoner endpoints).

Issue for this PR

No tracking issue — these are upstream fixes that fell off the bridge during our diverged history. Investigated as a follow-up to #849 review.

How did you verify your code works?

  • bun test test/provider/ — 387 pass / 0 fail, exercises the variant cascade and normalizeMessages
  • bun run typecheck — clean
  • bun run script/upstream/analyze.ts --markers --base main --strict — clean (new code wrapped in altimate_change blocks)
  • Spot-checked against a DGX DeepSeek-V4 benchmark trace at ~/ade-bench-openrouter/experiments/duckdb_deepseek_v4pro_run1__none/ to confirm the model id pattern matches (alibaba-cn/deepseek-v4-pro and azure-deepseek/deepseek-v4-flash both contain deepseek-v4).

Checklist

  • Tests pass locally
  • No new lint errors
  • Marker guard clean
  • Self-reviewed the diff
  • All ported changes carry upstream_fix: so they auto-surface during the next upstream merge audit

Summary by cubic

Ports three upstream DeepSeek transform fixes to restore API compatibility and prevent 400 errors in multi-turn chats. Ensures reasoning fields are always present and enables max reasoning effort for deepseek-v4.

  • Bug Fixes

    • Always add an empty reasoning part to DeepSeek assistant messages.
    • Always set the interleaved reasoning field on assistant messages, even when empty.
    • Add "max" to reasoning effort variants for deepseek-v4 under @ai-sdk/openai-compatible.
  • Refactors

    • Wrap altimate-backend and google-vertex-anthropic provider IDs in altimate_change guards.

Summary by CodeRabbit

  • Improvements
    • Enhanced support for AI reasoning capabilities across models
    • Expanded compatibility with additional AI provider backends
    • Added maximum reasoning effort level option for DeepSeek models
    • Improved message transformation consistency for multi-provider support

Review Change Stack