dsh-voice-mode 0.1.3 → 0.1.5
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 +3 -1
- package/lib/client.js +8 -2
- package/lib/index.js +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ DeepSeek Harness 语音双工对话模式:会话内一键进入 → 边说边
|
|
|
29
29
|
- **开口打断(barge-in)**:三档灵敏度的发声前沿检测 → 本地静音 + host 合成队列作废(epoch)+ 正在运行的回合取消(保留半截并自然续入你的新消息)
|
|
30
30
|
- **模型懒加载与进度**:首次使用自动下载 zipformer2 中文流式模型(约 160MB,`.part` 断点续传),状态条实时显示下载进度;可用 `npm run prefetch` 预下载
|
|
31
31
|
- **容错**:麦克风被拒红点提示、模型下载失败可见提示、TTS 连接失败状态条提示(自动重试)、提交失败文字留在草稿、SSE 断线自动重连
|
|
32
|
-
- **设置**:设置 → 插件配置 → voice-mode
|
|
32
|
+
- **设置**:设置 → Plugins → 插件配置 → 语音模式(voice-mode),可调音色 / 语速 / 打断灵敏度 / 静音停顿 / 空闲超时 / 模型镜像 / 自动发送 / 交互模式 / 唤醒词 / 口语化提示词;**音色可试听**(「试听」按钮按当前音色 + 当前语速即时合成预览,无需进入语音模式;自定义 ShortName 同样可试听)
|
|
33
33
|
- **空闲退出**:10 分钟无活动自动退出并释放麦克风
|
|
34
34
|
|
|
35
35
|
## 操作手势
|
|
@@ -243,6 +243,8 @@ pnpm install && pnpm build # esbuild:lib/index.js(host)+ lib/client.js
|
|
|
243
243
|
pnpm test # segmenter/wakeword 单测 + 发布前自检(均无需网络)
|
|
244
244
|
node test/hold-e2e.js # hold 模式验收(独立浏览器,/asr 路由拦截)
|
|
245
245
|
bash test/spoken-prompt-rpc.sh # 口语化提示词验证(RPC 直发,无需浏览器;需在线 TTS)
|
|
246
|
+
# 注:hold-e2e/spoken-prompt-rpc/spoken-toggle-ui-check 等集成探测脚本位于仓库根 test/
|
|
247
|
+
#(不在 npm 包内);npm 包内 test/ 仅含无需网络的离线单测。
|
|
246
248
|
systemctl restart dsh # Linux;其他平台重启 dsh 进程
|
|
247
249
|
```
|
|
248
250
|
|
package/lib/client.js
CHANGED
|
@@ -152,7 +152,7 @@ function createAsrEngine(config, sessionId) {
|
|
|
152
152
|
});
|
|
153
153
|
resolve(r2);
|
|
154
154
|
} catch {
|
|
155
|
-
resolve(new Response(null, { status:
|
|
155
|
+
resolve(new Response(null, { status: 503 }));
|
|
156
156
|
}
|
|
157
157
|
}, 5e3);
|
|
158
158
|
});
|
|
@@ -220,7 +220,7 @@ function createAsrEngine(config, sessionId) {
|
|
|
220
220
|
})
|
|
221
221
|
);
|
|
222
222
|
} catch {
|
|
223
|
-
resolve(new Response(null, { status:
|
|
223
|
+
resolve(new Response(null, { status: 503 }));
|
|
224
224
|
}
|
|
225
225
|
}, 5e3);
|
|
226
226
|
});
|
|
@@ -358,6 +358,10 @@ function createAsrEngine(config, sessionId) {
|
|
|
358
358
|
});
|
|
359
359
|
const AC = window.AudioContext ?? window.webkitAudioContext;
|
|
360
360
|
audioCtx = new AC({ sampleRate: SAMPLE_RATE });
|
|
361
|
+
try {
|
|
362
|
+
await audioCtx.resume?.();
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
361
365
|
ctxRate = audioCtx.sampleRate;
|
|
362
366
|
const source = audioCtx.createMediaStreamSource(stream);
|
|
363
367
|
processor = audioCtx.createScriptProcessor(BUFFER_SIZE, 1, 1);
|
|
@@ -1688,6 +1692,8 @@ function VoiceOverlay({ bus }) {
|
|
|
1688
1692
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1689
1693
|
"div",
|
|
1690
1694
|
{
|
|
1695
|
+
role: "status",
|
|
1696
|
+
"aria-live": "polite",
|
|
1691
1697
|
style: {
|
|
1692
1698
|
position: "fixed",
|
|
1693
1699
|
right: 16,
|
package/lib/index.js
CHANGED
|
@@ -439,10 +439,10 @@ function createVoiceSettingsSchema(defs) {
|
|
|
439
439
|
voice: z.string().default(d.voice).description(
|
|
440
440
|
"Edge TTS \u97F3\u8272\uFF08\u5927\u9646\u81EA\u7136\u97F3\uFF1Azh-CN-XiaoxiaoNeural \u6653\u6653\xB7\u5973 / zh-CN-XiaoyiNeural \u6653\u4F0A\xB7\u5973 / zh-CN-YunxiNeural \u4E91\u5E0C\xB7\u7537 / zh-CN-YunjianNeural \u4E91\u5065\xB7\u7537 / zh-CN-YunyangNeural \u4E91\u626C\xB7\u7537 / zh-CN-YunxiaNeural \u4E91\u590F\xB7\u7537\uFF1B\u65B9\u8A00\uFF1A\u4E1C\u5317-\u5C0F\u5317 / \u9655\u897F-\u5C0F\u59AE\uFF1B\u7CA4\u8BED\uFF1AHiuGaai/HiuMaan/WanLung\uFF1B\u53F0\u6E7E\uFF1AHsiaoChen/HsiaoYu/YunJhe\uFF1B\u5B8C\u6574\u6E05\u5355\u89C1 scripts/list-voices.mjs\uFF09"
|
|
441
441
|
),
|
|
442
|
-
rate: z.number().default(d.rate).description("\u6717\u8BFB\u8BED\u901F\u500D\u7387\uFF080.5 = \u6162\u901F\uFF0C2.0 = \u5FEB\u901F\uFF0C1.0 = \u6B63\u5E38\uFF09"),
|
|
442
|
+
rate: z.number().min(0.5).max(2).default(d.rate).description("\u6717\u8BFB\u8BED\u901F\u500D\u7387\uFF080.5 = \u6162\u901F\uFF0C2.0 = \u5FEB\u901F\uFF0C1.0 = \u6B63\u5E38\uFF09"),
|
|
443
443
|
interruptLevel: z.union([z.const(0), z.const(1), z.const(2)]).default(d.interruptLevel).description("\u53D1\u58F0\u6253\u65AD\u7075\u654F\u5EA6\uFF1A0 \u9AD8\u95E8\u69DB\uFF08\u5B89\u9759\u73AF\u5883\uFF0C\u9ED8\u8BA4\uFF09/ 1 \u4E2D / 2 \u4F4E\uFF08\u5608\u6742\u73AF\u5883\u66F4\u5BB9\u6613\u6253\u65AD\uFF09"),
|
|
444
|
-
silenceMs: z.number().default(d.silenceMs).description("\u8BF4\u5B8C\u6574\u4E00\u53E5\u7684\u9759\u97F3\u505C\u987F\u6BEB\u79D2\u6570\uFF08\u9ED8\u8BA4 2000 = 2 \u79D2\uFF09"),
|
|
445
|
-
idleTimeoutMinutes: z.number().default(d.idleTimeoutMinutes).description("\u65E0\u6D3B\u52A8\u81EA\u52A8\u9000\u51FA\u8BED\u97F3\u6A21\u5F0F\u7684\u5206\u949F\u6570\uFF08\u9ED8\u8BA4 10\uFF09"),
|
|
444
|
+
silenceMs: z.number().min(500).max(3e4).default(d.silenceMs).description("\u8BF4\u5B8C\u6574\u4E00\u53E5\u7684\u9759\u97F3\u505C\u987F\u6BEB\u79D2\u6570\uFF08\u9ED8\u8BA4 2000 = 2 \u79D2\uFF09"),
|
|
445
|
+
idleTimeoutMinutes: z.number().min(1).max(120).default(d.idleTimeoutMinutes).description("\u65E0\u6D3B\u52A8\u81EA\u52A8\u9000\u51FA\u8BED\u97F3\u6A21\u5F0F\u7684\u5206\u949F\u6570\uFF08\u9ED8\u8BA4 10\uFF09"),
|
|
446
446
|
modelHost: z.string().default(d.modelHost).description("ASR \u6A21\u578B\u4E0B\u8F7D\u6E90\uFF08\u7559\u7A7A\u7528\u9ED8\u8BA4\u6E90\uFF1B\u56FD\u5185\u7F51\u7EDC\u53EF\u586B https://hf-mirror.com\uFF09"),
|
|
447
447
|
autoSend: z.boolean().default(d.autoSend).description("\u8BC6\u522B\u5B9A\u7A3F\u540E\u81EA\u52A8\u53D1\u9001\uFF08\u5173\u95ED\u5219\u53EA\u8FDB\u8349\u7A3F\u4F9B\u7F16\u8F91\uFF1B\u6309\u4F4F Ctrl / hold \u677E\u624B\u4ECD\u4F1A\u53D1\u9001\uFF09"),
|
|
448
448
|
mode: z.union([z.const("toggle"), z.const("hold")]).default(d.mode).description("\u4EA4\u4E92\u6A21\u5F0F\uFF1Atoggle \u6301\u7EED\u8046\u542C + \u9759\u97F3\u81EA\u52A8\u65AD\u53E5\uFF08\u9ED8\u8BA4\uFF09\uFF1Bhold \u6309\u4F4F\u8BF4\u8BDD\u3001\u677E\u624B\u53D1\u9001\uFF08\u77ED\u6309\u9000\u51FA\uFF09"),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-voice-mode",
|
|
3
|
-
"description": "Full-duplex voice mode for DeepSeek Harness: zipformer2 streaming ASR → editable draft, Edge TTS sentence-by-sentence read-aloud with live captions, true barge-in — no API key
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"description": "Full-duplex voice mode for DeepSeek Harness: zipformer2 streaming ASR → editable draft, Edge TTS sentence-by-sentence read-aloud with live captions, true barge-in — on-device ASR, no API key. · DSH 语音双工对话:流式识别入草稿、按句朗读+实时字幕、开口即打断,识别本地推理、无需 API Key",
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"repository": {
|