Skip to content

feat: DeepSeek API v4 stabilization — release v1.1.0

Choose a tag to compare

@sluisr sluisr released this 29 Apr 15:40
· 468 commits to main since this release

DeepSeek CLI v1.1.0 — DeepSeek API v4 Stabilization

Released: 2026-04-29

This release stabilizes the native DeepSeek API v4 integration (thinking mode +
reasoning_content), adds cost/latency optimizations to the model router, fixes
the exit_plan_mode workflow, and completes the user-facing rebrand from
gemini to deepseek.

Highlights

  • DeepSeek v4 thinking mode is now stable. The HTTP 400 errors caused by
    missing reasoning_content between turns are fixed at the root.
  • Lower cost per session. Classifier no longer uses thinking mode and routes
    more tasks to the cheaper flash model. Tools are sent in stable order to
    improve DeepSeek's prompt cache hit rate.
  • exit_plan_mode works without a pre-existing plan file. Models can pass
    the plan inline via plan_content and the tool will materialize it before
    validating.
  • Consistent branding. All user-facing CLI commands now read deepseek
    instead of gemini (deepseek --resume, deepseek mcp, deepseek extensions update, etc.).

What's Changed

Fixed

  • DeepSeek v4 HTTP 400 — missing reasoning_content. The server requires
    every assistant turn that used thinking mode to be replayed with its
    reasoning_content on the following request. Two bugs caused this to fail:

    • getMessageKey produced different keys for tool_calls: undefined and
      tool_calls: [], so cached reasoning_content was looked up under the
      wrong key on the next turn and dropped.
    • The Gemini-style history filter stripped any non-text fields on assistant
      turns, removing the cached reasoning even when the lookup succeeded.

    Fix: cache key normalization + smuggling reasoning_content inside a hidden
    Part on the assistant message so it survives history filtering and is
    reattached when the message is mapped back to the DeepSeek request.

    Files: packages/core/src/core/deepseekContentGenerator.ts,
    packages/core/src/core/deepseekContentGenerator.test.ts (new).

  • exit_plan_mode "Invalid plan" error. When the model proposed a plan
    without first writing it to disk, approval failed because the validator could
    not find the plan file. The tool now accepts an optional plan_content
    argument; when provided it writes the plan inside the validated plans
    directory before approval.

    Files: packages/core/src/tools/exit-plan-mode.ts,
    packages/core/src/tools/definitions/dynamic-declaration-helpers.ts.

  • Branding inconsistencies. All user-visible references to gemini in CLI
    output, error messages, resume hints and tests are now deepseek.

    Files: packages/cli/src/ui/components/SessionSummaryDisplay.tsx (+ test &
    snapshot), packages/cli/src/commands/extensions/{update,new}.ts,
    packages/cli/src/commands/extensions/update.test.ts,
    packages/cli/src/commands/mcp/enableDisable.ts,
    packages/cli/src/config/extension-manager.ts,
    packages/cli/src/config/mcp/mcpServerEnablement.ts,
    packages/cli/src/acp/commands/extensions.ts.

Added

  • plan_content parameter on the exit_plan_mode tool declaration. When
    set, the tool writes the plan to the plans directory before validation,
    letting the model exit plan mode in a single step.
  • stream_options.include_usage: true on streaming requests, so the final
    SSE chunk carries the real token usage (no more zero-token rows in
    /stats).
  • prompt_cache_hit_tokens mapping. DeepSeek's cache-hit counter is now
    surfaced as cachedContentTokenCount in the Gemini-shaped usage metadata,
    with a debug log line on every hit.
  • DEEPSEEK_DEBUG environment variable. When set to a truthy value, the
    generator logs request/response shapes, cache hits/misses, and reasoning
    recovery decisions to stderr.
  • State directory ~/.deepseek/. The reasoning cache and debug logs now
    live under the user's home directory, independent of the working directory
    and any GEMINI_CLI_HOME overrides.
  • Regression test for getMessageKey cache key normalization
    (packages/core/src/core/deepseekContentGenerator.test.ts).

Changed

  • Classifier complexity threshold raised from 50 to 70. More tasks now
    route to deepseek-v4-flash instead of deepseek-v4-pro, reducing cost
    without observable quality regression on the eval set.
  • Classifier no longer uses thinking mode. Classification is a structured
    JSON output task and does not benefit from chain-of-thought; disabling
    reasoning saves both tokens and a full extra round-trip of latency.
    File: packages/core/src/routing/strategies/deepseekClassifierStrategy.ts.
  • Tools sent to the API in alphabetical order. Stable ordering improves
    DeepSeek's prompt-prefix cache hit rate across turns.

Upgrade notes

  • No configuration migration is required. Existing ~/.gemini/ settings are
    still read; only the runtime cache and debug logs move to ~/.deepseek/.
  • If you set GEMINI_CLI_HOME to work around earlier path issues, you can
    unset it — the duplication bug it caused has been removed upstream.
  • If you scripted around the old gemini --resume resume hint, switch to
    deepseek --resume.

Verification

# Smoke test
DEEPSEEK_API_KEY=sk-... deepseek --prompt "ping"

# With debug logging
DEEPSEEK_API_KEY=sk-... DEEPSEEK_DEBUG=1 deepseek --prompt "design a small REST API"

Tests: npx vitest run packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx packages/cli/src/commands/extensions/update.test.ts
(16/16 passing) and npx tsc --noEmit -p packages/cli/tsconfig.json (clean).