DSH Web 的双向语音:用统一输入框听写、用朗读按钮与自动朗读听回复,任意设备可用。需 DSH 0.1.7+、Node 22+、Python 3(含 numpy 与 requests)、TTS 模型与麦克风。
安装
# npm 包(预构建)
dsh plugin --profile web add @martindye/dsh-voice
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:martindye/dsh-voice
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
该插件的 README 只有英文版本。
Martin's self-contained two-way voice plugin for the DSH web app: you speak, the agent replies out loud, and the microphone keeps listening. Works on any device the web app runs on (iPhone or PC).
A standalone fork of @deepseek-ai/dsh-experimental-client-ui-voice-input
(0.1.7-rc.2, from the deepseek-harness checkout), renamed @martindye/dsh-voice
and grown into the single voice plugin: composer in, speaker buttons and
auto-read out. The retired dsh-voice-chat kit and the old dsh-voice-output
plugin are both superseded by this repository.
What it does
Input (the composer):
- The unified 34 px blue composer button: voice entry on an empty draft, send arrow while typing, stop square while the agent runs or the system speaks, cross while a voice turn is active.
- Continuous listening: after a reply ends the microphone reopens on its own; an auto-open that draws no words is quietly re-offered a few times.
- The spoken pause command ("hold the mic", "pause the mic", "stop listening") parks the listening loop without sending.
- In-call mute: while a voice turn is active the dictate button becomes a mute/unmute toggle (white on red while muted); muted audio never reaches the recognizer and the voice-activity clocks freeze.
Output (the speaker):
- A speaker button on every finalized assistant message (speak / stop).
- Auto-read: fresh replies (younger than 2 minutes) are read aloud on a
device that (1) has the auto-read toggle on and (2) has used the voice
composer on that device (
dsh.voice-chat.v1). No PC-side bridge is involved — each device reads what it is shown. - A per-device auto-read toggle in the session header corner (green dot when the device is voice-armed), persisted per browser.
- Text is resolved from the session log on the host and prepared for speech (code, links and markdown stripped) before synthesis.
Layout
src/— plugin source.src/index.ts(host entry),src/tts-host.ts(TTS supervision + speech preparation, host half),src/client/(browser half: composer, speaker button, header toggle, playback).tts/— the plugin's own TTS HTTP server (server.py) and its engines (qwen3.pyGPU voice,pocket.pyCPU fallback).bin/tts-server.exe— the bundled qwentts.cpp server for the qwen3 engine (adopts a compatible resident server on 127.0.0.1:8095 when present).ref_voices/— the reference voices the qwen3 engine clones from (pocket,warm-brit). Both are synthetic takes (Pocket TTS and a VoiceDesign take respectively) — no real person's voice is bundled; seeTHIRD-PARTY.mdfor the full attribution list.lib/— build output (lib/index.jsnode half,lib/client.jsbrowser bundle). Gitignored; rebuild withpnpm bundle.tests/— vitest client tests (jsdom): the composer audio pipeline, the waveform, and the conversation simulation with its trace files.
Building
pnpm install
pnpm bundle # lib/index.js + lib/client.js
pnpm test # vitest
The client bundle is a CJS closure factory registered with the host's module loader under the package name; platform modules (react, primitives, slots, gateway) stay externals, everything else inlines. CSS modules are compiled with lightningcss and injected as self-managed style tags.
Runtime requirements (the machine running DSH)
- Python 3 on PATH (override with
DSH_VOICE_PYTHON) withnumpyandrequests; addpocket-ttsfor the CPU fallback engine. The server is spawned on demand at127.0.0.1:8189(override the port withDSH_VOICE_TTS_PORT) and supervised by the plugin host. - qwen3 (GPU) models under
~/.dsh/voice-chat/models/qwen3(talker + tokenizer GGUFs); the engine choice is the shared consent file~/.dsh/voice-chat/consent.json("engine": "qwen3" | "pocket"), default qwen3 when its models are present. - Host log:
~/.dsh/logs/voice-tts.log.
With Pocket selected, only the CPU engine is warmed when the TTS server starts.
A failed Pocket request does not fall back to a GPU engine. Selecting qwen3
still enables the GPU engine and retains its CPU fallback. The host passes the
selected registry name through VOICE_CHAT_PRELOAD_ENGINE; a standalone server
or an older host defaults its warm-up to Pocket. GPU requests remain available
on demand. Run python -m unittest discover -s tests -p 'test_tts_server.py'
for the model-free startup and fallback checks.
Installing
From npm (the published package ships prebuilt lib/ — no build step, no
build-script permission needed):
dsh plugin --profile <profile> add @martindye/dsh-voice
for example dsh plugin --profile web add @martindye/dsh-voice for the web
app. Then restart the web host (or start it) and open the app: the unified
voice button appears in the composer, and a speaker button on every finalized
message.
Requirements: DSH 0.1.7+ (web app), Node 22+ on the host, and Python 3 with
the TTS engine dependencies for the spoken replies (see tts/); the browser
needs microphone permission for dictation, and the speech-to-text models are
fetched on first use under the DSH home.
How the bundle works
The package declares a dsh.bundle with cordis.patch.yml. Adding the
bundle to a profile's bundles list (the web profile does this in its
package.json) inserts:
ui-voice— this plugin,- the speech-to-text stack (
speech-to-textwithsensevoice-localas default provider and languageen,speech-to-text-sensevoicewithdataRootat the DSH homespeech-to-text/sensevoice, andapi-speech-to-text),
and disables the upstream ui-voice-input row. The three @deepseek-ai/ dsh-experimental-*speech-to-text* packages must be installed in the same
profile (the web profile links them from the deepseek-harness checkout).
lib/ is not committed to git (it is included in the npm tarball); run
pnpm bundle after pulling when working from a checkout. A page refresh
picks up the client; the host half needs a web-host restart.
Retired neighbours
DSH_TESTS/dsh-voice-chat— the read-only kit (STT + TTS) that this plugin replaces wholesale. Keep it as reference only.DSH_TESTS/dsh-voice-output— the old output-only plugin; superseded by the speaker buttons in this plugin.- The TTSTT coding-voice bridge (retired 10/06) is deliberately not referenced anywhere: auto-read no longer depends on any PC-side process.
链接
同类插件
PolinniZhong/dsh-omi-voice★ 76
DeepSeek Harness 对话内朗读:点一下即可朗读、暂停、继续 AI 回复,豆包 TTS 自然音色(BYOK),只读最终回答并过滤代码、表格与图形,本地引擎,插件零 Key。
beiyege-01/dsh-voice-ai-girlfriend-plugin★ 40
Web UI 语音 AI 女友:FunASR 麦克风语音输入、Qwen3-TTS 语音回复、数字人动画窗、QQ 双向聊天(文本/语音/图片推送,经 NapCat)。
PensiveFei/dsh-voice-scribe★ 35
面向 Web UI 的语音输入插件:点按 Alt(或 Alt+空格)开始/停止听写,支持浏览器内置 Web Speech(零配置)或 OpenAI 兼容云端 ASR,可选经 DSH 已配置模型润色,带设置页。
1624318455/dsh-plugin-tts★ 29
用免费 Edge TTS 或你自己的 RVC 音色朗读 AI 回复:消息朗读与自动朗读、长文自适应分块渐进播放(无缝衔接)、音色包仓库一键安装、便携 RVC 运行时。
ppy-web/dsh-plugin-xiaomi-mimo-tts★ 28
为 DSH 提供小米 MiMo、豆包和浏览器本地语音朗读,支持自动播报、自定义音色与可选 UI 音效。
WizisCool/dsh-ears★ 24
面向 DeepSeek Harness (dsh) 的语音输入插件:输入框的麦克风按钮把语音转成草稿文本,支持多种语音识别后端,可选经 dsh 自有 LLM 路由润色,并带原生设置页。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。