DeepSeek Harness Plugin

qwert702/dsh-auto-translate

Category UI Enhancements Added 2026-08-20

Full-pipeline Chinese translation for the dsh web GUI: live translation of the model reasoning as it streams, in-place Chinese below each English reply, and one-line Chinese summaries for tool outputs and tool-call glosses — a standalone provider request that never enters the session transcript.

Install

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

dsh plugin --profile web add github:qwert702/dsh-auto-translate

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 | 中文

Full-pipeline Chinese translation for the DeepSeek Harness Web GUI. When the model is thinking (the Think disclosure), writing its final reply, or producing tool output, English content gets a Chinese rendering in place — translated live while the model is still streaming. Every translation is a standalone provider request that never enters the session transcript: no context window cost, no conversation-history pollution.

Install (one command):

dsh plugin add qwert702/dsh-auto-translate

Restart the harness (dsh web) and refresh the page.

Features

  • Live reasoning translation — inside each Think disclosure row, the expanded body shows the original thinking text followed by a Chinese translation; while the model is still reasoning the translation updates on a debounced cadence, and once the step settles the full text is translated once and cached.
  • Inline reply translation — every English text block gets a small Chinese line (with a badge) directly beneath it. Chinese replies and code-dominated output are skipped heuristically.
  • Tool-output summaries — for every settled tool call, a line tool — 中文含义 plus a summary renders at the end of the turn after the tool card sequence, summarizing the tool's text output in Chinese (a summary, not a line-by-line translation of raw output). The summary lives at the turn tail instead of inside the card because the chat view has no additive seat inside a tool card, and the tool-call renderer cannot be shadowed without losing the dedicated tool views (bash / web / read …) — see below.
  • Zero context cost — translation and summary requests are standalone provider /chat/completions calls made by the node half, fully outside the agent loop; the plugin adds no prompts, tools, or messages to any conversation and never rewrites a model request.
  • Configurable model — defaults to the current conversation's model; an override can be set in settings. When the conversation model id is unknown to the provider, the host retries once with deepseek-chat.

How it works (shadow rendering, no slot replacement)

The chat view has no additive seat inside a message, so the plugin uses the ecosystem's shadow registration technique: it registers the assistant-step renderer on conversation.chat.node at priority: -100, which shadows the harness's priority: 0 default and owns the in-place reasoning and reply translations. The renderer rebuilds the default presentation from public primitives (MarkdownText / DisclosureRow / JsonBlock from dsh-client-ui-primitives, ImageGallery from dsh-client-ui-attachment) — the same approach as the dsh-better-markdown plugin.

The tool-call node is deliberately NOT shadowed: its default renderer owns the sole declaration of the tool.call.toolview child slot (slot declarations are globally unique), so shadowing it either loses the dedicated tool views (bash / web / read …) or throws a duplicate-declaration error at startup. Tool summaries therefore ride the additive conversation.chat.turnTail chain seat, rendered after the turn's tool cards.

If a shadow renderer crashes it abdicates and the harness default takes over transparently.

Settings (optional)

Add a dsh-auto-translate namespace to ~/.dsh/settings.yaml:

dsh-auto-translate:
  enabled: true          # master switch
  model: ''              # '' = follow the current conversation's model; or e.g. deepseek-chat / deepseek-reasoner
  apiKeyRef: DEEPSEEK_API_KEY   # credential reference resolved by the harness credentials service
  baseURL: https://api.deepseek.com
  temperature: 0.3       # sampling temperature for translation requests
  maxInputChars: 4000    # input truncation guard

All fields default as above. The API key stays server-side — it is resolved through the harness credentials service and never leaves the host.

Repo layout

  • lib/index.js — node half: settings namespace + POST /api/auto-translate/translate route (standalone translate/summarize requests, mode: translate | summarize, with a model fallback).
  • lib/client.js — browser half: the assistant-step shadow registration (priority: -100, in-place reasoning/reply translations) plus the additive conversation.chat.turnTail chain entry (tool-output summaries).
  • test/smoke.cjsnode test/smoke.cjs: syntax checks, host route paths (disabled / bad-request / empty / no-key / ok / summarize / model-fallback), client registration assertions, and ReactDOMServer renders (thinking / text / streaming / tool summary).

Known limitations

  • Conflicts with dsh-better-markdown — both shadow assistant-step at priority: -100; installing both throws a duplicate-key error at startup. Install one; to coexist, change one side's priority.
  • Tool summaries live at the turn tail, not inside cards — the chat view has no additive seat inside a tool card and the tool-call renderer cannot be shadowed without losing the dedicated tool views, so summaries render after the turn's tool card sequence.
  • Owns the default rendering — shadowing means the thinking/text block presentation is maintained by this plugin; a dsh upgrade that changes the internal rendering may need an adaptation (a crash abdicates to the harness default, so nothing breaks silently).
  • Streaming translations are provisional — while output is still streaming, the translation reflects the text seen so far and updates on a debounced cadence; when output stops it is re-translated from the full text.
  • Tool summaries cover text blocks only — images and binary output are not translated; long outputs are truncated (maxInputChars) first.
  • Heuristics — replies shorter than ~10 letters, CJK/latin mixed text, and code-dominated output are not translated (isEnglishProse / isMostlyCode in lib/client.js).
  • Cache — translations are cached in browser memory per node/call identity; a page refresh re-requests the same content.
  • Settings UI — configured through settings.yaml; no settings panel yet.

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.