@goodandready/dsh-voice 0.8.9 → 0.8.11
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/LICENSE +1 -1
- package/README.md +137 -181
- package/README.ru.md +172 -0
- package/README.zh.md +116 -0
- package/lib/chain.js +18 -3
- package/lib/client.js +290 -8
- package/lib/index.js +304 -5
- package/lib/providers.js +62 -2
- package/lib/stats.js +72 -0
- package/package.json +2 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,216 +1,172 @@
|
|
|
1
|
-
# dsh-voice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
# 📦 @goodandready/dsh-voice
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
<h3>Zero-Latency Streaming Dictation & Multi-Provider Voice Input for 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/All_Author_Projects-goodandready.app-ff4500.svg?style=for-the-badge&logo=rocket&logoColor=white&labelColor=1a1a2e" alt="All Author Projects"></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
|
+
</div>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ⚡ Overview
|
|
29
|
+
|
|
30
|
+
**`dsh-voice`** brings voice superpowers to the **DeepSeek Harness** Web UI. Whether you need hands-free real-time streaming dictation segmented on natural breath pauses or crisp voice notes with keyboard/mouse Push-to-Talk gestures, `dsh-voice` ensures your audio is never lost thanks to **automatic multi-provider fallback chains**.
|
|
31
|
+
|
|
32
|
+
```mermaid
|
|
33
|
+
graph LR
|
|
34
|
+
subgraph Client [Browser Web UI]
|
|
35
|
+
Mic[🎙️ Dictation Mic] -->|VAD Cut on Pause| Stream[Audio Chunks]
|
|
36
|
+
Wave[🌊 Voice Message] -->|Hold / Release| PTT[Push-to-Talk]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph Host [DSH Host Backend]
|
|
40
|
+
Stream --> FFMPEG[ffmpeg 16kHz Transcoder]
|
|
41
|
+
PTT --> FFMPEG
|
|
42
|
+
FFMPEG --> Chain{Fallback Chain}
|
|
43
|
+
|
|
44
|
+
Chain -->|1st Priority| P1[Deepgram / Nova-2]
|
|
45
|
+
Chain -.->|On Rate Limit / 429| P2[Groq / Whisper Turbo]
|
|
46
|
+
Chain -.->|On Failure| P3[Local whisper.cpp / Offline]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
subgraph Output [Target]
|
|
50
|
+
P1 --> Composer[💬 Web Composer / Chat]
|
|
51
|
+
P2 --> Composer
|
|
52
|
+
P3 --> Composer
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
style Client fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
|
|
56
|
+
style Host fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
|
|
57
|
+
style Output fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
|
|
25
58
|
```
|
|
26
59
|
|
|
27
|
-
|
|
60
|
+
---
|
|
28
61
|
|
|
29
|
-
##
|
|
62
|
+
## ✨ Key Features
|
|
30
63
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
64
|
+
* 🎙️ **Streaming Dictation with VAD**: Speech is automatically sliced at natural pauses (`vadSilenceMs`, default 700ms) and typed into the composer in real time.
|
|
65
|
+
* 🌊 **Voice Notes with Cancel Window**: Record your thought and have it automatically dispatched to the agent after a safety countdown (`autoSendMs`, default 4000ms).
|
|
66
|
+
* 🎮 **Tactile Push-to-Talk**:
|
|
67
|
+
* **Mouse**: Hold the wave button — releasing sends the message; dragging pointer away discards.
|
|
68
|
+
* **Keyboard**: Hold <kbd>Ctrl</kbd> (or custom hotkey) for hands-free speaking; press <kbd>Esc</kbd> to cancel.
|
|
69
|
+
* ⚡ **Zero-Latency In-Browser Captions (`browser`)**: Chrome Web Speech API recognition runs 100% locally with live floating captions as you speak.
|
|
70
|
+
* 🛡️ **Ironclad Multi-Provider Fallbacks**: If your primary cloud provider runs out of credits or hits a 429 rate limit, requests seamlessly fail over down the chain.
|
|
71
|
+
* 🧠 **Context Glossary Injection**: Automatically extracts code variables and identifiers from your composer draft to steer STT model accuracy on technical jargon.
|
|
72
|
+
* 🎵 **Embedded Audio Player**: Preview, scrubber, and playback of your recorded voice message directly in chat and the composer dock.
|
|
73
|
+
* 🔇 **Hardware Noise Suppression Toggle**: Configurable in settings to toggle browser-level noise suppression, echo cancellation, and auto gain control.
|
|
74
|
+
* 📊 **Provider Latency & Health Dashboard**: Live visual telemetry of provider latency (ms), success rates, and errors directly within the settings UI.
|
|
75
|
+
* 🔒 **Zero API Key Leakage**: Keys are resolved on the host via `ctx.credentials` (`credentialRef`) and never transmitted to browser clients.
|
|
76
|
+
* 🖥️ **Offline Local Whisper Server**: Automatically boots and manages [whisper.cpp](https://github.com/ggerganov/whisper.cpp) (`whisper-server`) with on-the-fly `ffmpeg` transcode.
|
|
77
|
+
* ⚡ **SenseVoice-ONNX / Sherpa-ONNX** *(0.8.11)*: Ultra-fast (~50–100ms) non-autoregressive local STT engine with automatic emotion/event tag stripping. Supports both Sherpa-ONNX HTTP and OpenAI-compatible endpoints.
|
|
78
|
+
* 🌐 **Realtime Audio Streaming** *(0.8.11)*: Low-latency WebSocket bridge (`/dsh-voice/realtime`) for OpenAI Realtime API or local Sherpa-ONNX streaming. API keys stay securely on the host.
|
|
38
79
|
|
|
39
|
-
|
|
40
|
-
`$DSH_HOME/.credentials.yaml`), falling back to the process environment. A
|
|
41
|
-
provider without a key is skipped, not fatal.
|
|
80
|
+
---
|
|
42
81
|
|
|
43
|
-
|
|
82
|
+
## 🎮 Four Ways to Speak
|
|
44
83
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
| Name | Model | Credential |
|
|
84
|
+
| Mode | Gesture / Trigger | Behavior |
|
|
48
85
|
|---|---|---|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
| `mistral` | `voxtral-mini-latest` | `MISTRAL_API_KEY` |
|
|
54
|
-
| `openrouter` | `google/gemini-2.5-flash` | `OPENROUTER_API_KEY` |
|
|
55
|
-
|
|
56
|
-
```yaml
|
|
57
|
-
- id: dsh-voice
|
|
58
|
-
config:
|
|
59
|
-
message:
|
|
60
|
-
chain:
|
|
61
|
-
- provider: openai
|
|
62
|
-
- provider: local-whisper
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Every endpoint was probed without a key before being written down: all six answered `401`, the answer of a path that exists and wants credentials. The model ids are starting points — override `model` in a chain row to change one.
|
|
86
|
+
| **Dictation** | Click <kbd>🎙️ Mic</kbd> | Speech is sliced on pauses (`vadSilenceMs`) and typed live into composer |
|
|
87
|
+
| **Voice Message** | Click <kbd>🌊 Wave</kbd> | Records until stopped, then sends after cancel window (`autoSendMs`) |
|
|
88
|
+
| **Mouse PTT** | Hold <kbd>🌊 Wave</kbd> | Records while held; release sends message, drag off button to discard |
|
|
89
|
+
| **Keyboard PTT** | Hold <kbd>Ctrl</kbd> | Hands-free recording; release sends message, press <kbd>Esc</kbd> to discard |
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
> [!TIP]
|
|
92
|
+
> You can customize the keyboard modifier in settings (`hotkey`: `Control`, `Alt`, `Shift`, or any `KeyboardEvent.code`).
|
|
68
93
|
|
|
69
|
-
|
|
94
|
+
---
|
|
70
95
|
|
|
71
|
-
|
|
72
|
-
next to the built-in ones. Two templates, because those APIs disagree on how
|
|
73
|
-
audio is sent:
|
|
96
|
+
## 🛠️ Supported Providers Matrix
|
|
74
97
|
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
98
|
+
| Provider Key | Service Backend | Default Model | Credential Ref | Features & Notes |
|
|
99
|
+
|---|---|---|---|---|
|
|
100
|
+
| `browser` | Web Speech API | Native Browser | *None* | Zero latency, floating live captions in Chrome |
|
|
101
|
+
| `deepgram` | Deepgram API | `nova-2` | `DEEPGRAM_API_KEY` | Ultra-fast cloud transcription |
|
|
102
|
+
| `groq` | Groq Whisper | `whisper-large-v3-turbo` | `GROQ_API_KEY` | Near-instant inference speed |
|
|
103
|
+
| `hf` | HuggingFace Inference | `openai/whisper-large-v3` | `HF_TOKEN` | High-accuracy open Whisper |
|
|
104
|
+
| `local-whisper` | Local whisper.cpp | Server defined | *None* | 100% private, offline, no internet needed |
|
|
105
|
+
| `sensevoice` | SenseVoice-ONNX / Sherpa-ONNX | `SenseVoiceSmall` | *None* | Ultra-fast (~50ms) local non-autoregressive STT |
|
|
79
106
|
|
|
80
|
-
|
|
81
|
-
template there:
|
|
107
|
+
### 🚀 Ready-Made Presets (Plug & Play)
|
|
82
108
|
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
model: google/gemini-2.5-flash
|
|
91
|
-
keyEnv: OPENROUTER_API_KEY
|
|
92
|
-
message:
|
|
93
|
-
chain:
|
|
94
|
-
- provider: openrouter
|
|
95
|
-
- provider: local-whisper
|
|
96
|
-
```
|
|
109
|
+
Just specify the name in your fallback chain and add the corresponding API key:
|
|
110
|
+
* `openai` (`whisper-1`) → `OPENAI_API_KEY`
|
|
111
|
+
* `siliconflow` (`SenseVoiceSmall`) → `SILICONFLOW_API_KEY`
|
|
112
|
+
* `mistral` (`voxtral-mini-latest`) → `MISTRAL_API_KEY`
|
|
113
|
+
* `openrouter` (`google/gemini-2.5-flash`) → `OPENROUTER_API_KEY`
|
|
114
|
+
* `deepinfra` (`whisper-large-v3-turbo`) → `DEEPINFRA_API_KEY`
|
|
115
|
+
* `fireworks` (`whisper-v3-turbo`) → `FIREWORKS_API_KEY`
|
|
97
116
|
|
|
98
|
-
|
|
99
|
-
one), `keyEnv` names the credential holding the API key (empty means no
|
|
100
|
-
authorization header), and `prompt` overrides the instruction sent with the
|
|
101
|
-
audio in the chat template. A row in a chain may still override `model`.
|
|
117
|
+
---
|
|
102
118
|
|
|
103
|
-
|
|
104
|
-
webm/opus — the plugin converts with ffmpeg, the same way the local whisper
|
|
105
|
-
provider does, so **ffmpeg is required for `openai-chat-audio`**.
|
|
119
|
+
## 📦 Quick Installation
|
|
106
120
|
|
|
107
|
-
|
|
121
|
+
```bash
|
|
122
|
+
dsh plugin --profile web add @goodandready/dsh-voice
|
|
123
|
+
```
|
|
108
124
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
| Click the microphone | dictation: speech is cut on pauses and each phrase is appended to the composer |
|
|
112
|
-
| Click the wave | a voice message: recording runs until you stop it, then the text is sent after a cancel window |
|
|
113
|
-
| **Hold the wave** | records only while held; release sends it, moving the pointer off the button discards |
|
|
114
|
-
| **Hold `Ctrl`** | the same without reaching for the mouse; `Escape` discards |
|
|
125
|
+
> [!IMPORTANT]
|
|
126
|
+
> Restart DSH Web UI after installation (`systemctl --user restart dsh-web`) and refresh your browser tab.
|
|
115
127
|
|
|
116
|
-
|
|
128
|
+
---
|
|
117
129
|
|
|
118
|
-
##
|
|
130
|
+
## ⚙️ Configuration
|
|
119
131
|
|
|
120
|
-
|
|
132
|
+
Open **Settings → Plugins → Plugin settings → Voice** in the Web UI:
|
|
121
133
|
|
|
122
134
|
```yaml
|
|
123
135
|
- id: dsh-voice
|
|
124
136
|
config:
|
|
125
137
|
dictation:
|
|
138
|
+
language: ru
|
|
139
|
+
vadSilenceMs: 700
|
|
126
140
|
chain:
|
|
127
|
-
- provider:
|
|
128
|
-
- provider:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
Settings → **Plugins → Plugin settings → Voice** — the plugin's own
|
|
141
|
-
collapsible card in the plugins tab; the sidebar keeps no separate row for it.
|
|
142
|
-
The card has four blocks:
|
|
143
|
-
|
|
144
|
-
- **Dictation** — fallback chain (provider + optional model per row, order is
|
|
145
|
-
the order of attempts), language, and the silence threshold that ends a
|
|
146
|
-
phrase (`vadSilenceMs`, default 700 ms).
|
|
147
|
-
- **Voice message** — its own independent chain, language, and the cancel
|
|
148
|
-
window before the message is sent (`autoSendMs`, default 4000 ms).
|
|
149
|
-
- **Your own providers** — an OpenAI-compatible API per card: name, template,
|
|
150
|
-
base URL, model, credential name. The name becomes selectable in both chains
|
|
151
|
-
as soon as it is filled in.
|
|
152
|
-
- **General** — local whisper endpoint, binary, model, autostart, beep, localOnly,
|
|
153
|
-
microphone, custom vocabulary, offline polish endpoint (`polishBaseUrl`/`polishModel`/`polishKeyEnv`).
|
|
154
|
-
- **Voice message** also has `polishSend` (polish the whole draft before sending) and
|
|
155
|
-
`sessionCommands` ("send", "cancel", "stop", "continue" act on the session instead of text).
|
|
156
|
-
- **Dictation** also has a wake word: browser recognition starts recording when speech
|
|
157
|
-
begins with that phrase (empty disables it).
|
|
158
|
-
|
|
159
|
-
Speed matters for dictation and accuracy for messages, which is why the chains
|
|
160
|
-
are separate: a sensible pair is Deepgram → Groq → local for dictation and
|
|
161
|
-
Groq → HuggingFace → local for messages.
|
|
162
|
-
|
|
163
|
-
## Local whisper.cpp
|
|
164
|
-
|
|
165
|
-
The local provider needs a running [whisper.cpp](https://github.com/ggerganov/whisper.cpp)
|
|
166
|
-
server:
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
whisper-server -m /path/to/ggml-medium-q8_0.bin --host 127.0.0.1 --port 8001
|
|
141
|
+
- provider: deepgram
|
|
142
|
+
- provider: groq
|
|
143
|
+
- provider: local-whisper
|
|
144
|
+
message:
|
|
145
|
+
language: ru
|
|
146
|
+
autoSendMs: 4000
|
|
147
|
+
chain:
|
|
148
|
+
- provider: openai
|
|
149
|
+
- provider: local-whisper
|
|
150
|
+
hotkey: Control
|
|
151
|
+
autoStart: true
|
|
152
|
+
whisperModel: /models/ggml-medium-q8_0.bin
|
|
170
153
|
```
|
|
171
154
|
|
|
172
|
-
|
|
173
|
-
launches the server itself when `autoStart` is on. While `whisperModel` is
|
|
174
|
-
empty, autostart stays off.
|
|
175
|
-
|
|
176
|
-
**ffmpeg is required for this provider.** whisper.cpp accepts WAV only and
|
|
177
|
-
rejects the webm/opus the browser records, so the host converts each recording
|
|
178
|
-
to 16 kHz mono WAV before forwarding it. Point `ffmpegBin` at your binary if it
|
|
179
|
-
is not in `PATH`.
|
|
180
|
-
|
|
181
|
-
## Tool
|
|
155
|
+
---
|
|
182
156
|
|
|
183
|
-
|
|
184
|
-
agent, using the voice-message chain. Useful for recordings and interviews that
|
|
185
|
-
are already files on disk.
|
|
186
|
-
|
|
187
|
-
## Routes
|
|
188
|
-
|
|
189
|
-
| Route | Purpose |
|
|
190
|
-
|---|---|
|
|
191
|
-
| `POST /dsh-voice/transcribe` | `{dataBase64, mimeType, mode}` → `{ok, text, provider, tookMs}` |
|
|
192
|
-
| `GET /dsh-voice/status` | whisper server state and the effective chains |
|
|
193
|
-
|
|
194
|
-
## Structure
|
|
195
|
-
|
|
196
|
-
```
|
|
197
|
-
lib/index.js host: config, routes, transcribe_audio, whisper autostart
|
|
198
|
-
lib/providers.js the four providers, pure functions (network injected)
|
|
199
|
-
lib/chain.js fallback walk over a chain
|
|
200
|
-
lib/wav.js webm/opus → WAV 16 kHz mono via ffmpeg
|
|
201
|
-
lib/client.js browser: composer buttons, recording, settings page
|
|
202
|
-
test/ node --test units for the chain and the providers
|
|
203
|
-
```
|
|
157
|
+
## 🤖 Agent Tool & HTTP API
|
|
204
158
|
|
|
205
|
-
|
|
159
|
+
### Agent Tool (`transcribe_audio`)
|
|
160
|
+
Registers `transcribe_audio(file_path, language?)` in `ctx.tools`, allowing agents to analyze audio files, interview recordings, and voice notes directly from disk.
|
|
206
161
|
|
|
207
|
-
|
|
162
|
+
### Internal HTTP Endpoints
|
|
163
|
+
* `POST /dsh-voice/transcribe` — `{ dataBase64, mimeType, mode }` → `{ ok, text, provider, tookMs }`
|
|
164
|
+
* `POST /dsh-voice/polish` — `{ text }` → `{ ok, text }`
|
|
165
|
+
* `GET /dsh-voice/status` — Returns daemon status, active chains, SenseVoice and realtime config.
|
|
166
|
+
* `GET /dsh-voice/realtime` — **WebSocket upgrade** for low-latency audio streaming (OpenAI Realtime API / Sherpa-ONNX). Accepts binary audio chunks, returns JSON text deltas.
|
|
208
167
|
|
|
209
|
-
|
|
210
|
-
- Node 20+
|
|
211
|
-
- ffmpeg, for the local whisper provider
|
|
212
|
-
- a microphone reachable from the browser (HTTPS or localhost)
|
|
168
|
+
---
|
|
213
169
|
|
|
214
|
-
## License
|
|
170
|
+
## 📄 License
|
|
215
171
|
|
|
216
|
-
MIT
|
|
172
|
+
MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
|
package/README.ru.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
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
|
+
</div>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ⚡ Обзор
|
|
29
|
+
|
|
30
|
+
**`dsh-voice`** добавляет полноценные голосовые возможности в веб-интерфейс **DeepSeek Harness**. Будь то непрерывная диктовка с нарезкой фраз по естественным паузам или голосовые сообщения с удобными жестами Push-to-Talk (мышь и клавиатура) — `dsh-voice` гарантирует сохранность каждой записи благодаря **автоматическим цепочкам отказоустойчивости**.
|
|
31
|
+
|
|
32
|
+
```mermaid
|
|
33
|
+
graph LR
|
|
34
|
+
subgraph Client [Браузер Web UI]
|
|
35
|
+
Mic[🎙️ Микрофон диктовки] -->|Нарезка фраз VAD| Stream[Аудио-чанки]
|
|
36
|
+
Wave[🌊 Голосовое сообщение] -->|Зажатие / Отпускание| PTT[Push-to-Talk]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph Host [Бэкенд DSH Host]
|
|
40
|
+
Stream --> FFMPEG[Транскодер ffmpeg 16кГц]
|
|
41
|
+
PTT --> FFMPEG
|
|
42
|
+
FFMPEG --> Chain{Цепочка фолбеков}
|
|
43
|
+
|
|
44
|
+
Chain -->|1-й приоритет| P1[Deepgram / Nova-2]
|
|
45
|
+
Chain -.->|При лимитах / 429| P2[Groq / Whisper Turbo]
|
|
46
|
+
Chain -.->|При сбое| P3[Локальный whisper.cpp]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
subgraph Output [Результат]
|
|
50
|
+
P1 --> Composer[💬 Строка ввода чата]
|
|
51
|
+
P2 --> Composer
|
|
52
|
+
P3 --> Composer
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
style Client fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
|
|
56
|
+
style Host fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
|
|
57
|
+
style Output fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## ✨ Ключевые возможности
|
|
63
|
+
|
|
64
|
+
* 🎙️ **Потоковая диктовка с VAD**: аудиопоток режется по естественным паузам речи (`vadSilenceMs`, по умолчанию 700 мс) и мгновенно печатается в поле ввода.
|
|
65
|
+
* 🌊 **Голосовые заметки с окном отмены**: запишите законченную мысль — сообщение автоматически уйдёт агенту по истечении таймера (`autoSendMs`, по умолчанию 4000 мс).
|
|
66
|
+
* 🎮 **Тактильный Push-to-Talk**:
|
|
67
|
+
* **Мышь**: зажмите кнопку волны — запись идёт пока кнопка зажата; отпускание отправляет, увод курсора отменяет запись.
|
|
68
|
+
* **Клавиатура**: зажмите <kbd>Ctrl</kbd> для записи без мыши; нажмите <kbd>Esc</kbd> для отмены.
|
|
69
|
+
* ⚡ **Субтитры браузера в реальном времени (`browser`)**: локальное распознавание Chrome Web Speech API без отправки звука на сервер с плавающими субтитрами.
|
|
70
|
+
* 🛡️ **Надёжные цепочки фолбеков**: при исчерпании квоты или ошибке 429 плагин мгновенно обращается к следующему провайдеру в списке.
|
|
71
|
+
* 🧠 **Контекстный словарь (Context Glossary)**: автоматическое извлечение переменных и технических терминов из черновика композера для точного распознавания редких слов и кода.
|
|
72
|
+
* 🎵 **Встроенный аудиоплеер**: предпросмотр и воспроизведение записанного голосового сообщения в чате и доке перед отправкой или для переслушивания.
|
|
73
|
+
* 🔇 **Аппаратное шумоподавление**: переключатель в настройках для включения/выключения браузерного шумоподавления, эхоподавления и АРУ.
|
|
74
|
+
* 📊 **Дашборд задержки и здоровья провайдеров**: мониторинг скорости ответа (мс), процента успешных транскрипций и ошибок в реальном времени.
|
|
75
|
+
* 🔒 **Безопасность API-ключей**: ключи читаются на сервере через `ctx.credentials` и никогда не попадают в браузер клиента.
|
|
76
|
+
* 🖥️ **Автозапуск локального whisper.cpp**: управление жизненным циклом `whisper-server` с авто-конвертацией через `ffmpeg`.
|
|
77
|
+
* ⚡ **SenseVoice-ONNX / Sherpa-ONNX** *(0.8.11)*: сверхбыстрый (~50–100мс) неавторегрессивный локальный STT с автоматической очисткой тегов эмоций/событий. Поддержка Sherpa-ONNX HTTP и OpenAI-совместимых эндпоинтов.
|
|
78
|
+
* 🌐 **Потоковое аудио в реальном времени** *(0.8.11)*: низколатентный WebSocket-мост (`/dsh-voice/realtime`) для OpenAI Realtime API или локального Sherpa-ONNX. API-ключи остаются на хосте.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🎮 4 способа голосового ввода
|
|
83
|
+
|
|
84
|
+
| Режим | Жест / Активация | Поведение |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| **Диктовка** | Клик <kbd>🎙️ Микрофон</kbd> | Речь режется по паузам (`vadSilenceMs`) и вставляется прямо в строку ввода |
|
|
87
|
+
| **Голосовое сообщение** | Клик <kbd>🌊 Волна</kbd> | Запись до нажатия стоп, затем отправка с окном отмены (`autoSendMs`) |
|
|
88
|
+
| **PTT Мышью** | Зажатие <kbd>🌊 Волна</kbd> | Запись пока зажата кнопка; отпускание отправляет, увод мыши сбрасывает |
|
|
89
|
+
| **PTT Клавиатурой** | Зажатие <kbd>Ctrl</kbd> | Запись без мыши; отпускание отправляет, нажатие <kbd>Esc</kbd> отменяет |
|
|
90
|
+
|
|
91
|
+
> [!TIP]
|
|
92
|
+
> Клавиатурную клавишу можно легко переопределить в настройках (`hotkey`: `Control`, `Alt`, `Shift` или любой код клавиши).
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 🛠️ Матрица поддерживаемых провайдеров
|
|
97
|
+
|
|
98
|
+
| Ключ | Сервис | Модель по умолчанию | Переменная секрета | Особенности |
|
|
99
|
+
|---|---|---|---|---|
|
|
100
|
+
| `browser` | Web Speech API | Нативная в браузере | *Не требуется* | Нулевая задержка, живые субтитры в Chrome |
|
|
101
|
+
| `deepgram` | Deepgram API | `nova-2` | `DEEPGRAM_API_KEY` | Сверхбыстрая облачная транскрипция |
|
|
102
|
+
| `groq` | Groq Whisper | `whisper-large-v3-turbo` | `GROQ_API_KEY` | Мгновенная скорость генерации |
|
|
103
|
+
| `hf` | HuggingFace Inference | `openai/whisper-large-v3` | `HF_TOKEN` | Высокоточный облачный Whisper |
|
|
104
|
+
| `local-whisper` | Локальный whisper.cpp | из параметров сервера | *Не требуется* | 100% приватность, оффлайн, без интернета |
|
|
105
|
+
| `sensevoice` | SenseVoice-ONNX / Sherpa-ONNX | `SenseVoiceSmall` | *Не требуется* | Сверхбыстрый (~50мс) локальный неавторегрессивный STT |
|
|
106
|
+
|
|
107
|
+
### 🚀 Готовые пресеты (Plug & Play)
|
|
108
|
+
|
|
109
|
+
Достаточно указать имя в цепочке и добавить API-ключ:
|
|
110
|
+
* `openai` (`whisper-1`) → `OPENAI_API_KEY`
|
|
111
|
+
* `siliconflow` (`SenseVoiceSmall`) → `SILICONFLOW_API_KEY`
|
|
112
|
+
* `mistral` (`voxtral-mini-latest`) → `MISTRAL_API_KEY`
|
|
113
|
+
* `openrouter` (`google/gemini-2.5-flash`) → `OPENROUTER_API_KEY`
|
|
114
|
+
* `deepinfra` (`whisper-large-v3-turbo`) → `DEEPINFRA_API_KEY`
|
|
115
|
+
* `fireworks` (`whisper-v3-turbo`) → `FIREWORKS_API_KEY`
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 📦 Быстрая установка
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
dsh plugin --profile web add @goodandready/dsh-voice
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
> [!IMPORTANT]
|
|
126
|
+
> Перезапустите Web UI после установки (`systemctl --user restart dsh-web`) и обновите страницу в браузере.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## ⚙️ Настройка конфигурации
|
|
131
|
+
|
|
132
|
+
Откройте **Настройки → Плагины → Настройки плагинов → Голос** в Web UI:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
- id: dsh-voice
|
|
136
|
+
config:
|
|
137
|
+
dictation:
|
|
138
|
+
language: ru
|
|
139
|
+
vadSilenceMs: 700
|
|
140
|
+
chain:
|
|
141
|
+
- provider: deepgram
|
|
142
|
+
- provider: groq
|
|
143
|
+
- provider: local-whisper
|
|
144
|
+
message:
|
|
145
|
+
language: ru
|
|
146
|
+
autoSendMs: 4000
|
|
147
|
+
chain:
|
|
148
|
+
- provider: openai
|
|
149
|
+
- provider: local-whisper
|
|
150
|
+
hotkey: Control
|
|
151
|
+
autoStart: true
|
|
152
|
+
whisperModel: /models/ggml-medium-q8_0.bin
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 🤖 Инструмент агента и HTTP API
|
|
158
|
+
|
|
159
|
+
### Инструмент агента (`transcribe_audio`)
|
|
160
|
+
Регистрирует `transcribe_audio(file_path, language?)` в `ctx.tools`, позволяя агентам распознавать аудиофайлы, интервью и записи с диска.
|
|
161
|
+
|
|
162
|
+
### Внутренние HTTP эндпоинты
|
|
163
|
+
* `POST /dsh-voice/transcribe` — `{ dataBase64, mimeType, mode }` → `{ ok, text, provider, tookMs }`
|
|
164
|
+
* `POST /dsh-voice/polish` — `{ text }` → `{ ok, text }`
|
|
165
|
+
* `GET /dsh-voice/status` — состояние демонов, цепочки, конфигурация SenseVoice и реалтайма.
|
|
166
|
+
* `GET /dsh-voice/realtime` — **WebSocket upgrade** для низколатентного аудио-стриминга (OpenAI Realtime API / Sherpa-ONNX). Принимает бинарные аудио-чанки, возвращает JSON-дельты текста.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 📄 Лицензия
|
|
171
|
+
|
|
172
|
+
MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
|