前言¶
DSH 的插件體系裏,文本輸出是基本能力,但「聽」仍然是空白。開發者跑本地智能體時,常常需要離開屏幕去確認結果,或者邊做別的事邊聽任務進展。dsh-speak 上游已經做了「把回答念出來」,但它默認只處理最終文本;一旦把中間過程也開起來,模型在工具調用間隙吐出的那些碎片會被一條條切開念,聽感很差。
下面介紹的 m0yun/dsh-speak-plus 就是針對這個問題的增強分支。維護者 M0Yun,屬於 DSH 客戶端類插件,GitHub 倉庫地址見文末。它定位是 dsh-speak 1.8.4 的增強分支,上游的朗讀、隊列、設置頁、WebSocket 狀態同步全部保留,另外補了中間過程合併、審批/提問插隊、新內容換手、Alt + S 停止等行爲。所有新增行爲默認關閉或取保守值,不配置時與上游一致。
這是什麼¶
一句話定位:給 DSH 加上中文語音播報,並且把中間過程按段合併後朗讀,而不是逐句切碎地念。
- 倉庫:https://github.com/M0Yun/dsh-speak-plus
- 目錄頁:https://www.skillhub.cn/plugins/M0Yun/dsh-speak-plus
- 上游:Alan2Z/dsh-speak(1.8.4)
- 許可證:MIT,繼承上游 LICENSE
- 維護者:M0Yun
- 分類:客戶端
它解決的核心問題是:開啓 queueAllMessages 後,每條 assistant 消息立刻獨立入隊朗讀,模型在工具調用之間往往只吐一兩句話,於是聽到的是「收到——」(被切)、「那就你自己重啓。」(被切)、「6 個場景全過。」(被切)這樣的碎片。本分支把連續到達的正文先攢成一段再念,同時規定什麼時候該打斷、什麼時候不該。
核心功能¶
下表按 README 的對照列出,只寫已覈實的能力。
| 能力 | 上游 1.8.4 | 本分支 |
|---|---|---|
| 朗讀最終回覆 | 支持 | 支持 |
| 朗讀中間過程 | 逐條、易被切碎 | 合併成段,按序讀完 |
| 新內容打斷當前朗讀 | 不支持 | 可配(默認等新回合產出內容才換手) |
| 審批 / 提問優先 | 不支持(會被正文頂掉) | 插隊並保護 |
| 停止播報快捷鍵 | 不支持 | Alt + S |
| 配置讀取 | 依賴設置 schema | schema 不可用時回落讀 profile 配置 |
| 隊列 / 狀態同步 / 設置頁 / 手動重播 | 支持 | 全部保留 |
新增的五個能力是相對上游的增量,README 裏逐項給了鍵名和默認值,見下方配置項一節。
安裝與啓用¶
插件以 DSH bundle 形式掛載,在 profile 的 cordis.patch.yml 中配置。下面這段是 README 給出的示例,路徑裏的 <你> 需要替換成實際用戶名:
- id: dsh-speak
name: dsh-speak-plus
config:
queueAllMessages: true
interruptOnNewMessage: true
interimMode: queue
interimMergeMs: 800
interimMaxBacklog: 180
engine: 'C:\Users\<你>\.dsh\profiles\desktop\data\dsh-speak-edge\speak-edge.ps1' # 可選:自定義引擎
rate: 8
這一步在做什麼:用 id: dsh-speak 聲明掛載點與上游保持一致,用 name: dsh-speak-plus 指向本分支;config 裏的鍵決定朗讀行爲,engine 是可選的自定義引擎腳本路徑。
平臺層面,Windows 用系統 SAPI 嗓音(裝了 NaturalVoiceSAPIAdapter 可用自然音色),macOS 用系統 say。引擎腳本與上游一致(engine/speak.ps1、engine/speak.sh),也可以用 engine 指向自己的腳本。
配置項¶
新增(本分支)¶
| 鍵 | 默認 | 說明 |
|---|---|---|
interruptOnNewMessage |
false |
總開關:打開後啓用本分支的打斷 / 合併邏輯 |
interruptOnNewTurn |
false |
false:提交消息不打斷,等新回合真的產出內容才換手;true:按下發送就掐斷 |
interimMode |
queue |
queue:回合內各段排隊讀完、互不打斷;replace:每段新內容立刻頂掉正在播的 |
interimMergeMs |
800 |
靜默多久把碎片合併成一段,0 = 不合並 |
interimMaxBacklog |
180 |
待播正文最多積壓多少字,超出丟棄最舊的 |
繼承自上游(常用)¶
| 鍵 | 默認 | 說明 |
|---|---|---|
enabled |
true |
總開關,關掉後完全不出聲 |
automaticSpeech |
true |
自動朗讀;手動重播始終可用 |
queueAllMessages |
false |
每條 assistant 消息都入隊(中間過程) |
throttleMs |
1500 |
默認模式的合併延遲 |
engine |
空 | 覆蓋引擎腳本路徑 |
rate / volume |
0 / 50 |
Windows 爲 SAPI 刻度(-10~10) |
maxChars |
安全值 | 超過則只念固定提示語 |
longTextMode / longTextMessage |
message |
超長文本的處理方式 |
announceApprovals / announceQuestions |
true |
審批 / 提問播報 |
announceTurnEnd / announceCommandDone / announceGoalChange / announceToolErrors / announceTodoWrite |
false |
可選事件播報 |
完整列表見上游文檔 docs/UPSTREAM-README.zh-CN.md。
典型用法¶
先看一段可復現的最小配置。只想合併中間過程、不做打斷,保留默認即可:
- id: dsh-speak
name: dsh-speak-plus
config:
queueAllMessages: true
interruptOnNewMessage: true
這一段的意思是:interruptOnNewMessage 打開,啓用合併與打斷邏輯;interruptOnNewMessage 不打開時,所有新增行爲保持上游原樣。
快捷鍵統一爲 Alt + S:立刻停止播報,同時清空待播隊列和還沒播出的緩衝片段。README 特別說明,DSH 核心的「快捷鍵」列表只列核心自己的動作,沒有給插件預留註冊入口,所以這個鍵位由插件自己監聽,不會出現在那個列表裏,輸入框有焦點時同樣生效。
行爲上要明確兩點,做集成或排查時容易踩:
- 回合內中間過程按
interimMergeMs合併成段,段與段排隊,前一段唸完再念下一段;待播積壓超過interimMaxBacklog字時丟棄最舊的。 - 換手規則:你發消息時不掐斷當前朗讀;新回合第一段內容要播時,才掐掉上一輪還在唸的正文;正在唸審批 / 提問時,新正文排隊等待,不搶佔。
另外,某些 DSH 構建裏插件無法加載設置 schema,此時會直接讀本 profile 的 cordis.patch.yml(按修改時間緩存,只取已知鍵),與運行時配置合併,運行時優先。掛載時會打一行 生效配置: … 便於排查。
適用場景與注意¶
適合這幾類人:用 Windows SAPI 或 macOS say 做本地念讀、需要靠聽來確認任務進展的開發者;已經在用上游 dsh-speak、但嫌中間過程被切碎的用戶;以及想給審批和提問加聲音提示的團隊。它不適合需要商業級 TTS 音色、或對播報時延有硬性要求的場景——它調用的是系統自帶引擎。
幾點限制必須寫清楚:
- 插件以當前 DSH 進程的權限運行,安裝前應先檢查源碼與許可證(MIT),確認
cordis.patch.yml的內容符合自己的 profile 約定。 - 設置頁依賴
Configschema;構建失敗時設置頁可能不顯示,此時改 YAML 即可。 - 新回合內容會掐掉其他會話正在播的正文(同一套揚聲器),不區分來源。
- 直接改
node_modules裏的插件文件會在重裝 / 升級時被覆蓋。
按目錄頁信息,該插件分類爲客戶端,屬於社區生態項目。需要強調一點:社區目錄是獨立站點,與 DeepSeek / 幻方無官方從屬關係,這只是聚合展示。
結尾¶
dsh-speak-plus 的價值在於把「中間過程認不清」這個上游遺留問題處理掉了:碎片合併成段、按序讀完,審批和提問插隊保護,Alt + S 一鍵停止,新增行爲默認關閉。對已經在用 dsh-speak 的人來說,改動集中在一個 cordis.patch.yml,風險集中在配置而非代碼。
- 目錄頁:https://www.skillhub.cn/plugins/M0Yun/dsh-speak-plus
- GitHub:https://github.com/M0Yun/dsh-speak-plus