@goodandready/dsh-tts 0.3.22 → 0.4.0
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 +12 -12
- package/README.ru.md +13 -10
- package/README.zh.md +10 -10
- package/lib/cache.js +4 -5
- package/lib/client.js +105 -88
- package/lib/engines/f5.js +45 -33
- package/lib/engines/kokoro.js +21 -29
- package/lib/engines/types.js +26 -13
- package/lib/http-util.js +27 -0
- package/lib/index.js +70 -467
- package/lib/providers.js +105 -25
- package/lib/routes.js +400 -0
- package/lib/stream-hub.js +31 -0
- package/lib/text.js +46 -19
- package/package.json +6 -3
- package/scripts/f5_daemon.py +40 -0
- package/lib/client/worklet.js +0 -71
- package/lib/router.js +0 -4
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
**`dsh-tts`** provides robust, lifelike spoken voice synthesis for assistant replies in the **DeepSeek Harness** Web UI. When **Speak agent replies** is enabled, each finished assistant turn or real-time streaming chunk is synthesized on the host and streamed directly to the browser.
|
|
31
31
|
|
|
32
|
-
API keys never reach client browsers: synthesis is executed entirely on the host backend across **independent multi-provider fallback chains**, including
|
|
32
|
+
API keys never reach client browsers: synthesis is executed entirely on the host backend across **independent multi-provider fallback chains**, including local system engines (Edge TTS, Piper, eSpeak). Kokoro-82M and F5-TTS weights can be downloaded for future runtime support, but neural inference is **not bundled** in this package — those providers fail honestly and the chain continues.
|
|
33
33
|
|
|
34
34
|
```mermaid
|
|
35
35
|
graph LR
|
|
@@ -49,10 +49,10 @@ graph LR
|
|
|
49
49
|
|
|
50
50
|
subgraph Fallback [TTS Provider Fallback Chain]
|
|
51
51
|
LRU -->|Cache Miss| Chain{Active Chain}
|
|
52
|
-
Chain -->|
|
|
53
|
-
Chain -.->|Cloud Neural| P2[ElevenLabs /
|
|
54
|
-
Chain -.->|
|
|
55
|
-
Chain -.->|
|
|
52
|
+
Chain -->|Offline| P1[Edge TTS / Piper / eSpeak]
|
|
53
|
+
Chain -.->|Cloud Neural| P2[OpenAI / ElevenLabs / Google / Azure / Groq]
|
|
54
|
+
Chain -.->|OpenAI-compatible| P3[SiliconFlow / DeepInfra / Fireworks / OpenRouter]
|
|
55
|
+
Chain -.->|Other| P4[MiMo / MiniMax / Custom]
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
subgraph Output [Delivery & Integrations]
|
|
@@ -75,9 +75,9 @@ graph LR
|
|
|
75
75
|
|
|
76
76
|
## 🚀 Key Features
|
|
77
77
|
|
|
78
|
-
### 1. 📴 Offline
|
|
79
|
-
* **
|
|
80
|
-
* **F5-TTS
|
|
78
|
+
### 1. 📴 Offline system engines + optional future neural runtimes
|
|
79
|
+
* **Edge TTS / Piper / eSpeak**: fully offline or free local/system synthesis without cloud API keys (Edge needs the `edge-tts` CLI).
|
|
80
|
+
* **Kokoro-82M / F5-TTS**: weight download and status UI only. **Neural inference is not bundled** in this package — those providers fail with a clear reason and the fallback chain continues. Do not enable them expecting speech until a supported runtime is wired.
|
|
81
81
|
* **ModelManager UI**: Direct manual installation in settings with real-time download progress bar, SHA-256 validation, and deletion. No silent or automatic multi-gigabyte downloads.
|
|
82
82
|
|
|
83
83
|
### 2. ⚡ Real-Time Streaming Audio (< 300 ms Latency)
|
|
@@ -112,8 +112,8 @@ graph LR
|
|
|
112
112
|
|
|
113
113
|
| Provider Key | Service Backend | Default Model | Default Voice | Credential Ref | Features & Notes |
|
|
114
114
|
|---|---|---|---|---|---|
|
|
115
|
-
| `kokoro` | Local Kokoro-82M ONNX | `hexgrad/Kokoro-82M` | `af_bella` | *None* | **
|
|
116
|
-
| `f5` | Local F5-TTS GPU Daemon | `F5-TTS` | Default | *None* | **
|
|
115
|
+
| `kokoro` | Local Kokoro-82M ONNX | `hexgrad/Kokoro-82M` | `af_bella` | *None* | Weights downloadable; **ONNX inference not bundled** — fails honestly |
|
|
116
|
+
| `f5` | Local F5-TTS GPU Daemon | `F5-TTS` | Default | *None* | Daemon ping only; **GPU inference not bundled** — fails honestly |
|
|
117
117
|
| `elevenlabs` | ElevenLabs API | `eleven_multilingual_v2` | `Rachel` | `ELEVENLABS_API_KEY` | Ultra-realistic, emotional nuance |
|
|
118
118
|
| `openai` | OpenAI Audio | `gpt-4o-mini-tts` / `tts-1` | `alloy` | `OPENAI_API_KEY` | High-quality industry standard |
|
|
119
119
|
| `edge` | Microsoft Edge Online | `ru-RU-SvetlanaNeural` | `ru-RU-SvetlanaNeural` | *None* | **Free, high-fidelity neural TTS without API keys** |
|
|
@@ -170,8 +170,8 @@ dsh-tts:
|
|
|
170
170
|
cacheMaxMb: 150
|
|
171
171
|
autoDetect: true
|
|
172
172
|
chain:
|
|
173
|
-
- provider: kokoro
|
|
174
173
|
- provider: edge
|
|
174
|
+
- provider: espeak
|
|
175
175
|
voice: ru-RU-SvetlanaNeural
|
|
176
176
|
- provider: openai
|
|
177
177
|
model: tts-1
|
|
@@ -192,7 +192,7 @@ dsh-tts:
|
|
|
192
192
|
* `GET /dsh-tts/stream` — Real-time Server-Sent Events (SSE) audio streaming.
|
|
193
193
|
* `POST /dsh-tts/speak` — `{ text, voice?, model? }` → Returns synthesized audio.
|
|
194
194
|
* `POST /dsh-tts/preview` — `{ provider, model, voice, text? }` → Test voice playback in UI.
|
|
195
|
-
* `GET /dsh-tts/models/status` — Reports
|
|
195
|
+
* `GET /dsh-tts/models/status` — Reports Kokoro/F5 weight installation states (download only; inference not bundled).
|
|
196
196
|
* `POST /dsh-tts/models/install` — `{ engine: 'kokoro' | 'f5' }` → Starts HuggingFace model download.
|
|
197
197
|
* `DELETE /dsh-tts/models/delete` — `{ engine: 'kokoro' | 'f5' }` → Removes local model files.
|
|
198
198
|
* `GET /dsh-tts/integrations` — Status of sibling plugins (`dsh-voice`, `dsh-messenger-gateway`).
|
package/README.ru.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
<h3>Многопровайдерная озвучка ответов
|
|
5
|
+
<h3>Многопровайдерная озвучка ответов агента: облачные и системные offline-движки, потоковый звук, IT-словарь и интеграция с мессенджерами для DeepSeek Harness</h3>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://www.npmjs.com/package/@goodandready/dsh-tts"><img src="https://img.shields.io/npm/v/@goodandready/dsh-tts.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
@@ -27,9 +27,12 @@
|
|
|
27
27
|
|
|
28
28
|
## ⚡ Обзор
|
|
29
29
|
|
|
30
|
+
> **Честно про локальные нейросети:** Kokoro/F5 — только статус и загрузка весов. Inference **не входит** в пакет; эти провайдеры падают с понятной причиной, цепочка идёт дальше. Рабочий offline: Edge TTS, Piper, eSpeak.
|
|
31
|
+
|
|
32
|
+
|
|
30
33
|
**`dsh-tts`** обеспечивает качественное голосовое озвучивание ответов ассистента в веб-интерфейсе **DeepSeek Harness**. При включённой опции **«Читать ответы агента»**, каждая готовая реплика или потоковый фрагмент синтезируется на хосте и мгновенно воспроизводится в браузере.
|
|
31
34
|
|
|
32
|
-
API-ключи никогда не передаются в браузер: синтез аудио выполняется на стороне хоста через **независимые цепочки отказоустойчивости (фолбеков)**, включая
|
|
35
|
+
API-ключи никогда не передаются в браузер: синтез аудио выполняется на стороне хоста через **независимые цепочки отказоустойчивости (фолбеков)**, включая системные offline-движки (Edge TTS, Piper, eSpeak). Kokoro/F5 — только загрузка весов; inference не входит в пакет.
|
|
33
36
|
|
|
34
37
|
```mermaid
|
|
35
38
|
graph LR
|
|
@@ -49,8 +52,8 @@ graph LR
|
|
|
49
52
|
|
|
50
53
|
subgraph Fallback [Цепочка фолбеков TTS]
|
|
51
54
|
LRU -->|Промах кэша| Chain{Активная цепочка}
|
|
52
|
-
Chain -->|
|
|
53
|
-
Chain
|
|
55
|
+
Chain -->|Offline| P1[Edge TTS / Piper / eSpeak]
|
|
56
|
+
Chain -.->|Cloud| P2[OpenAI / ElevenLabs / Google / Azure / Groq]
|
|
54
57
|
Chain -.->|Бесплатные облака| P3[EdgeTTS / SiliconFlow]
|
|
55
58
|
Chain -.->|Системный фолбек| P4[Локальный Piper / eSpeak NG]
|
|
56
59
|
end
|
|
@@ -75,9 +78,9 @@ graph LR
|
|
|
75
78
|
|
|
76
79
|
## 🚀 Ключевые возможности
|
|
77
80
|
|
|
78
|
-
### 1. 📴
|
|
79
|
-
* **
|
|
80
|
-
* **F5-TTS
|
|
81
|
+
### 1. 📴 Offline-системные движки и честный статус нейросетей
|
|
82
|
+
* **Edge TTS / Piper / eSpeak**: рабочий offline/системный синтез без облачных API-ключей.
|
|
83
|
+
* **Kokoro-82M / F5-TTS**: только UI и загрузка весов. **Inference не входит в пакет** — провайдер падает с понятной причиной, цепочка идёт дальше.
|
|
81
84
|
* **ModelManager в UI**: Ручная загрузка моделей прямо из настроек плагина с отображением процентов и прогресс-бара, проверкой SHA-256 и кнопкой удаления. Никаких скрытых или автозагрузок гигабайтных весов.
|
|
82
85
|
|
|
83
86
|
### 2. ⚡ Потоковое воспроизведение звука с задержкой < 300 мс
|
|
@@ -112,8 +115,8 @@ graph LR
|
|
|
112
115
|
|
|
113
116
|
| Ключ провайдера | Сервис | Модель по умолчанию | Голос по умолчанию | Имя ключа (credential) | Особенности |
|
|
114
117
|
|---|---|---|---|---|---|
|
|
115
|
-
| `kokoro` |
|
|
116
|
-
| `f5` |
|
|
118
|
+
| `kokoro` | Веса Kokoro-82M (ONNX) | `hexgrad/Kokoro-82M` | `af_bella` | *Не требуется* | Веса скачать можно; **inference не bundled** — честный fail |
|
|
119
|
+
| `f5` | Демон F5 (ping) | `F5-TTS` | По умолчанию | *Не требуется* | Только ping; **GPU inference не bundled** — честный fail |
|
|
117
120
|
| `elevenlabs` | ElevenLabs API | `eleven_multilingual_v2` | `Rachel` | `ELEVENLABS_API_KEY` | Реалистичный эмоциональный синтез |
|
|
118
121
|
| `openai` | OpenAI Audio | `gpt-4o-mini-tts` / `tts-1` | `alloy` | `OPENAI_API_KEY` | Эталонное качество индустрии |
|
|
119
122
|
| `edge` | Microsoft Edge Online | `ru-RU-SvetlanaNeural` | `ru-RU-SvetlanaNeural` | *Не требуется* | **Бесплатный нейросинтез без API-ключей** |
|
|
@@ -182,7 +185,7 @@ dsh-tts:
|
|
|
182
185
|
* `GET /dsh-tts/stream` — Потоковая передача аудио по SSE в реальном времени.
|
|
183
186
|
* `POST /dsh-tts/speak` — `{ text, voice?, model? }` → Возвращает аудиофайл для воспроизведения.
|
|
184
187
|
* `POST /dsh-tts/preview` — `{ provider, model, voice, text? }` → Тестовое прослушивание голоса в UI.
|
|
185
|
-
* `GET /dsh-tts/models/status` — Статус
|
|
188
|
+
* `GET /dsh-tts/models/status` — Статус загрузки весов Kokoro/F5 (inference не в комплекте).
|
|
186
189
|
* `POST /dsh-tts/models/install` — `{ engine: 'kokoro' | 'f5' }` → Запуск загрузки модели с HuggingFace.
|
|
187
190
|
* `DELETE /dsh-tts/models/delete` — `{ engine: 'kokoro' | 'f5' }` → Удаление локальной модели.
|
|
188
191
|
* `GET /dsh-tts/integrations` — Проверка статуса связанных плагинов (`dsh-voice`, `dsh-messenger-gateway`).
|
package/README.zh.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
<h3>DeepSeek Harness
|
|
5
|
+
<h3>DeepSeek Harness 多引擎语音合成:云端与系统离线引擎、流式音频、IT 术语词典与即时通讯集成</h3>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://www.npmjs.com/package/@goodandready/dsh-tts"><img src="https://img.shields.io/npm/v/@goodandready/dsh-tts.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
**`dsh-tts`** 为 **DeepSeek Harness** Web 界面提供高保真智能体回复语音朗读服务。开启 **朗读智能体回复** 后,每条生成的助手回复或实时流式片段均由服务端合成并即时推流至浏览器播放。
|
|
31
31
|
|
|
32
|
-
API
|
|
32
|
+
API 密钥绝不暴露给前端:音频合成全程在服务端通过**多服务商独立备用链**执行,包括系统离线引擎(Edge TTS、Piper、eSpeak)。Kokoro/F5 仅可下载权重,**推理未捆绑**。
|
|
33
33
|
|
|
34
34
|
```mermaid
|
|
35
35
|
graph LR
|
|
@@ -49,8 +49,8 @@ graph LR
|
|
|
49
49
|
|
|
50
50
|
subgraph Fallback [TTS 引擎备用链]
|
|
51
51
|
LRU -->|未命中| Chain{生效备用链}
|
|
52
|
-
Chain
|
|
53
|
-
Chain
|
|
52
|
+
Chain -->|离线| P1[Edge TTS / Piper / eSpeak]
|
|
53
|
+
Chain -.->|云端| P2[OpenAI / ElevenLabs / Google / Azure / Groq]
|
|
54
54
|
Chain -.->|免费云端| P3[EdgeTTS / SiliconFlow]
|
|
55
55
|
Chain -.->|系统兜底| P4[本地 Piper / eSpeak NG]
|
|
56
56
|
end
|
|
@@ -75,9 +75,9 @@ graph LR
|
|
|
75
75
|
|
|
76
76
|
## 🚀 核心功能
|
|
77
77
|
|
|
78
|
-
### 1. 📴
|
|
79
|
-
* **
|
|
80
|
-
* **F5-TTS
|
|
78
|
+
### 1. 📴 离线系统引擎与诚实的神经引擎状态
|
|
79
|
+
* **Edge TTS / Piper / eSpeak**:可用的离线/系统合成,无需云 API Key。
|
|
80
|
+
* **Kokoro-82M / F5-TTS**:仅权重下载与状态展示。**推理未捆绑在本包中**,provider 会明确失败并继续 fallback。
|
|
81
81
|
* **ModelManager 管理界面**:在设置中手动安装模型,实时显示下载进度条、SHA-256 校验和一键删除。无任何静默或自动下载。
|
|
82
82
|
|
|
83
83
|
### 2. ⚡ 实时流式音频播放(延迟 < 300ms)
|
|
@@ -107,8 +107,8 @@ graph LR
|
|
|
107
107
|
|
|
108
108
|
| 服务商 Key | 对应引擎 | 默认模型 | 默认发音人 | 凭证变量名 | 说明与亮点 |
|
|
109
109
|
|---|---|---|---|---|---|
|
|
110
|
-
| `kokoro` |
|
|
111
|
-
| `f5` |
|
|
110
|
+
| `kokoro` | Kokoro 权重(ONNX) | `hexgrad/Kokoro-82M` | `af_bella` | *无需密钥* | 可下载权重;**推理未捆绑** — 明确失败 |
|
|
111
|
+
| `f5` | F5 守护进程(ping) | `F5-TTS` | 默认 | *无需密钥* | 仅 ping;**GPU 推理未捆绑** — 明确失败 |
|
|
112
112
|
| `elevenlabs` | ElevenLabs API | `eleven_multilingual_v2` | `Rachel` | `ELEVENLABS_API_KEY` | 极致拟人情感音色 |
|
|
113
113
|
| `openai` | OpenAI Audio | `gpt-4o-mini-tts` / `tts-1` | `alloy` | `OPENAI_API_KEY` | 经典高清发音 |
|
|
114
114
|
| `edge` | 微软 Edge 在线 | `zh-CN-XiaoxiaoNeural` | `zh-CN-XiaoxiaoNeural` | *无需密钥* | **免费免 Key 高保真神经网络语音** |
|
|
@@ -177,7 +177,7 @@ dsh-tts:
|
|
|
177
177
|
* `GET /dsh-tts/stream` — 实时 SSE 音频流推送。
|
|
178
178
|
* `POST /dsh-tts/speak` — `{ text, voice?, model? }` → 返回合成音频。
|
|
179
179
|
* `POST /dsh-tts/preview` — `{ provider, model, voice, text? }` → UI 中试听语音。
|
|
180
|
-
* `GET /dsh-tts/models/status` —
|
|
180
|
+
* `GET /dsh-tts/models/status` — 查询 Kokoro/F5 权重下载状态(推理未捆绑)。
|
|
181
181
|
* `POST /dsh-tts/models/install` — `{ engine: 'kokoro' | 'f5' }` → 启动模型下载。
|
|
182
182
|
* `DELETE /dsh-tts/models/delete` — `{ engine: 'kokoro' | 'f5' }` → 删除本地模型。
|
|
183
183
|
* `GET /dsh-tts/integrations` — 查询关联插件状态(`dsh-voice`、`dsh-messenger-gateway`)。
|
package/lib/cache.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// cacheMaxMb и может меняться на живую, поэтому приходит функцией.
|
|
1
|
+
// Disk speech cache: key is a hash of (text, provider, model, voice),
|
|
2
|
+
// value is the provider response as-is (bytes + MIME). LRU eviction;
|
|
3
|
+
// cacheMaxMb is live config so the limit is passed as a function.
|
|
5
4
|
import { createHash } from 'node:crypto'
|
|
6
5
|
import fs from 'node:fs'
|
|
7
6
|
import path from 'node:path'
|
|
@@ -68,7 +67,7 @@ export function createSpeechCache({ root, maxBytes }) {
|
|
|
68
67
|
try {
|
|
69
68
|
const meta = JSON.parse(await fs.promises.readFile(path.join(dir, key + '.json'), 'utf8'))
|
|
70
69
|
const audio = await fs.promises.readFile(path.join(dir, key + AUDIO_EXT))
|
|
71
|
-
//
|
|
70
|
+
// Touch LRU asynchronously so reads are never blocked.
|
|
72
71
|
fs.promises.writeFile(path.join(dir, key + '.json'), JSON.stringify({ mime: meta.mime, at: Date.now() })).catch(() => {})
|
|
73
72
|
return { mime: meta.mime || 'audio/mpeg', audio }
|
|
74
73
|
} catch (miss) {
|