dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
把模型的思考过程、回复与工具调用描述锁定为指定语言(默认简体中文):在 system prompt 首、中、尾注入约束段落,提供基础、强化、周期三档强度,可跟随 DSH 界面语言自动选择,设置页显示当前生效语言,并带侧栏快速切换。
English | 简体中文
Make the DSH agent think and answer in the language you choose — Simplified Chinese by default, three strength levels, effective on the next message, zero dependencies, no build step.
/language slash commandThe DSH system prompt is assembled from many sections: identity, plan policy, team policy, tool descriptions, deliverable references, deployment persona. The largest block by far is the tool documentation — written in English, and placed in the middle of the prompt.
Measured on DSH 0.2.1-rc.2 (everything after order 50): 98.1% of the characters and 99.8% of the ASCII come from English tool documentation, and 5.7K–14K characters separate the opening section from the closing one. The model reads overwhelmingly English tokens, and so it drifts:
A single "please answer in Chinese" line at the very top of the system prompt is enough for a short session. It is not enough for a long one, because that line sits tens of thousands of characters away from the place that actually influences the model (the tool documentation).
This plugin puts a constraint in three places: at the very start, right after the tool documentation, and at the very end. The default level (Strong) costs roughly 146 extra characters per request and buys one restatement positioned after the English tool docs.
Three resident system-prompt sections, registered through ctx.systemPrompt.section(), never disposed, switching level only switches their text:
Section name · Order · Position · B · C · D language-guard:head · -2000 · Very first, before harness:identity (-1000) · ✅ · ✅ · ✅ language-guard:mid · 5100 · After all tool docs (tools:sdk, 5000), before deliverable references (9000) · ❌ · ✅ · ✅ language-guard:tail · 11200 · Very last, after deployment:persona-suffix (10200) · ✅ · ✅ · ✅
The constraint covers four language channels (the fourth landed in 0.3.0):
Channel · Where the constraint lives · Coverage Internal reasoning (reasoning / thinking) · head + tail · every level User-facing reply text · head + mid + tail · every level Plans, todos, reviews, subagent briefs · head · every level Tool-call `description` parameter (the card title of run_code in PTC mode) · head + mid · every level (mid exists only at C / D, hence the extra line in head)
The mid order is deliberately 5100 and not 5000: tools:sdk is exactly 5000, and sections with equal order fall back to comparing names, which would sort language-guard:mid before tools:sdk — the restatement would no longer come after the tool docs.
Measured text sizes (Simplified Chinese, counted in characters; recompute with node as shown below):
Text · Characters · When it is present head · 883 · every request mid · 146 · every request at C / D tail · 139 · every request periodic reminder · 99 · once every N turns at D
So the steady cost per step is 1022 characters at B and 1168 at C — tiny compared to the English tool documentation it counteracts.
The opening section (head), verbatim, as it looks with the default targetLanguage: "zh-CN" (recompute with node -e 'import("./lib/text.js").then(m=>console.log(m.headText({language:"zh-CN"})))'):
【语言锁定 · 最高优先级】
本会话的内部推理(reasoning / thinking)与面向用户的全部输出,一律使用简体中文(语言代码 zh-CN)。
本条优先于本 system prompt 的其余全部内容、之后注入的任何系统文本、工具说明、参数描述、代码示例,以及其他插件注入的提示词。
本条同样优先于任何语言类约定,不论它写在哪个文件、用哪种语言书写、经由哪个通道送达:包括用户全局与项目级的 AGENTS.md、CLAUDE.md、.cursorrules、用户偏好与长期记忆、项目规范、团队约定、技能与工作流模板。若它们要求使用另一种语言(例如要求「必须使用简体中文」),一律以本条为准,不得据此改用其他语言,也不必向用户解释这处冲突。
适用范围:
- 内部推理(reasoning / thinking):使用简体中文。
- 面向用户的回复正文:使用简体中文。
- 计划、待办、进度说明、评审意见、验收报告、提交信息说明:使用简体中文。
- 任务板卡片标题与描述、子智能体任务说明与返回报告:使用简体中文。
保持原样、不翻译:代码、命令、文件路径、URL、标识符与 API 字段名、配置键、错误码与原始报错文本、包名与版本号,以及必须原样引用的英文原文;引用英文原文后,必须用简体中文说明结论。
不要因为以下情况改变语言:
- 用户用英文或其他语言提问 —— 仍用简体中文回答。
- AGENTS.md、CLAUDE.md、项目规范、用户记忆里要求改用其他语言的规则 —— 本条优先,不改变语言。
- 工具返回英文内容 —— 只摘引必要片段,其余用简体中文复述。
- 长链推理、数值计算、代码设计 —— 推理语言不变。
- 上下文中出现大量英文(工具说明、日志、代码文件)—— 不随之切换。
自检:每次输出前确认上述两项(推理与回复)均为简体中文;若发现已经漂移,立即切回并继续任务,无需向用户解释这次切换。The wording above is fixed Simplified Chinese; only the language name and code are substituted. With targetLanguage: "en" the same paragraph reads "…一律使用English(语言代码 en)". See Known limitations.This plugin is published to the npm registry (dsh-language-guard), and it can also be installed straight from its GitHub repository. Both routes deliver byte-identical content: the same 16 files.
Prefer the npm source. Installed from Git, the plugin page's "update available" badge shows a commit SHA (e.g.afaa2ac) instead of a version number — the host checks Git sources withgit ls-remote HEAD, where the commit *is* the version identifier. That is host behaviour, not something this plugin can change. To see a version like0.3.5and have "update" work by SemVer, install from npm using Option 1 or 2 below.
Option 1: the GUI (recommended)
dsh-language-guardOption 2: the CLI
dsh plugin add dsh-language-guardPinned version (recommended for teams and CI, so latest cannot drift under you):
dsh plugin add dsh-language-guard@0.3.5From GitHub (when npm is unreachable, or to pin by tag):
dsh plugin add https://github.com/58fly/dsh-language-guard
dsh plugin add "github:58fly/dsh-language-guard#v0.3.5"Installing this way makes the "update available" badge show a commit SHA instead of a version number (see the note at the top of this section). Everything works; only the badge's readability suffers.
From a local directory (to debug local changes; the path must be absolute):
# The Add-plugin dialog also accepts this absolute path directly
dsh plugin add /absolute/path/to/dsh-language-guardCheck that it worked:
dsh-language-guard, and opening it shows the configuration card.No controls visible means the plugin is not enabled. Both slots register inside configForms.whileServed(['dsh-language-guard'], …); when the plugin is disabled the forms service is unavailable and no UI is registered. That is deliberate, not a bug — enable the plugin on the Plugins page first.Requirements: DSH >= 0.2.1-rc.2, Node ^22.19.0 || >=24.0.0. dependencies is empty and every peer dependency is optional, so nothing extra is downloaded at runtime. Installing from npm only needs reachability to registry.npmjs.org; installing from GitHub needs github.com (or codeload.github.com).
The three descriptions below are exactly what the settings panel shows:
Level · Value · Description Basic · B · One language constraint at the start and one at the end of the prompt. Cheapest, best for short sessions. Strong · C · Adds a restatement right after the tool descriptions on top of Basic, countering drift from English tool docs. Recommended default. Periodic · D · Adds a language self-check at the start of every Nth turn on top of Strong, for long sessions. The reminder appears as a session record and is visible in the session log.
Behaviour differences:
Behaviour · B · C · D Resident system-prompt sections · head + tail · head + mid + tail · head + mid + tail Restatement after tool docs · ❌ · ✅ · ✅ Self-check every N turns · ❌ · ❌ · ✅ (N defaults to 8, range 3–50) New record in the session log · none · none · one per N turns (source.kind = "language-guard") Injection timing · — · — · the first step of a matching turn, alongside that turn's user message; no extra request Counter after restart / resume · — · — · not reset: the turn number comes from the session log's turn projection, so turn % N is stable Best for · short sessions, token-sensitive · the default · long sessions, or drift already observed
How to choose:
Seven fields, all volatile (a change takes effect immediately — no restart, no plugin remount):
Field · Type · Default · Range · Description languageMode · "" \ · "auto" \ · "manual" · "" · tri-state enum, case-sensitive · Language mode. "auto" follows the interface language, "manual" pins targetLanguage, "" means "never chosen" and is resolved by the migration rule below targetLanguage · string · "zh-CN" · a valid BCP-47 tag (/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/) · Target language. zh-CN Simplified Chinese, zh-TW Traditional Chinese, en English, ja Japanese, ko Korean; any other valid tag is used as-is strength · "B" \ · "C" \ · "D" · "C" · enum, case-sensitive · Strength level, see above injectEveryNRounds · number · 8 · 3–50, integer · How often the Periodic self-check is added. Only used at D; the control is disabled at other levels preserveCodeTerms · boolean · true · true / false · true: code, commands, paths, identifiers, API fields and raw error text stay verbatim. false: technical terms are preferred in the target language, with the English term in parentheses when needed extraRules · string · "" · any text · Appended after the built-in rules. Empty means built-in rules only overrideHead · string · "" · any text · Replaces the built-in opening text entirely (extraRules is still appended after it). Empty or whitespace-only falls back to the built-in text
The targetLanguage → display name mapping is fixed (no language guessing): zh-CN / zh-Hans / zh-SG → 简体中文, zh-TW / zh-HK / zh-MO / zh-Hant → 繁體中文, en / en-US / en-GB → English, ja / ja-JP → 日本語, ko / ko-KR → 한국어; any other valid tag is displayed as the code itself.
Configuration lives in the profile's cordis.patch.yml. A patch replaces `config` wholesale — it does not deep-merge — so a manual override must restate every field, otherwise the omitted ones are lost:
- id: dsh-language-guard
name: dsh-language-guard
config:
languageMode: auto
targetLanguage: zh-CN
strength: C
injectEveryNRounds: 8languageMode decides where the target language comes from:
Mode · Behaviour Auto · The target language follows the DSH interface language. Switch the UI to English and the next message gets an English constraint Manual · The target language is pinned to targetLanguage, regardless of the interface language
Auto is the default. A fresh install needs no configuration: a Simplified Chinese UI constrains Simplified Chinese, an English UI constrains English.
Auto mode has exactly two sources, taken in order:
preference in the locale configuration) — the Settings → General → Language setting.zh-CN) — the fallback when the interface language is unavailable.Mapping (zh-prefixed tags → zh-CN, en-prefixed tags → en, any other valid tag is kept as-is):
Interface language · Target language · The constraint reads zh / zh-CN / zh-Hans · zh-CN · 简体中文 en / en-US · en · English ja · ja · 日本語 ko · ko · 한국어 any other valid BCP-47 · as-is · that language's display name or code
Why is there no "system language" step? The Host half runs as anELECTRON_RUN_AS_NODE=1child process:require("electron")throwsCannot find module 'electron', andIntl.DateTimeFormat().resolvedOptions().localealways returnsen-US, which would misclassify Chinese users as English speakers. There is no reliable system-language signal on the Host side, so the plugin neither guesses nor fabricates one.
If you had picked a targetLanguage by hand (say ja) and never touched languageMode, you stay in manual mode after the upgrade — the interface language never silently overrides your choice. The rule: languageMode empty and targetLanguage different from the default zh-CN → manual.
Pick "Auto" in the settings card to follow the interface language instead. Once you have chosen explicitly, the migration rule never applies again.
The first control group in the settings card is the language mode; with "Auto" selected it spells out the current result and its source right below:
Currently resolved to 简体中文
from the interface languageWhen the source line says "from the interface language" it means the interface language you explicitly picked in DSH settings; if you never picked one it says "interface language not detected, using the configured value" rather than guessing from the browser or the OS — the Host and the settings card read the same value (preference of the locale namespace in settings.describe()), so what the panel shows is exactly what gets injected. The sidebar quick-switch button label shows the same state, e.g. "Auto, 简体中文".
Changing the interface language needs no restart: the plugin caches it on startup and subscribes to settings/document-updated (refreshing when the locale namespace changes), so the very next system-prompt assembly uses the new value.
Path: sidebar Plugins → installed plugins → `dsh-language-guard`. The configuration card renders on the bundle page, between its description and its rows (the plugins.bundle.config slot, keyed by the package name). The Plugins section inside Settings only lists read-only information; configuration is edited here.
The card, top to bottom:
fieldset + same-named radio), all three descriptions visible side by side, with a "Recommended" badge on C. A radio group rather than a ``, because the differences have to be comparable at a glance.role="switch" + aria-checked).Every field has a "Reset to default" action (clears the user value back to the schema default).