dsh-voice-mode 0.7.21 → 0.7.22

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.en.md CHANGED
@@ -340,6 +340,7 @@ Also: the on-device recording fixture used for debugging is **off by default**;
340
340
  | Mic click does nothing, red hint in the status bar | The browser denied mic permission: allow it in the address bar and retry |
341
341
  | Status bar stuck on `Loading model… x%` | Check the network; the model is large (160 MB) — `npm run prefetch` first; on mainland networks set `modelHost` to `https://hf-mirror.com` |
342
342
  | Status bar shows `Model download failed (<file>)` | Both mirrors are unreachable: check network/proxy and re-enter voice mode (resumable) |
343
+ | Local Kokoro on the official desktop app shows "failed" and asks for Node.js | The desktop host is Electron, where Kokoro's native add-on cannot run: install Node.js >= 18 on PATH (or set `DSHVM_NODE` to its path) and retry, or use the default Edge / local VITS (unaffected on desktop) |
343
344
  | Caption appears (overlay) but no sound | Check system volume/output; if autoplay is blocked, click anywhere on the page and retry |
344
345
  | Status bar shows `朗读连接失败:正在重试…` | Edge TTS unreachable (overseas service), auto-retries; if it persists, check network/proxy |
345
346
  | Poor recognition | Get closer to the mic, reduce ambient noise; if echo remains, raise the interrupt sensitivity by one step |
package/README.md CHANGED
@@ -313,6 +313,7 @@ flowchart LR
313
313
  | 唤醒词完全没反应 | ① 确认交互模式是 `toggle`(`hold` 与手动打断下唤醒词不生效);② 确认 `bargeInMode`:`manual`(或 `detect` 在本机无原生回声消除时自动落 manual)会关闭常驻聆听 → 唤醒词失效,改回 `auto` 或按住麦克风/Ctrl;③ 朗读期说唤醒词不触发(先等 AI 说完);④ 看待机态实时转写,确认它听到了什么(同音字 1 字内已容错,建议 3-4 字词) |
314
314
  | 按住说话松手后没反应 | 确认交互模式为「按住说」且按住期间按钮高亮;松手后识别定稿约 1 秒内进入草稿 |
315
315
  | 打不断(朗读中开口无反应) | 调高 `interruptLevel`(更敏感档 = 0 或 1)或检查麦克风权限;若 VAD 持续不触发可临时切到「手动打断」(`mode: hold` / 唤醒词定时延后);**不要**调 `echoGateDb`——真机 3.1 分钟朗读期里 Silero 0/777 帧把回声判成语音,原生 AEC 生效时此阈值从未被执行(详见 ADR-0006) |
316
+ | 官方桌面端上选本地 Kokoro,设置里显示「加载失败」并提示需要 Node.js | 桌面端宿主是 Electron,Kokoro 的原生 addon 在其中不可用:在系统 PATH 上安装 Node.js ≥18(或设环境变量 `DSHVM_NODE` 指向它)后重试;或改用默认的 Edge / 本地 VITS(桌面端不受影响) |
316
317
  | 字幕被输入框挡住 | 默认 `captionMaxWidth=1`(70vw)+ `captionFontSize=0`(12px)在窄屏可能与底部输入框重叠;调高档位或点字幕浮层「×」收起 |
317
318
  | 让位行为异常(朗读期说「嗯」不停 / 真话被打断) | 「嗯/对」类短词触发让位 1.5s 后继续朗读;继续说真话会走硬打断;不要时关 `backchannelYield` 即可恢复改造前行为(ADR-0008) |
318
319
  | 朗读期说「嗯」没让位 | 确认 `backchannelYield=true`(默认开);hold 模式松手后让位 1.5s 内继续说话会变硬打断 |
