@goodandready/dsh-voice 0.9.29 → 0.9.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +252 -249
- package/README.ru.md +251 -248
- package/README.zh.md +179 -176
- package/lib/client.js +346 -42
- package/lib/host-routes.js +188 -188
- package/lib/local-daemon.js +2 -2
- package/lib/schema.js +161 -160
- package/lib/updater.js +18 -3
- package/package.json +72 -72
package/README.zh.md
CHANGED
|
@@ -1,176 +1,179 @@
|
|
|
1
|
-
# 📦 @goodandready/dsh-voice
|
|
2
|
-
|
|
3
|
-
<div align="center">
|
|
4
|
-
|
|
5
|
-
<h3>DeepSeek Harness 零延迟流式语音听写与多服务商对讲输入插件</h3>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<a href="https://www.npmjs.com/package/@goodandready/dsh-voice"><img src="https://img.shields.io/npm/v/@goodandready/dsh-voice.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
9
|
-
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-10b981.svg?style=for-the-badge&color=10b981&labelColor=064e3b" alt="license"></a>
|
|
10
|
-
<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/DSH-Plugin-8b5cf6.svg?style=for-the-badge&labelColor=2e1065" alt="DSH Plugin"></a>
|
|
11
|
-
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-20%2B-f59e0b.svg?style=for-the-badge&labelColor=451a03" alt="Node version"></a>
|
|
12
|
-
</p>
|
|
13
|
-
|
|
14
|
-
<p align="center">
|
|
15
|
-
<a href="https://goodandready.app/"><img src="https://img.shields.io/badge/作者全部项目-goodandready.app-ff4500.svg?style=for-the-badge&logo=rocket&logoColor=white&labelColor=1a1a2e" alt="作者全部项目"></a>
|
|
16
|
-
</p>
|
|
17
|
-
|
|
18
|
-
<p align="center">
|
|
19
|
-
<a href="README.md"><b>🇬🇧 English</b></a> •
|
|
20
|
-
<a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
|
|
21
|
-
<a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
|
|
22
|
-
</p>
|
|
23
|
-
|
|
24
|
-
<table align="center">
|
|
25
|
-
<tr>
|
|
26
|
-
<td align="center">
|
|
27
|
-
⭐ <strong>如果您喜欢这个插件,请在 GitHub 上为它点亮 Star</strong> — 这能让我知道插件对您有用,并鼓励我继续开发和维护它。
|
|
28
|
-
<br><br>
|
|
29
|
-
🐛 <strong>如果您发现 Bug 或希望增加功能</strong>,请使用任意语言在 GitHub 上提交 Issue — 我会评估您的建议,并在后续版本中实现有价值的改进。
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
|
114
|
-
|
|
115
|
-
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
|
125
|
-
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
###
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
* `
|
|
143
|
-
* `
|
|
144
|
-
* `GET
|
|
145
|
-
* `
|
|
146
|
-
* `
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
1
|
+
# 📦 @goodandready/dsh-voice
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
<h3>DeepSeek Harness 零延迟流式语音听写与多服务商对讲输入插件</h3>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@goodandready/dsh-voice"><img src="https://img.shields.io/npm/v/@goodandready/dsh-voice.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-10b981.svg?style=for-the-badge&color=10b981&labelColor=064e3b" alt="license"></a>
|
|
10
|
+
<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/DSH-Plugin-8b5cf6.svg?style=for-the-badge&labelColor=2e1065" alt="DSH Plugin"></a>
|
|
11
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-20%2B-f59e0b.svg?style=for-the-badge&labelColor=451a03" alt="Node version"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://goodandready.app/"><img src="https://img.shields.io/badge/作者全部项目-goodandready.app-ff4500.svg?style=for-the-badge&logo=rocket&logoColor=white&labelColor=1a1a2e" alt="作者全部项目"></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="README.md"><b>🇬🇧 English</b></a> •
|
|
20
|
+
<a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
|
|
21
|
+
<a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<table align="center">
|
|
25
|
+
<tr>
|
|
26
|
+
<td align="center">
|
|
27
|
+
⭐ <strong>如果您喜欢这个插件,请在 GitHub 上为它点亮 Star</strong> — 这能让我知道插件对您有用,并鼓励我继续开发和维护它。
|
|
28
|
+
<br><br>
|
|
29
|
+
🐛 <strong>如果您发现 Bug 或希望增加功能</strong>,请使用任意语言在 GitHub 上提交 Issue — 我会评估您的建议,并在后续版本中实现有价值的改进。
|
|
30
|
+
</td>
|
|
31
|
+
</tr>
|
|
32
|
+
</table>
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 运行要求
|
|
39
|
+
### 浏览器麦克风与安全上下文 (Secure Context)\n现代浏览器要求在**安全上下文**(`https://` 或 `http://localhost` / `http://127.0.0.1`)下才允许调用麦克风接口(`navigator.mediaDevices.getUserMedia`)。当通过局域网以普通 HTTP 访问 DSH(如使用 `dsh-lanmode` 访问 `http://192.168.1.x:3080`)时,浏览器默认会阻止录音。在局域网环境下,请配置 HTTPS 反向代理,或在浏览器中启用标志(`chrome://flags/#unsafely-treat-insecure-origin-as-secure`)。\n
|
|
40
|
+
|
|
41
|
+
## ⚡ 插件概览
|
|
42
|
+
|
|
43
|
+
**`dsh-voice`** 为 **DeepSeek Harness** Web 界面带来极速语音交互体验。无论是按自然停顿切分的流式听写,还是带撤回保护的语音消息以及键盘/鼠标 Push-to-Talk 对讲,`dsh-voice` 凭借**多服务商自动故障转移备用链**确保您的录音万无一失。
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
graph LR
|
|
47
|
+
subgraph Client [前端 Web 浏览器]
|
|
48
|
+
Mic[🎙️ 听写麦克风] -->|VAD 停顿切分| Stream[音频数据切片]
|
|
49
|
+
Wave[🌊 语音消息] -->|长按 / 松开| PTT[Push-to-Talk]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
subgraph Host [DSH 服务端 Host]
|
|
53
|
+
Stream --> FFMPEG[ffmpeg 16kHz 转码器]
|
|
54
|
+
PTT --> FFMPEG
|
|
55
|
+
FFMPEG --> Chain{备用链轮询}
|
|
56
|
+
|
|
57
|
+
Chain -->|首选优先级| P1[Deepgram / Nova-2]
|
|
58
|
+
Chain -.->|遭遇限流 / 429| P2[Groq / Whisper Turbo]
|
|
59
|
+
Chain -.->|异常故障时| P3[本地 whisper.cpp / 离线]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
subgraph Output [输出目标]
|
|
63
|
+
P1 --> Composer[💬 聊天输入框]
|
|
64
|
+
P2 --> Composer
|
|
65
|
+
P3 --> Composer
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
style Client fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
|
|
69
|
+
style Host fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
|
|
70
|
+
style Output fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## ✨ 核心亮点
|
|
76
|
+
|
|
77
|
+
* 🎙️ **VAD 智能流式听写**:说话停顿自动切句(`vadSilenceMs`,默认 700ms),文字实时追加至输入框。
|
|
78
|
+
* 🌊 **带撤回窗口的语音消息**:录制完整语音,转写后在倒计时(`autoSendMs`,默认 4000ms)结束后自动发送。
|
|
79
|
+
* 🎮 **沉浸式 Push-to-Talk 对讲**:
|
|
80
|
+
* **鼠标操作**:按住声波按钮开始录音,松开发送,拖离按钮取消。
|
|
81
|
+
* **键盘操作**:按住 <kbd>Ctrl</kbd> 无需鼠标即刻说话,按 <kbd>Esc</kbd> 放弃本次录音。
|
|
82
|
+
* ⚡ **浏览器实时同声字幕 (`browser`)**:Web Speech API 实时语音识别与浮动同声字幕(注意:Chrome 等标准浏览器通常将音频发送至服务商云端解析;若需 100% 本地离线隐私保护,请使用本地 `whisper` 或 `sensevoice`)。
|
|
83
|
+
* 🛡️ **多服务商自动容灾切换**:首选 API 额度耗尽或遭遇 429 限流时,毫秒级顺位切换备用引擎。
|
|
84
|
+
* 🧠 **上下文术语注入 (Context Glossary)**:自动从输入草稿中提取代码变量名与专业术语,引导 STT 模型精准转写专业词汇。
|
|
85
|
+
* 🎵 **内嵌音频播放器**:在输入框与录音浮层中随时试听和回放刚刚录制的原始音频片段。
|
|
86
|
+
* 🔇 **硬件降噪切换开关**:在插件设置中自由开关浏览器级降噪、回声消除与自动增益控制。
|
|
87
|
+
* 📊 **服务商延迟与健康监控看板**:在设置界面实时掌握每个语音引擎的延迟(毫秒)、成功率与调用状态。
|
|
88
|
+
* 🔒 **API 密钥安全隔离**:密钥由服务端 `ctx.credentials` 统一解析,绝不向浏览器前端泄漏。
|
|
89
|
+
* 🖥️ **本地 whisper.cpp 服务端直连**:自动管理 `whisper-server` 进程,结合 `ffmpeg` 实现实时音频转码。
|
|
90
|
+
* ⚡ **SenseVoice-ONNX / Sherpa-ONNX** *(0.8.11)*:超快速(~50–100ms)非自回归本地语音识别引擎,自动清除情绪/事件标签。支持 Sherpa-ONNX HTTP 和 OpenAI 兼容端点。
|
|
91
|
+
* 🌊 **Liquid Wave 与 Dynamic Orb 动态可视化** *(0.8.12)*:录音面板内的生动波形动态可视化,实时响应麦克风音量。可选平滑流动波浪、发光脉冲球体、经典频条或关闭。
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 📝 0.8.19 更新说明
|
|
96
|
+
|
|
97
|
+
v0.8.18 质量审查后的修复批次(Gitea #79–#87,PR #88):
|
|
98
|
+
|
|
99
|
+
- 设置占位提示在**渲染时**通过 locale 解析,不再冻结为 i18n key(#79)
|
|
100
|
+
- `whisperModel` / `sensevoiceModel` 使用模型路径提示(#82)
|
|
101
|
+
- 可视化器改用 DSH 主题 token,不再硬编码颜色(#80)
|
|
102
|
+
- 样式标签使用 `data-dsh-plugin="dsh-voice"`,避免邻居插件 HMR 清理误删(#81)
|
|
103
|
+
- 源码语言统一为英文;界面不再内置完整 `ru` 词典(#85)
|
|
104
|
+
- 浏览器端源码拆分为 `lib/client-src/*.js`,由 `npm run build:client` 构建(#87)
|
|
105
|
+
|
|
106
|
+
> [!IMPORTANT]
|
|
107
|
+
> **v0.8.19 语言说明:** 未安装 translation 插件时,Web UI 保持英文。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 🎮 四种语音输入方式
|
|
112
|
+
|
|
113
|
+
| 交互模式 | 触发手势 | 行为效果 |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| **流式听写** | 单击 <kbd>🎙️ 麦克风</kbd> | 按停顿切分语音 (`vadSilenceMs`),文本实时录入输入框 |
|
|
116
|
+
| **语音消息** | 单击 <kbd>🌊 声波</kbd> | 持续录音至手动停止,转写后进入撤回倒计时 (`autoSendMs`) |
|
|
117
|
+
| **鼠标对讲** | 长按 <kbd>🌊 声波</kbd> | 按住录音;松开发送,光标拖出按钮区域取消 |
|
|
118
|
+
| **键盘对讲** | 按住 <kbd>Ctrl</kbd> | 免鼠标快捷 Push-to-Talk 录音;按 <kbd>Esc</kbd> 取消 |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 🛠️ 服务商矩阵
|
|
123
|
+
|
|
124
|
+
| 服务商标识 | 对应引擎 | 默认模型 | 环境变量凭据 | 特性说明 |
|
|
125
|
+
|---|---|---|---|---|
|
|
126
|
+
| `browser` | Web Speech API | 浏览器原生引擎 | *无需密钥* | 零延迟同声字幕输出(依赖浏览器厂商云端解析;非离线本地) |
|
|
127
|
+
| `deepgram` | Deepgram API | `nova-2` | `DEEPGRAM_API_KEY` | 极速高精云端转写 |
|
|
128
|
+
| `groq` | Groq Whisper | `whisper-large-v3-turbo` | `GROQ_API_KEY` | 毫秒级极速推理 |
|
|
129
|
+
| `hf` | HuggingFace Inference | `openai/whisper-large-v3` | `HF_TOKEN` | 经典高精度开源模型 |
|
|
130
|
+
| `local-whisper` | 本地 whisper.cpp | 启动参数指定 | *无需密钥* | 100% 离线私密运行 |
|
|
131
|
+
| `sensevoice` | SenseVoice-ONNX / Sherpa-ONNX | `SenseVoiceSmall` | *无需密钥* | 超快速(~50ms)本地非自回归 STT |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🤖 智能体工具与 HTTP 端点
|
|
136
|
+
|
|
137
|
+
### 智能体工具 (`transcribe_audio`)
|
|
138
|
+
在 `ctx.tools` 中注册 `transcribe_audio(file_path, language?)`,允许智能体直接读取和转写本地音频文件。包含严格的目录边界检查(`allowedAudioDirs`、`~/.dsh`、`tmpdir`、`cwd`)、符号链接越界防护以及音频特征码(magic bytes)校验。
|
|
139
|
+
|
|
140
|
+
### 内部 HTTP 端点
|
|
141
|
+
|
|
142
|
+
* `POST /dsh-voice/transcribe` — 音频转写:`{ dataBase64, mimeType, mode }` → `{ ok, text, provider, tookMs }`
|
|
143
|
+
* `POST /dsh-voice/polish` — 文本模型润色:`{ text }` → `{ ok, text }`
|
|
144
|
+
* `GET /dsh-voice/status` — 查询后端状态、服务商健康度、SenseVoice 及 effectiveSensevoiceProvider
|
|
145
|
+
* `GET /dsh-voice/config` — 获取插件运行时配置快照
|
|
146
|
+
* `PUT /dsh-voice/config` — 跨网络安全持久化更新插件配置
|
|
147
|
+
* `GET/POST /dsh-voice/sensevoice-installer` — SenseVoice 一键模型安装状态与触发接口(受 `isTrustedCaller` 保护,绝对路径脱敏)
|
|
148
|
+
* `POST /api/dsh-voice/update` — 触发插件自动更新至 npm 最新兼容版本(受本地调用与锁校验保护)
|
|
149
|
+
* `GET /api/dsh-voice/update` — 获取更新检查状态与版本信息
|
|
150
|
+
|
|
151
|
+
### 🔒 配置文件锁与受控操作员恢复机制
|
|
152
|
+
在安装或更新插件时,DeepSeek Harness 使用 `<profile-dir>/package.json.lock`(例如 `~/.dsh/profiles/<profile>/package.json.lock`)协调并发操作。
|
|
153
|
+
* **规范竞争者策略**: 竞争者进程绝不删除现有的锁定文件。禁止竞争者自动清理残留锁,以杜绝 TOCTOU 竞态条件并避免破坏配置文件状态。
|
|
154
|
+
* **诊断信息**: 若存在 lock 文件,更新请求将返回 `409 Conflict` 并附带诊断说明:
|
|
155
|
+
- 若由活跃进程持有,则报告其 PID。
|
|
156
|
+
- 若遭遇文件系统访问错误(`EACCES`、`EIO`),则安全失败(fail-closed)并保留错误码。文件系统错误需要检查磁盘健康度、目录权限或挂载选项——**请勿**因 `EACCES`/`EIO` 错误而删除锁文件。
|
|
157
|
+
* **受控操作员恢复流程**:
|
|
158
|
+
若先前安装进程异常终止(如 OOM 终止或系统断电)留下僵死锁,必须由操作员按以下受控流程进行清理:
|
|
159
|
+
1. **建立独占维护窗口**: 确保目标配置文件当前没有正在运行或计划启动的并发安装任务(CLI 命令 `dsh plugin add`、Web UI 交互或自动更新器)。
|
|
160
|
+
2. **确认静止状态与无活跃属主**: 通过 `pgrep`、`ps`、`fuser` 或 `lsof` 确认目标配置文件目录下确实没有正在执行包操作的活跃进程。仅凭锁文件存在时间较长或 PID 未能解析**不足以**作为删除依据,前提必须是彻底排除其他进程启动的可能。若无法确认静止状态,切勿删除。
|
|
161
|
+
3. **安全删除已确认的孤立锁**: 只有在完全确认锁文件已孤立且处于维护窗口期时,才允许由操作员手动删除该特定锁文件(严禁使用递归或 force 标志):
|
|
162
|
+
```bash
|
|
163
|
+
rm ~/.dsh/profiles/<profile>/package.json.lock
|
|
164
|
+
```
|
|
165
|
+
4. **恢复正常运行**: 重新开启安装通道并重试插件更新。
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 📦 安装指南
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
dsh plugin --profile web add @goodandready/dsh-voice
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 📄 开源协议
|
|
178
|
+
|
|
179
|
+
MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
|