UncleK/dsh-think-translate
Thinking-chain UI translation for DeepSeek Harness: 8 target languages, local Ollama model primary with in-panel download, Google/Bing fallback
Project Overview项目介绍
A DSH plugin that translates the DeepSeek Harness Web UI's thinking chain, task cards, and answers into 8 target languages in real time on the display layer only, while originals stay intact and translations never enter the model context. Default provider is a local Ollama model (qwen2.5:7b/14b) with auto-download on first selection; Google and Bing serve as fallbacks when local inference is unavailable. Use it when DeepSeek-class models reason in a language you don't read. Caveat: it is purely a rendering layer—any code, file paths, URLs, or regex lines are deliberately skipped.
DSH 插件,在 DeepSeek Harness Web UI 的显示层实时翻译思考链、任务卡与回答为 8 种语言,原文保留,译文不进入模型上下文。默认调用本地 Ollama(qwen2.5:7b/14b),首次选择自动下载;本地不可用时回退到 Google/Bing 联网翻译。支持段落/句子批量、LRU 缓存、失败重试与失败结果不缓存,代码、路径、URL、正则等被保护不译。安装方式:dsh plugin --profile web add dsh-think-translate,重启 web 即生效。注意:纯显示层插件,模型上下文不受影响。
请帮我了解并安装插件:【dsh-think-translate】【https://github.com/UncleK/dsh-think-translate】
Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。
Or use CLI install (for developers)或使用命令行安装(适合开发者)
CLI Install命令行安装
dsh plugin --profile web add dsh-think-translate
把 UncleK/dsh-think-translate 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
Translate the reasoning / thinking chain (chain-of-thought), task cards and answers of the DeepSeek Harness Web UI into one of 8 target languages — in real time, on the display layer only. The originals stay untouched in the transcript, and the translated text never enters the model context.
✨ Why dsh-think-translate
DeepSeek-class models often reason in Chinese — or in whatever language they happen to think in. dsh-think-translate renders the Think row, task cards and answer in your language while you watch, like subtitles for the model's thinking.
- 🕵️ Read any thinking chain — reasoning, chain-of-thought, task cards and answers translated in real time, streamed batch by batch
- 🌍 8 languages, one consistent UI — 中文 / English / 日本語 / 한국어 / Español / Français / Deutsch / Русский; the settings panel, thinking rows and task cards all follow your choice, and it persists across reloads
- 🔗 Dynamic provider chain — order providers by drag-and-drop and enable/disable each one. Built-ins (google gtx, bing, local Ollama) plus any number of custom providers; the chain already ends with the free providers, so a second fallback pass is a config-file option, not a UI one
- 🔌 Custom providers (OpenAI & Anthropic) — add arbitrary OpenAI-compatible endpoints (any
/v1/chat/completionsgateway) or native Anthropic Messages API endpoints (Claude) from the settings panel: name, type, base URL, API key, model - 🪄 DSH provider discovery — providers already configured in DSH's
settings.yaml(llm-pi-ai.providers, e.g. linuxdo-hub, coding-hub) are auto-discovered and appear in the chain as read-only "DSH" entries, and one button in settings rescans and adds them all at once; keys are resolved from.credentials.yamlat runtime and never written to the plugin's config. The harness's own default route counts too: whenagent-default-modelpoints atdeepseek-official, DeepSeek's API is offered as one more DSH entry - 🔒 Private & offline-first — local Ollama (qwen2.5:7b / 14b or custom) is a first-class provider: free, unlimited, nothing leaves your machine. First local-model selection auto-downloads the model with a live progress bar and enables it when done
- 🧠 Zero context cost — pure display layer: the model still sees the original text, and translated text never consumes the context window
- ☁️ Google / Bing fallback — automatic switch when other providers are unavailable (google goes through a Node CONNECT tunnel using the system proxy, bypassing anti-bot blocks)
- 🛡️ Code-safe — file paths, commands, URLs, regexes and pure-code lines are never translated
- 🧩 Paragraph & sentence-aware chunking — long thinking chains are split on blank lines (paragraph structure preserved) and further batched by sentence, so even a small local model keeps quality
- ⏱️ Resilient — 3× backoff retries, per-provider test buttons, failed results never cached
- 🎚️ Adjustable translation timing — pre-translate everything, lazy-load historical chains (default), or translate only the expanded chain
📦 Installation
# Option 1: npm (recommended)
dsh plugin --profile web add dsh-think-translate
# then restart web
# Option 2: GitHub
dsh plugin --profile web add github:UncleK/dsh-think-translate
# Option 3: manual (junction + patch)
# 1. link the package into the profile's node_modules
New-Item -ItemType Junction -Path "$HOME\.dsh\profiles\node_modules\dsh-think-translate" `
-Target "<repo path>"
# 2. add to "$HOME\.dsh\profiles\web\cordis.patch.yml":
# - insert:
# - id: dsh-think-translate
# name: dsh-think-translate
# 3. restart web
🧯 After a DSH upgrade
Third-party client plugins load through DSH's client module graph, and that graph is composed once per process — a composition that failed is remembered in memory until the process restarts. So these three things commonly bite right after an upgrade:
- Starting from a source checkout fails with
client bundles not found; run \pnpm run build` before launch— the new client packages ship unbuilt: runpnpm run buildin the harness checkout, then startdsh web` again. - The plugin's UI is gone (no translated Think row, no Think Translation section in Settings) — restart
dsh web; refreshing the page alone is sometimes not enough. - The local model list is empty — the
ollamaservice is not serving that model directory: checkollama list(orGET /api/tags) and theOLLAMA_MODELSthe running service actually uses. When the model files live on another drive, a directory junction can point the service's default directory at them.
Nothing to configure on the plugin side: it declares no ordering dependency on DSH internals (it binds only to the slots service, plus an optional @deepseek-ai/dsh-client-ui-primitives), so it runs on both older DSH (≤ 0.1.1-rc) and the current line (≥ 0.1.2-alpha.1, 0.1.5-rc.1 included).
🚀 Usage
- Open Settings → Think Translation
- Pick the target language (e.g. 日本語) — the settings panel, thinking rows and task cards all switch to it
- Manage the provider chain — the list below it is the delivery order; drag rows to reorder, and the checkbox is the on/off switch:
- Built-ins: google gtx / bing (free, works out of the box via system proxy) and local Ollama — on first local-model selection a download prompt appears (qwen2.5:7b / 14b or custom); it auto-enables when finished. Built-ins are permanent: uncheck one to stop using it, there is nothing to delete
- DSH providers: endpoints already configured in DSH (
llm-pi-ai.providers) appear automatically as read-only entries (badge "DSH"); their checkbox adds/removes them from the chain. The Import from DSH config button right below the list rescans on click and adds all of them in one go — there is no base URL and no key to retype, because the key is resolved from DSH's own credentials at request time - Custom providers: "Add custom provider" registers any OpenAI-compatible or Anthropic Messages endpoint; the form offers presets for common low-cost models (DeepSeek, OpenAI, Qwen, GLM, Kimi, SiliconFlow, OpenRouter, Anthropic) that fill base URL + model + env name, all still editable; the model lists were checked against the vendors' documentation in September 2026 and are suggestions only — any model id can be typed in. Each row has a test button, an edit form and a × to delete it (a DSH row cannot be deleted — it is managed by the harness)
- A provider can name an environment variable (
apiKeyEnv) instead of carrying the key: presets fill that in, and a DSH row brings its own. The key is resolved per request and never written toconfig.json, and such a row shows anenv:NAMEbadge. The edit form has no env field (the value survives an edit untouched), but emptying a field really removes it — the field is sent as an explicit delete - The former fallback chain option is gone: it was redundant once the chain itself ends with the free providers, and unchecking a provider is how you opt out of it.
fallbackstill exists inconfig.jsonfor anyone who wants it (off by default)
- Send a message that makes the model think, then expand the Think row to read the translation and compare with the original
⚙️ How it works
browser → POST /_xlate/translate (same-origin, no CORS)
→ host provider chain (fail-open, user-ordered):
chain: [provider1, provider2, ...] ← drag-reordered in settings
each provider is one of:
google (gtx via Node CONNECT tunnel / curl through system proxy)
bing (ttranslatev3 via curl)
openai (OpenAI-compatible /chat/completions — Ollama local or any gateway)
anthropic(Anthropic Messages API /v1/messages)
fallback chain (config-only, off by default) tried when the primary chain fails entirely
→ browser-direct fallback
- Provider config lives in
config.json(runtime, gitignored):chain(ordered ids),fallback(enabled + chain, config-only),providers(per-providertype/enabled/baseURL/apiKey/apiKeyEnv/model). Oldpriority-based configs auto-migrate. A provider that declaresapiKeyEnvresolves its key from that environment variable at request time (the literalapiKeystays as the fallback), and no env-resolved key is ever written back toconfig.json. Anullfield in a config patch deletes that field, which is how the UI clears one. - DSH discovery reads the harness
settings.yaml(llm-pi-ai.providers) and.credentials.yaml(refs) on load; discovered providers are markedsource: "dsh", resolved keys stay in memory (never written toconfig.json), and a/_xlate/dsh-scanroute re-reads them on demand. - Host half (
lib/index.js): provider adapters, ordered chain + fallback execution, LRU cache (600), per-provider override for tests,/_xlate/modelslisting,/_xlate/model/pull+pull-statusmodel download management (auto-configures on completion) - Client half (
lib/client.js): 8-language UI, drag-reorderable provider list, add/edit/delete custom providers, per-provider test buttons, sentence/paragraph-batched translation, streaming Think rows, localStorage persistence (settings + translation cache) - Pure display layer: originals remain in the transcript and model context
🛠 Development
- No build step:
lib/client.jsis the browser bundle (source = artifact),lib/index.jsis the host ESM - Client changes apply on page refresh; host changes need a web restart
- The 8-language strings live in the
UI_TEXTdictionary inlib/client.js
📄 License
MIT

umineko987/dsh-search-enhance
anysearch-team/anysearch-dsh
DDDMUC/dsh-free-search
wxkingstar/SpecFusion
A3Boy/dsh-web-tools
yyyyukari/dsh-plugin-workshop
cyijun/dsh-surfing-plugin