package/lib/client.js CHANGED
@@ -1534,6 +1534,7 @@ var zh = {
1534
1534
  engineLoading: "\u52A0\u8F7D\u4E2D\u2026",
1535
1535
  engineReady: "\u5C31\u7EEA",
1536
1536
  engineError: "\u52A0\u8F7D\u5931\u8D25",
1537
+ errKokoroNeedsNode: "\u672C\u5730 Kokoro \u65E0\u6CD5\u5728\u5B98\u65B9\u684C\u9762\u7AEF\uFF08Electron\uFF09\u5185\u76F4\u63A5\u8FD0\u884C\uFF1A\u8BF7\u5728\u7CFB\u7EDF PATH \u4E0A\u5B89\u88C5 Node.js \u226518\uFF08\u6216\u8BBE\u73AF\u5883\u53D8\u91CF DSHVM_NODE \u6307\u5411\u5B83\uFF09\uFF0C\u6216\u628A\u6717\u8BFB\u5F15\u64CE\u5207\u6362\u4E3A Edge / \u672C\u5730 VITS\u3002",
1537
1538
  ttsModelsMissing: "\u672C\u5730\u6A21\u578B\u672A\u5C31\u7EEA",
1538
1539
  ttsDownload: "\u4E0B\u8F7D",
1539
1540
  ttsDelete: "\u5220\u9664",
@@ -1763,6 +1764,7 @@ var en = {
1763
1764
  engineLoading: "loading\u2026",
1764
1765
  engineReady: "ready",
1765
1766
  engineError: "failed",
1767
+ errKokoroNeedsNode: "Local Kokoro cannot run directly inside the official desktop app (Electron): install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge / local VITS.",
1766
1768
  ttsModelsMissing: "local models missing",
1767
1769
  ttsDownload: "Download",
1768
1770
  ttsDelete: "Delete",
@@ -2749,7 +2751,7 @@ function EngineStatusInline() {
2749
2751
  children: acting ? acting === "clean" ? t("ttsDeleting") : t("ttsDownloading") : action === "clean" ? t("ttsDelete") : t("ttsDownload")
2750
2752
  }
2751
2753
  ),
2752
- tts.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, color: "var(--dsw-alias-state-error-primary)", flexBasis: "100%" }, children: tts.error })
2754
+ tts.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, color: "var(--dsw-alias-state-error-primary)", flexBasis: "100%" }, children: tts.errorCode === "kokoro_needs_node" ? t("errKokoroNeedsNode") : tts.error })
2753
2755
  ] });
2754
2756
  }
2755
2757
  function ModelStatusView() {
@@ -3099,7 +3101,7 @@ var TELEMETRY_VIEW = [
3099
3101
  { stage: "first-tts-chunk", key: "telFirstChunk" },
3100
3102
  { stage: "first-audio-played", key: "telFirstPlayed" }
3101
3103
  ];
3102
- var BUILD_TAG = "b51f379";
3104
+ var BUILD_TAG = "b05db39";
3103
3105
  var TELEMETRY_FLAG = "dsh-voice-mode.telemetry";
3104
3106
  var telemetryEnabled = typeof localStorage !== "undefined" && localStorage.getItem(TELEMETRY_FLAG) === "1";
3105
3107
  console.log("[dsh-voice] build=" + BUILD_TAG);
package/lib/index.js CHANGED
@@ -1313,6 +1313,13 @@ var probeNode = (command, env) => {
1313
1313
  }
1314
1314
  };
1315
1315
  var NATIVE_RUNTIME_UNAVAILABLE = 'Local Kokoro cannot run inside the Electron-based desktop host (native add-on blocked: "External buffers are not allowed"). Install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge or VITS.';
1316
+ var NativeRuntimeUnavailableError = class extends Error {
1317
+ code = "kokoro_needs_node";
1318
+ constructor() {
1319
+ super(NATIVE_RUNTIME_UNAVAILABLE);
1320
+ this.name = "NativeRuntimeUnavailableError";
1321
+ }
1322
+ };
1316
1323
  var cached;
