Skip to content

feat: DeepSeek V4 support with reasoning-effort control (0.4.0) - #17

Merged
Hmbown merged 4 commits into
mainfrom
expand-deepseek-first-v0.3.33
Apr 24, 2026
Merged

feat: DeepSeek V4 support with reasoning-effort control (0.4.0)#17
Hmbown merged 4 commits into
mainfrom
expand-deepseek-first-v0.3.33

Conversation

@Hmbown

@Hmbown Hmbown commented Apr 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds first-class support for deepseek-v4-pro and deepseek-v4-flash with 1M context windows and current DeepSeek alias handling.
  • Fixes DeepSeek V4 thinking-mode requests to send top-level thinking in raw Chat Completions JSON, not SDK-only extra_body.
  • Preserves prior assistant reasoning_content for all thinking-mode tool-call turns so multi-turn tool conversations do not hit DeepSeek's HTTP 400 replay error.
  • Fixes the npm wrapper first-run download race and keeps the 0.4.0 release path aligned with GitHub release assets and npm Trusted Publishing.

Model & pricing

Model Context Cache hit in Cache miss in Output
deepseek-v4-pro 1M $0.145 / 1M $1.74 / 1M $3.48 / 1M
deepseek-v4-flash 1M $0.028 / 1M $0.14 / 1M $0.28 / 1M

Legacy deepseek-chat, deepseek-reasoner, deepseek-r1, deepseek-v3, and deepseek-v3.2 remain accepted local aliases and now budget against the current V4 1M context unless an explicit context suffix is provided.

Reasoning effort

Config field reasoning_effort in ~/.deepseek/config.toml:

  • off -> thinking.type = "disabled"
  • low / medium / high -> reasoning_effort: "high", thinking.type = "enabled"
  • max / xhigh -> reasoning_effort: "max", thinking.type = "enabled"

Test plan

  • cargo fmt --all -- --check
  • cargo check --workspace --all-targets --locked
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • cargo test --workspace --all-features --locked
  • cargo build --release --locked -p deepseek-tui-cli -p deepseek-tui
  • target/release/deepseek-tui doctor
  • Live DeepSeek V4 smoke: DEEPSEEK_MODEL=deepseek-v4-pro target/release/deepseek-tui --no-alt-screen --skip-onboarding -p "Reply with exactly OK."
  • npm local asset mirror: npm run release:check, npm pack, temp-install npx deepseek / npx deepseek-tui smoke

Hmbown and others added 3 commits April 23, 2026 15:43
Pivot the client to DeepSeek's documented OpenAI-compatible Chat Completions
API as the primary path. The Responses API probe is now gated behind
DEEPSEEK_EXPERIMENTAL_RESPONSES_API for local compatibility experiments only.

- Update pricing to DeepSeek's cache-hit vs cache-miss input tiers and wire
  cached-token fields from usage into cost tracking.
- Accept /v1 and /beta base URLs for OpenAI SDK compatibility and document
  /v1/models for live discovery and health checks.
- Refresh README, AGENTS, CONFIGURATION, ARCHITECTURE, and npm README to
  describe the documented endpoints, cache behavior, and env overrides.
- Extend engine, turn, session, UI, and client tests to cover the new path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds first-class support for deepseek-v4-pro and deepseek-v4-flash with
1M context windows and new per-model pricing. Introduces a reasoning-effort
tier (off/low/medium/high/max) plumbed through the request layer and a
Shift+Tab cycler with a header chip for live switching.

- Model registry: v4-pro (flagship) and v4-flash first-class; legacy
  deepseek-chat/reasoner/v3.2 kept as silent aliases of v4-flash.
- Defaults flipped to deepseek-v4-pro.
- Pricing: v4-pro \$0.145/\$1.74/\$3.48, v4-flash \$0.028/\$0.14/\$0.28 per 1M
  (cache-hit / cache-miss / output).
- 1M context window recognized for v4 models; MAX_COMPACTION_MESSAGE_THRESHOLD
  raised 150 → 500 so large-context runs don't prematurely compact.
- reasoning_effort config field + Op::SendMessage + Session plumbing.
- Client translates effort into reasoning_effort + extra_body.thinking for
  chat/completions, streaming, and Responses.
- Shift+Tab cycles off → high → max; header shows ⚡ chip.
- npm publish job added to release.yml (OIDC trusted publisher).
- Version bump 0.3.33 → 0.4.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the workspace to version 0.4.0, introducing comprehensive support for DeepSeek V4 models, including deepseek-v4-pro and deepseek-v4-flash. Key enhancements include the implementation of reasoning-effort tiers (off, high, max) with TUI integration, updated pricing calculations for context caching, and a refactored CLI that provides better command delegation to the TUI. The default model is transitioned to deepseek-v4-pro. Review feedback highlights several locations in the CLI where hardcoded legacy model IDs and test assertions need to be updated to maintain consistency with the new V4 defaults.

