ppy-web/dsh-plugin-xiaomi-mimo-tts
ppy-web/dsh-plugin-xiaomi-mimo-tts为 DSH 提供小米 MiMo、豆包、浏览器本地 TTS 语音朗读;自动播报、自定义音色、UI 音效、桌宠联动、QQBot 联动。
对话结束语音播报(会话名、轮数、结果),回复生成时实时逐句朗读;内置 edge-tts,零第三方依赖。
English | 简体中文
A voice announcement plugin for DSH (DeepSeek Harness). It listens for each session's turn/end event and speaks the session title, round number, and outcome — so you know which conversation finished and whether it encountered an error, without watching the screen.
Session title: Round N ended, with dedicated copy for errors, aborts, truncation, and interruptionsdsh plugin --profile web add dsh-voice-announcer
The edge-tts engine is built into the plugin (zero third-party npm dependencies).
winget install ffmpeg (bundles ffplay)Open Settings → Plugin configuration → Voice announcement in the sidebar. Edits are applied live after saving.
Append the following to ~/.dsh/profiles/<profile>/cordis.patch.yml:
- id: dsh-voice-announcer
config:
enabled: true
engine: edge-tts # edge-tts / sapi
voices: [] # [] = all Chinese voices (default); or a list, e.g. [zh-CN-XiaoxiaoNeural, zh-CN-YunxiNeural]
overlapLive: true # sessions with different voices read aloud simultaneously (default); set false for a single global queue
announceCompleted: true
announceError: true
announceSubagent: false # announce subagent sessions too
announceWait: true # speak when a session waits for you (question / plan review / approval request)
liveRead: true # live-read replies as they stream in (both engines)
liveReadActiveOnly: false # live-read only the currently active session
liveReadMaxQueue: 5 # catch-up jump threshold (pending sentences)
sapiVoice: '' # sapi system voice name, e.g. Microsoft Huihui ('' = system default)
sapiRate: 0 # sapi speech rate, -10 (slowest) ~ +10 (fastest)
sapiVolume: 100 # sapi volume, 0 ~ 100
autoFallbackSapi: true # fall back to local sapi when edge-tts cannot reach Microsoft
| Option | Default | Description |
|---|---|---|
| enabled | true | Master switch |
| engine | edge-tts | Engine. Both engines support live reading; the voice/rate/pitch controls are edge-tts-specific and the sapi* options are sapi-specific |
| voices | [] | Voice pool (edge-tts Chinese voices). New sessions pick one by round-robin index from this pool and keep it. Empty = all 14 Chinese voices (default); one entry = every session uses that single voice |
| rate | +0% | Speech rate (edge-tts), slider -50% ~ +50% |
| pitch | +0Hz | Speech pitch (edge-tts), slider -50Hz ~ +50Hz |
| announceCompleted | true | Announce normal completion |
| announceError | true | Announce errors, aborts, and truncations |
| announceSubagent | false | Announce subagent sessions too |
| announceWait | true | Speak when a session pauses waiting for you: it asks a question, presents a plan for review, or requests approval |
| liveRead | true | Live-read replies sentence by sentence while they stream (edge-tts streams from the network, sapi speaks locally) |
| liveReadActiveOnly | false | Live-read only the currently active session (the browser reports it) |
| overlapLive | true | Overlap live-reading across sessions: on (default) = sessions with different voices can speak simultaneously (same session still serial); off = one session speaks at a time (global queue) |
| liveReadMaxQueue | 5 | Catch-up jump: when the pending queue exceeds this many sentences, drop the stale ones and jump to the latest content |
| sapiVoice | (empty) | sapi system voice name (e.g. Microsoft Huihui). Empty = system default. Use voice_health to list installed voices |
| sapiRate | 0 | sapi speech rate: -10 (slowest) ~ +10 (fastest), 0 = normal |
| sapiVolume | 100 | sapi volume: 0 ~ 100 |
| autoFallbackSapi | true | When edge-tts cannot reach Microsoft (403 / offline), automatically speak through local sapi instead of going silent |
All voices are Chinese (Mandarin / dialects / Cantonese / Taiwanese) — every edge-tts voice can also read English text, so mixed content works.
| Group | Voices |
|---|---|
| Mandarin (zh-CN) | Xiaoxiao · Xiaoyi · Yunxi · Yunyang · Yunjian · Yunxia |
| Dialects (zh-CN) | Xiaobei (Liaoning) · Xiaoni (Shaanxi) |
| Cantonese (zh-HK) | HiuGaai · HiuMaan · WanLung |
| Taiwanese (zh-TW) | HsiaoChen · HsiaoYu · YunJhe |
Per-session assignment: a new session (the first time it is read aloud) is assigned the voice at index
allocationCount % voices.lengthof your checked pool, then keeps it permanently (persisted tovoice-announcer-session-voices.json). Changing the filter only affects future assignments — existing sessions keep their voice, and the modulo keeps new sessions aligned to the new list length.
announceSubagent)announceWait)# Build the host (requires the tsc from a DSH source checkout)
DSH_CHECKOUT=<path-to-dsh-harness> bash scripts/build.sh
# Build the client (web settings card)
npx tsdown
speech.platform.bing.com host in many regions with HTTP 403). Synthesis now uses the new api.msedgeservices.com host with the Ocp-Apim-Subscription-Key parameter, keeping the legacy host as a fallback. Added automatic sapi fallback on any edge-tts failure (403 / network / missing ffplay) so announcements never go silent. sapi now supports live reading (previously edge-tts only), using a persistent local process to avoid per-sentence PowerShell startup. New settings: sapiVoice, sapiRate, sapiVolume, autoFallbackSapi.sessionProjections.snapshot(), which synchronously folds the entire event log of a huge session (millions of events × every registered projection key) and can freeze the DSH web server for seconds to minutes. Titles are now read with a lightweight reverse scan for the latest session/title event.BSD-3-Clause