zfu691531-hash
dsh-realtime-voice
Lightweight realtime ASR → DeepSeek Harness → TTS community plugin.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 15, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-realtime-voice
DeepSeek Harness 的轻量实时语音插件。不包含 Docker、Python或本地模型。千问线路是确定性的三段式管线:浏览器采集 PCM,Harness Host 以同源 WebSocket 代理专用 ASR/TTS;空闲时完整语句经原生输入框自动交给当前 Harness 会话,忙时的新语音留在输入框等待用户发送或清空,语音厂商没有独立回答的机会。

能力
- 国内线路:
qwen3-asr-flash-realtime → DeepSeek Harness → qwen3-tts-flash-realtime(阿里云百炼,北京/新加坡)。 - 全球线路:
gpt-realtime-2.1(OpenAI Realtime)。 - 千问使用两个独立语音模型:ASR 只转写,TTS 只播报;不再使用 Omni Realtime 作为对话模型。
- ASR final 统一经过原生输入框:空闲且输入框为空时,在续说窗口结束后自动调用原生发送;Harness 推理或播报期间、以及输入框已有待处理文字时,只追加草稿等待用户发送或清空。推理、记忆、联网、插件与工具调度全部由 Harness 完成。
- VAD 默认
threshold=0.85、尾静音700ms,并关闭浏览器自动增益以优先近讲。ASR final 先进入候选断句,再等待1200ms的续说窗口;从停顿开始约1.9s才提交 Harness,期间继续说话仍属于同一轮。 - 严格的
TurnCoordinator为每轮分配唯一 ID,并串行处理 ASR 状态事件;旧轮的迟到回调不能再启动 Harness、覆盖新轮或播放过期语音。 - Harness 执行工具期间,普通背景转写不会再取消当前任务;只有明确说“停止 / 取消 / 算了”才会中止。
- Harness 正在推理或 TTS 正在播报时,新语音只追加到原生输入框;播报结束后不会跳过这些文字。输入框有待处理内容时,后续识别继续合并,直到用户发送或清空;输入框为空才恢复下一轮自动提交。
- 语音模式开启期间,插件旁路观察用户手动提交的原生 Harness turn,流式提取口语摘要并交给 TTS;不需要插件再次提交相同消息。
- TTS 使用 24kHz PCM 流式播放。播报期间麦克风音频先留在浏览器本地,不会直接污染云端 ASR;经过播放预热且检测到至少
500ms持续近讲后,才暂停播放器并把带预卷的候选音频交给 ASR。 - 候选插话经过文本有效性与播报回声相似度复核;误触发会恢复原播报,确认插话才停止 TTS。插话文字只进入原生输入框,等待用户发送或清空,不会自动抢开第二个 Harness 任务。
- TTS 播放结束后保留
400ms防回声窗口,清理残留 ASR 缓冲后才重新进入监听。 - 实时语音轮次要求 Harness 把 1–2 句自然口语结论放在第一段,空行后再写详细结果;插件在第一段每个完整句子生成时立即提交 TTS,不等待详细正文或
turn/end。聊天界面不再显示任何voice-summary/HTML 边界,TTS 只消费text-delta,绝不读取reasoning-delta、工具过程或后续详情。 - 实际等待超过默认
800ms且仍没有正文时,本地接场器最多播放一句不含结论的自然承接;快回答自动取消接场。接场和结果共用同一 TTS 单写者队列,不创建第二个 Agent、不写 Harness 历史;Harness 轨迹出现 LLM retry 时立即作废旧播报。 - 同一会话只允许一个语音委派。排队任务使用定向删除,运行中任务才会取消当前 turn,避免误伤原有工作。
- API Key 只由 Host 的凭据服务按请求读取,不写入浏览器、
localStorage、包文件或日志。
安装
推荐直接从带版本标签的 GitHub 仓库安装:
dsh plugin --profile web add github:zfu691531-hash/dsh-realtime-voice#v0.9.0
仓库提交预构建 lib/,因此这条命令不需要本机 TypeScript、源码 checkout 或 pnpm allowBuilds。重启 DeepSeek Harness 后,在“设置 → 插件”展开“实时语音(千问 / GPT)”。
也可以下载同版本 GitHub Release 中的预构建 tarball 后执行:
dsh plugin --profile web add ./dsh-realtime-voice-0.9.0.tgz
也可以从源码自行验收并打包:
npm install --ignore-scripts
npm run dev:link-dsh
npm run check
npm pack
源码构建需要本机已安装 DeepSeek Harness;dev:link-dsh 只把类型检查和打包所需的 Harness 包链接进当前开发目录。普通用户安装 Release tarball 不需要执行这一步。
卸载
dsh plugin --profile web remove dsh-realtime-voice
重启 Harness 后插件的 Host 路由、客户端槽位和语音上下文会随 Cordis disposer 一并移除。凭据由 Harness 统一管理,卸载插件不会擅自删除用户凭据。
Doctor
先运行 dsh plugin --profile web list 确认安装版本,再在 Harness 已打开的浏览器页面执行:
await fetch('/dsh-realtime-voice/status').then(response => response.json())
完整示例配置与排障见 docs/EXAMPLE_CONFIG.md。
DSH 插件规范
- 仓库根目录即独立插件包,不依赖另一个社区仓库。
package.json通过dsh.bundle.patch声明组合包,patch 指向本包的 Host 与 Client 入口。cordis.patch.yml只贡献本插件自己的服务行,不覆盖用户 profile 的其他插件。- GitHub 标签固定版本,预构建产物随源码提交;安装不会运行第三方构建脚本。
- API Key 由 Harness credentials 服务解析,浏览器端只拿到临时语音连接,不持久化密钥。
配置
在 Harness 的凭据配置中提供所选线路的引用:
- 千问:
DASHSCOPE_API_KEY,并在插件设置里填写同区域的百炼 Workspace ID。 - OpenAI:
OPENAI_API_KEY。
插件设置只保存 provider、Workspace ID、ASR/TTS 模型、TTS 音色、VAD 参数和播报风格;不保存 Key。千问默认使用北京区、qwen3-asr-flash-realtime、qwen3-tts-flash-realtime 和 Chelsie;OpenAI 默认使用 gpt-realtime-2.1 和 marin。Tina 是 Omni 专属音色,独立 TTS 不支持;Chelsie 是专用 TTS 中更接近其软糯亲昵风格的选择。
桌面版 rc.5 的麦克风限制
当前 DeepSeek Harness Desktop rc.5 的 Electron 壳会拒绝 renderer 的麦克风权限。插件在桌面窗口点击话筒时会用默认外部浏览器打开同一个 loopback Harness 页面;在 Chrome/Edge 中授权麦克风后即可使用。Host、会话和插件仍是同一套 Harness 实例,不会接入 Sophie 或另起 Agent 服务。
未来桌面壳开放麦克风权限后,这个插件无需音频架构变更即可直接在内嵌窗口工作。
开发与验收
npm install --ignore-scripts
npm run dev:link-dsh
npm run check
npm run check 包含类型检查、无真实 Key 的 Host/委派/双 provider 协议测试、生产构建和浏览器 bundle 纯度检查。
详细 rc.5 契约见 docs/HARNESS_RC5_CONTRACT.md。
面向 DSH 组合架构的职责、事件契约、权限边界、依赖和风险清单见 docs/ARCHITECTURE_PACKAGE.md。安全报告流程见 SECURITY.md。
自适应“对话接场器”的实现与后续进度话术路线见 docs/ADAPTIVE_FLOOR_MANAGER.md。当前版本已实现第一阶段的实际延迟竞速、单次承接和轨迹重试失效保护。
安全边界
- HTTP 与 WebSocket 路由仅接受 loopback、同源请求;百炼 Key 只在 Host 到上游的握手请求中出现。
- Qwen Workspace ID 和区域使用 allowlist 校验,不能注入任意上游域名。
- 上游错误最多返回截断后的非敏感文本,不返回凭据。
- OpenAI API 的可用地区和账户使用须遵守其服务条款;插件不实现或配置网络规避功能。