Comment thread crates/cli/src/main.rs Outdated
.deepseek
.model
.clone()
.unwrap_or_else(|| "deepseek-reasoner".to_string()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fallback model here is still hardcoded to deepseek-reasoner, which is now a legacy alias for deepseek-v4-flash. Since the flagship model has been updated to deepseek-v4-pro across the rest of the workspace (e.g., in crates/config/src/lib.rs and crates/tui/src/config.rs), this should be updated to maintain consistency for new logins.

Suggested change
.unwrap_or_else(|| "deepseek-reasoner".to_string()),
.unwrap_or_else(|| "deepseek-v4-pro".to_string()),

Comment thread crates/cli/src/main.rs Outdated
assert_eq!(store.config.api_key.as_deref(), Some("sk-test"));
assert_eq!(
store.config.default_text_model.as_deref(),
Some("deepseek-reasoner")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test assertion expects the legacy deepseek-reasoner model. It should be updated to reflect the new default model deepseek-v4-pro to match the intended behavior of the PR.

Suggested change
Some("deepseek-reasoner")
Some("deepseek-v4-pro")

Comment thread crates/cli/src/main.rs Outdated
);
let saved = std::fs::read_to_string(&path).expect("config should be written");
assert!(saved.contains("api_key = \"sk-test\""));
assert!(saved.contains("default_text_model = \"deepseek-reasoner\""));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test assertion should be updated to check for the new default model deepseek-v4-pro.

Suggested change
assert!(saved.contains("default_text_model = \"deepseek-reasoner\""));
assert!(saved.contains("default_text_model = \"deepseek-v4-pro\""));

devin-ai-integration[bot]

This comment was marked as resolved.

@Hmbown
Hmbown merged commit 39d5532 into main Apr 24, 2026
12 checks passed
@Hmbown
Hmbown deleted the expand-deepseek-first-v0.3.33 branch April 24, 2026 03:53
Hmbown added a commit that referenced this pull request May 25, 2026
Add  override in both integrations/feishu-bridge and web
package.json to resolve GHSA-q8mj-m7cp-5q26 (moderate DoS vulnerability
in qs < 6.15.2). Regenerated both package-lock.json files.

Dependabot alerts #16 (web) and #17 (feishu-bridge) are the two
vulnerabilities flagged during push.
Garfield1985 pushed a commit to Garfield1985/DeepSeek-TUI that referenced this pull request Sep 5, 2026
…room, fleet roles

Launch / splash
- The launch stage now samples the ambient clock and asks for frames while
  the mark surfaces, the card dissolves, or the water is alive. Before, the
  only clock driver was the transcript widget, which the launch screen never
  builds: surface_progress stayed at 0 and the braille whale was painted in
  the field colour forever (Hmbown#1), and the ocean ramp / ambient life were never
  wired into the stage (Hmbown#2, Hmbown#3). The stage paints the same ramp and life the
  transcript does; the life field ends at the composer dock.
- Recent rows resume (Hmbown#4): AppAction::LoadSession never dismissed the launch
  stage, so a resumed session loaded under a still-visible card.
- Tab cycles the mode on the launch screen (Hmbown#5): ModeCycle is AnyShell. The
  card's rule now reads `model (effort) · mode · permission` so the cycle is
  legible and matches the posture bar (Hmbown#7).

Work bar
- One-time migration of a persisted `work_surface_placement = "top"` to
  `bottom` (Hmbown#9), recorded in `work_surface_bottom_migrated`.
- Idle scheduled automations no longer count as work that auto-opens the
  dock (Hmbown#10); live shells, tasks, or a running automation still do.
- ORDER / AUTO_ORDER lead with TODO, then AGENTS (Hmbown#11). The dismissed dock
  re-opens on new work in any auto view, and `← for agents` works from the
  TODO view. Golden dock_80x24 re-blessed for the order.
- The posture bar's live counts are click targets that open the dock view
  they count; with nothing live a dim `todo` chip is the bottom affordance.

/mcp, /plugin, Extensions
- /mcp and every MCP action open Extensions → MCP rebuilt from the live
  pool snapshot; the text pager and its formatter are deleted (Hmbown#17Hmbown#19,
  Hmbown#25 — the `tools: 0` rows were the passive config snapshot).
- The markdown inline parser honours backslash escapes, so `computer\-use`
  renders as `computer-use` (Hmbown#21).
- Extensions keyboard follows grokbuild: Tab / Shift+Tab move across tabs,
  including mid-search with the query kept (Hmbown#22, Hmbown#23).

Automations
- New AutomationsView (`/automation`, `/automation show <id>`, the dock's
  background row): list + detail, p pause/resume, r run, x cancel the live
  run (via /task cancel), d delete (two-step confirm), Tab list↔detail.
  Every action is the typed command, so receipts match (Hmbown#14, Hmbown#16).
  `/automation list` and `print <id>` keep the text forms.

Fleet
- Roles are members. `add_fleet_model` requires a role (NeedsRole); the
  auto-enroll that turned every selected model into a role-less member is
  deleted with its 7 call sites; bare model pins are dropped on read so
  27 → 12 members (Hmbown#26). Picker ⇧F enrolls under `general`.
- Roster detail is role-first and compact (Hmbown#27, Hmbown#28); footer is
  ↑↓ · Enter · Tab workers · f · Esc (Hmbown#29). `m`, `s` and the model-picker
  shortcut event are removed.

Gates (run):
- cargo fmt --all -- --check: clean
- cargo clippy -p codewhale-tui -p codewhale-config --all-targets: clean
- scripts/dev-test.sh tui: 11658 tests run: 11658 passed, 13 skipped
- scripts/dev-test.sh tui-integration: 280 passed
- cargo test -p codewhale-config --lib: 634 passed; 0 failed; 1 ignored
- budget checks: dead-code 418/425, runtime-contract, provider-registry,
  command boundaries, migration manifest, locale parity (15 packs
  complete), product vocabulary: all PASS
- release build + tmux dogfood at 120x34: whale surfaces, ramp + fish on
  launch, Tab cycles mode, Enter on recent row resumes, dock closed at
  start and bottom/TODO-first when opened, /mcp opens Extensions with live
  tool counts, /automation opens the room, fleet shows 12 role members.
Not run: cargo nextest --workspace, tui-cucumber, web rung (no web change).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant