DeepSeek Harness Plugin

KannaKuron/dsh-agent-lang

Stars ★ 1 Downloads (30d) 3,349 Category Models & Providers Added 2026-09-01 npm dsh-agent-lang

Three independent language channels for model output — tool-call descriptions (every tool-call card title, including run_code in PTC-style presets), thinking, and replies — each set to follow the web GUI language, force a specific language, or turn off (default: only descriptions, following the GUI). One global runtime-context prompt directive on the host; the client half reports the GUI language; a Settings plugin card switches the modes.

Install

# from npm (prebuilt)

dsh plugin --profile web add dsh-agent-lang

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:KannaKuron/dsh-agent-lang

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

简体中文 | English | 日本語 | 한국어

Agent language control — three independently configured channels for DeepSeek Harness (DSH) model output: tool-call descriptions (including PTC mode's run_code description, 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

  1. Install, restart DSH, open the Web GUI (browser language or setting on Chinese);
  2. ~/.dsh/settings.yaml gains a agent-lang: section (uiLocale: zh) once a page loaded;
  3. Any new session: tool-call descriptions come out in Chinese;
  4. Switch the GUI language in Settings → General — descriptions switch on the next request;
  5. Settings → Plugins → Tool Description Language: pick ja from 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: PromptContext is still { name, order, text }, with order 125 (moved to 130 after the official table claimed 125, see v0.12.0) still after the official CONTEXT_ORDERS. The interpolate: false flag 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 + configForms above 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+) and plugins.bundle.config keyed 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 name IconChevronDownOutline14 does 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.

Relation to dsh 0.2.1's "description first" wording (complementary, zero conflict)

Since dsh 0.2.1 the bash / pwsh tool schemas carry the "Provide description before command in the arguments" guidance, so the UI renders an arrived description already during a call's preparing phase (run_code front-loaded description in alpha.3–alpha.4 as well; alpha.5 reverted it to code first and dropped the sentence). This is orthogonal to this plugin and complementary:

  • the host owns the order: nudging the model to send the description first, so the preparing-phase card has a title to render;
  • this plugin owns the language: the same runtime-context directive decides which language those descriptions (preparing-phase titles included) are written in.

The official English example wording in the schemas is unchanged, so the "Chinese UI, English descriptions" gap is still this plugin's description channel to close. Calls to new tools (0.2.1's schedule_* reminder tools included) are covered automatically: the channel is global and keys off the call's description argument, independent of tool-list churn. Re-verified against dsh 0.2.1-alpha.5: the systemPrompt.context signature is unchanged, and CONTEXT_ORDERS gained TEAM_IDENTITY: 125 (0.2.1-alpha.3) — this plugin's slot moved from 125 to 130 (v0.12.0).

Known limits

  • minimal is 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

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.