Install
Inside DeepSeek Harness, with dsh-market
dsh plugin --profile web add dshmarket
Or from the command line
dsh plugin --profile web add dsh-agent-lang
Installing runs third-party code with your own permissions — it can read your files, use your credentials and reach the network. Review the source first, and pin a commit (github:owner/repo#sha) when you can.
README
Agent language control — three independently configured channels for DeepSeek Harness (DSH) model output: tool-call descriptions (including PTC mode's
run_codedescription, the call card title), model thinking, and replies — each follows the GUI language, forces a fixed language, or turns off, with one-click sync-all / off-all shortcuts. By default only the descriptions channel is on.
Why
Every tool call in DSH carries a required description argument that is displayed verbatim as the call's UI label. The tool schemas describe that field with English wording and English examples ("5-10 words … Examples: 'Count TODO markers…'"), so models default to English descriptions regardless of the GUI language.
This plugin changes only the PROMPT side: one global dynamic runtime-context directive states the GUI's display language and instructs the model to write every tool-call description in it. No preset, persona, or tool schema is modified — those are deployment-owned assets an upgrade overwrites anyway.
Coverage
| Mode / preset | Supported | Notes |
|---|---|---|
standard |
✅ | |
ptc (PTC mode, formerly code) |
✅ | run_code's description included |
cordis (Creation mode) |
✅ | |
User presets (incl. ptc-cordis, dsh-gitbash-shell variants) |
✅ | Host-plane registration covers every unsealed preset in the process |
| Agent-Team teammates / ordinary subagents (v0.8.0) | ✅ on by default | Teammate and subagent requests carry the same directive; Settings can switch to "main agent only". A forked teammate still inherits the main agent's completed-turn history snapshot (which carries the directive already committed there) — no switch rewrites history |
minimal |
❌ (by design) | minimal mounts a complete persona and suppresses runtime context — its prompt is sealed against every late contributor; no prompt-level plugin can reach it |
How it works
- Detection order (auto mode): the explicit Settings → General → Language choice > the browser-reported active locale. English is a regular target too (v0.3.0+): some models mix languages inside thinking/replies, and an explicit English directive pins them; only a fully undetected language injects nothing.
- Channel:
systemPrompt.context()— the same per-request runtime-context snapshot as the sandbox/approval policies, rendered near the end of each request so recency beats the English tool-schema guidance. A GUI language switch takes effect on the very next request. - Settings card: Settings → Plugins pairs Host-served namespaces with registered cards automatically; switch behavior (follow GUI language / force a BCP 47 tag — pick from the dropdown or type one, e.g.
zh,ja/ off) and inspect the detection chain.
Install
dsh plugin --profile web add dsh-agent-lang
Plain JS, no build step, no installed dependencies (schemastery is a peer resolved through the profile). Restart DSH after installing.
Verify
- Install, restart DSH, open the Web GUI (browser language or setting on Chinese);
~/.dsh/settings.yamlgains aagent-lang:section (uiLocale: zh) once a page loaded;- Any new session: tool-call descriptions come out in Chinese;
- Switch the GUI language in Settings → General — descriptions switch on the next request;
- Settings → Plugins → Tool Description Language: pick
jafrom the force-language dropdown (or type any tag), switch off, etc.
Version compatibility
dsh 0.1.7-rc.2 and rc.1 were checked item by item on a real isolated instance (rc.2 record, per-surface zero-diff evidence and live evidence: CHANGELOG v0.7.1; rc.1: v0.7.0); the same holds for 0.1.6-alpha.1 (CHANGELOG v0.4.3):
- The
systemPrompt.context()contract is unchanged:PromptContextis still{ name, order, text }, with order 125 still after the official CONTEXT_ORDERS. Theinterpolate: falseflag applies to sections only, which this plugin does not use. - The injected text carries no
{{...}}interpolation risk: every language source (forced tag, explicit setting, browser report) passes BCP47 validation before it reaches the text. - The settings surface still splits at 0.1.7 (row
Config+configFormsabove it, the registered namespace below), and the settings card still ships both seats:settings.plugin.item(hosts ≤ 0.1.6, where it silently waits on 0.1.7+) andplugins.bundle.configkeyed by the package name (0.1.6-alpha.2+, live on 0.1.7). - The manifest declares the compatibility peer dsh 0.1.7-rc.1 enforces —
"@deepseek-ai/dsh": ">=0.1.0"(optional, so package managers never auto-install a prerelease-only package). The declaration puts this plugin under the gate (it carried no such peer before, so it was never validated) while leaving the range open-ended: the plugin adapts to host changes by runtime detection, so a future dsh upgrade never disables it silently. - Added for rc.2 (v0.7.1): rc.2 rolled out the unified design tokens across the client — corner radii
--dsw-radius-*and the focus ring--dsw-focus-ring-*(the official sheet paints none under pointer modality). The card follows with "new token + old literal fallback", so hosts ≤ rc.1 render exactly as before. The same release fixes a silent defect present since the first version: the probed chevron nameIconChevronDownOutline14does not exist on 0.1.7 (the family is…OutlineRegular/…OutlineMedium), so the card had always shown the text "▾"; it now probes a candidate chain.
Known limits
minimalis sealed by design (see table).- Without a browser page (pure CLI deployments) only the explicit choice is detectable.
- The GUI language is one global value; the most recently loaded page's report wins.
- Subagents / workflow models see the directive too (their descriptions are user-facing as well).
License
MIT
Comments
Comments live in GitHub Discussions. Sign in with GitHub to post or react.