1317
1324
  function resolveNativeRuntime(opts = {}) {
1318
1325
  const env = opts.env ?? process.env;
@@ -1660,6 +1667,7 @@ function createSherpaLocalEngine(options) {
1660
1667
  let ready = null;
1661
1668
  let engineLoading = false;
1662
1669
  let engineError;
1670
+ let engineErrorCode;
1663
1671
  let nextId = 1;
1664
1672
  const pending = /* @__PURE__ */ new Map();
1665
1673
  const call = (msg) => new Promise((resolve, reject) => {
@@ -1681,6 +1689,7 @@ function createSherpaLocalEngine(options) {
1681
1689
  ready = (async () => {
1682
1690
  engineLoading = true;
1683
1691
  engineError = void 0;
1692
+ engineErrorCode = void 0;
1684
1693
  downloadProgress = null;
1685
1694
  try {
1686
1695
  if (!child || !childInit) {
@@ -1708,7 +1717,7 @@ function createSherpaLocalEngine(options) {
1708
1717
  }
1709
1718
  if (!child) {
1710
1719
  const runtime = options.kind === "kokoro" ? resolveNativeRuntime() : { env: process.env };
1711
- if (!runtime) throw new Error(NATIVE_RUNTIME_UNAVAILABLE);
1720
+ if (!runtime) throw new NativeRuntimeUnavailableError();
1712
1721
  child = fork(workerPath, [], {
1713
1722
  stdio: ["ignore", "ignore", "pipe", "ipc"],
1714
1723
  ...runtime.execPath ? { execPath: runtime.execPath, env: runtime.env } : {}
@@ -1754,6 +1763,7 @@ function createSherpaLocalEngine(options) {
1754
1763
  broadcast("tts-ready", { engine: options.kind, worker: true });
1755
1764
  } catch (e) {
1756
1765
  engineError = e instanceof Error ? e.message : String(e);
1766
+ engineErrorCode = e instanceof NativeRuntimeUnavailableError ? e.code : void 0;
1757
1767
  throw e;
1758
1768
  } finally {
1759
1769
  engineLoading = false;
@@ -1790,6 +1800,7 @@ function createSherpaLocalEngine(options) {
1790
1800
  ready: childInit === true,
1791
1801
  loading: engineLoading,
1792
1802
  error: engineError,
1803
+ errorCode: engineErrorCode,
1793
1804
  progress: downloadProgress ?? void 0,
1794
1805
  local: {
1795
1806
  repo: repoName,
@@ -2064,6 +2075,7 @@ var en = {
2064
2075
  engineLoading: "loading\u2026",
2065
2076
  engineReady: "ready",
2066
2077
  engineError: "failed",
2078
+ errKokoroNeedsNode: "Local Kokoro cannot run directly inside the official desktop app (Electron): install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge / local VITS.",
2067
2079
  ttsModelsMissing: "local models missing",
2068
2080
  ttsDownload: "Download",
2069
2081
  ttsDelete: "Delete",
@@ -2284,7 +2296,7 @@ var name = "voice-mode";
2284
2296
  var NS_VOICE_MODE = "voice-mode";
2285
2297
  var BASE_PATH = "/voice-mode";
2286
2298
  var PREVIEW_NETWORK_PATTERN = /fetch failed|ECONN|ENOTFOUND|getaddrinfo|ETIMEDOUT|EAI_AGAIN|network|unreachable|socket hang up|aborted/i;
2287
- var PREVIEW_ENGINE_PATTERN = /model download|model verify|init failed|child exited|tts child|local TTS|prepare|sherpa/i;
2299
+ var PREVIEW_ENGINE_PATTERN = /model download|model verify|init failed|child exited|tts child|local TTS|prepare|sherpa|local Kokoro/i;
2288
2300
  var PREVIEW_TEXT_PATTERN = /empty or invalid audio|invalid audio|invalid text|too long|truncat/i;
2289
2301
  function classifyPreviewError(msg) {
2290
2302
  if (PREVIEW_TEXT_PATTERN.test(msg)) return "text";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-voice-mode",
3
3
  "description": "Full-duplex voice plugin for DeepSeek Harness: local zipformer2 streaming ASR (no API key) → editable draft; Edge TTS or local VITS / Kokoro read-aloud with live captions; true barge-in; hardened HTTP surface + model SHA256 pinning; compatible with all dsh releases since 0.1.1-rc.2 (verified 0.1.1-rc.2 → 0.2.0-rc.2).",
4
4
  "icon": "./icon.svg",
5
- "version": "0.7.21",
5
+ "version": "0.7.22",
6
6
  "type": "module",
7
7
  "main": "lib/index.js",
8
8
  "repository": {