From a239968f5b684317191cfec67116d518aa0b0888 Mon Sep 17 00:00:00 2001 From: Hunter Bown Date: Mon, 4 May 2026 12:10:23 -0500 Subject: [PATCH] fix(prompts): mirror user's language in reasoning + reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DeepSeek V4's `reasoning_content` channel inherits the system prompt's English bias even when users write in Chinese, so the visible thinking trace stays in English alongside (sometimes mixed-language) replies. Adds a `## Language` section near the top of `base.md` directing the model to mirror the user's language in *both* `reasoning_content` and the final reply, with a carve-out so identifiers, file paths, tool names, and log lines stay in their original form (translating `read_file` to `读取文件` would break tool calls). Default remains English when no clear signal is present, so existing behaviour is preserved. Includes a structural test in `crates/tui/src/prompts.rs` that asserts the section ships in every mode (Agent / Yolo / Plan). Wording is intentionally not asserted on, per the existing test module's "don't fail on prose" comment. Reported via the project Telegram community (#588). Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/tui/src/prompts.rs | 14 ++++++++++++++ crates/tui/src/prompts/base.md | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/crates/tui/src/prompts.rs b/crates/tui/src/prompts.rs index 9f1eeb76..f8711741 100644 --- a/crates/tui/src/prompts.rs +++ b/crates/tui/src/prompts.rs @@ -606,6 +606,20 @@ mod tests { assert!(prompt.contains("### `rlm`")); } + /// #588: language-mirroring directive must ship in every mode so + /// DeepSeek's `reasoning_content` and final reply follow the user's + /// language. Structural test — wording is not a test concern. + #[test] + fn language_mirroring_section_present_in_all_modes() { + for mode in [AppMode::Agent, AppMode::Yolo, AppMode::Plan] { + let prompt = compose_prompt(mode, Personality::Calm); + assert!( + prompt.contains("## Language"), + "## Language section missing from mode {mode:?}" + ); + } + } + /// #358: rlm guidance was reframed from "first-class" to "specialty /// tool" — verify the structural markers are present so a future /// change doesn't silently remove the RLM section entirely. diff --git a/crates/tui/src/prompts/base.md b/crates/tui/src/prompts/base.md index 8c4d13ec..2d5f246d 100644 --- a/crates/tui/src/prompts/base.md +++ b/crates/tui/src/prompts/base.md @@ -1,5 +1,11 @@ You are DeepSeek TUI. You're already running inside it — don't try to launch a `deepseek` or `deepseek-tui` binary. +## Language + +Detect the language the user writes in and respond in that same language — including your internal reasoning. If the user writes in Simplified Chinese (简体中文), your `reasoning_content` and final reply must both be in Simplified Chinese. If they switch languages mid-conversation, switch with them. The default when no clear signal is present is English. + +Code, file paths, identifiers, tool names, and log lines stay in their original form — translating `read_file` to `读取文件` would break tool calls. Only natural-language prose mirrors the user. + ## Preamble Rhythm When starting work on a user request, open with a short, momentum-building line that names the action you're taking. Keep it reserved — state what you're doing, not how you feel about it.