dsh-speak-plus 🔊
让 DeepSeek Harness 把回答念出来——而且中间过程也念,不是只念最后一句。
本仓库是 dsh-speak
1.8.4的增强分支(MIT 许可)。 上游的朗读、队列、设置页、WebSocket 状态同步全部保留,另外补了五项能力。 所有新增行为默认关闭或取保守值,不配置时与上游一致。
英文文档见 README.en.md;上游完整中文文档见 docs/UPSTREAM-README.zh-CN.md。
为什么做这个分支
上游开启 queueAllMessages 后,每条 assistant 消息都会立刻独立入队朗读。但模型在工具调用之间
往往只吐一两句话,于是听感是这样的:
"收到——"(被切)/ "那就你自己重启。"(被切)/ "6 个场景全过。"(被切)/ …
本分支把连续到达的正文先攒成一段再念,并且规定了「什么时候该打断、什么时候不该」,让中间过程 听得清、也不拖得太久。
功能
| 能力 | 上游 1.8.4 | 本分支 |
|---|---|---|
| 朗读最终回复 | ✅ | ✅ |
| 朗读中间过程 | 逐条、易被切碎 | 合并成段,按序读完 |
| 新内容打断当前朗读 | ❌ | ✅ 可配(默认等新回合出内容才换手) |
| 审批 / 提问优先 | ❌(会被正文顶掉) | ✅ 插队并保护 |
| 停止播报快捷键 | ❌ | ✅ Alt + S |
| 配置读取 | 依赖设置 schema | ✅ schema 不可用时回落读 profile 配置 |
| 队列 / 状态同步 / 设置页 / 手动重播 | ✅ | ✅ 全部保留 |
安装
插件以 DSH bundle 形式挂载,在 profile 的 cordis.patch.yml 中配置:
- 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
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 |
可选事件播报 |
完整列表见上游文档。
快捷键
Alt + S —— 立刻停止播报,同时清空待播队列和还没播出的缓冲片段。
说明:DSH 核心的「快捷键」列表只列核心自己的动作,没有给插件预留注册入口,所以这个键位由插件 自己监听,不会出现在那个列表里。输入框有焦点时同样生效。
行为说明
回合内的中间过程(interimMode: queue):
- 片段按
interimMergeMs合并成一段,避免一句话被拆成几次播报 - 段与段之间排队,前一段念完再念下一段,不互相打断
- 待播积压超过
interimMaxBacklog字时丢弃最旧的,保证不会越听越落后
换手规则:
- 你发消息时不掐断当前朗读
- 新回合第一段内容要播时,才掐掉上一轮还在念的正文
- 正在念审批 / 提问时,新正文排队等待,不抢占
配置兜底:某些 DSH 构建里插件无法加载设置 schema,此时会直接读本 profile 的
cordis.patch.yml(按修改时间缓存,只取已知键),与运行时配置合并,运行时优先。
挂载时会打一行 生效配置: … 便于排查。
已知限制
- 设置页依赖
Configschema;构建失败时设置页可能不显示,此时改 YAML 即可 - 新回合内容会掐掉其他会话正在播的正文(同一套扬声器),不区分来源
- 直接改
node_modules里的插件文件会在重装 / 升级时被覆盖
目录
adapters/dsh/speech-hook.js 宿主端:事件 → 队列 → 引擎
client/client.js 浏览器端:设置页、消息按钮、Alt+S
engine/ 朗读引擎(SAPI / macOS say)
docs/LOCAL-CHANGES.zh-CN.md 本分支相对上游的改动清单
docs/UPSTREAM-README.zh-CN.md 上游完整文档
许可
MIT,继承上游 LICENSE,上游版权归 Alan2Z 所有。
No comments yet. Be the first to write one.