open-agents-ai 0.187.564 → 0.187.565

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/dist/index.js CHANGED
@@ -563826,10 +563826,21 @@ __export(voice_exports, {
563826
563826
  registerCustomOnnxModel: () => registerCustomOnnxModel,
563827
563827
  resetNarrationContext: () => resetNarrationContext
563828
563828
  });
563829
- import { existsSync as existsSync87, mkdirSync as mkdirSync49, writeFileSync as writeFileSync46, readFileSync as readFileSync71, unlinkSync as unlinkSync17, readdirSync as readdirSync25, statSync as statSync28 } from "node:fs";
563829
+ import {
563830
+ existsSync as existsSync87,
563831
+ mkdirSync as mkdirSync49,
563832
+ writeFileSync as writeFileSync46,
563833
+ readFileSync as readFileSync71,
563834
+ unlinkSync as unlinkSync17,
563835
+ readdirSync as readdirSync25,
563836
+ statSync as statSync28
563837
+ } from "node:fs";
563830
563838
  import { join as join104, dirname as dirname30 } from "node:path";
563831
563839
  import { homedir as homedir32, tmpdir as tmpdir20, platform as platform5 } from "node:os";
563832
- import { execSync as execSync51, spawn as nodeSpawn } from "node:child_process";
563840
+ import {
563841
+ execSync as execSync51,
563842
+ spawn as nodeSpawn
563843
+ } from "node:child_process";
563833
563844
  import { createRequire as createRequire4 } from "node:module";
563834
563845
  function sanitizeForTTS(text) {
563835
563846
  return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
@@ -563902,7 +563913,12 @@ function normalizeSupertonicSettings(value2) {
563902
563913
  voiceName: SUPERTONIC_VOICES.includes(String(v.voiceName ?? "")) ? String(v.voiceName) : DEFAULT_SUPERTONIC_SETTINGS.voiceName,
563903
563914
  lang: SUPERTONIC_LANGS.includes(String(v.lang ?? "")) ? String(v.lang) : DEFAULT_SUPERTONIC_SETTINGS.lang,
563904
563915
  speed: clampFloat(v.speed, DEFAULT_SUPERTONIC_SETTINGS.speed, 0.7, 1.8),
563905
- totalStep: clampInt(v.totalStep, DEFAULT_SUPERTONIC_SETTINGS.totalStep, 4, 16),
563916
+ totalStep: clampInt(
563917
+ v.totalStep,
563918
+ DEFAULT_SUPERTONIC_SETTINGS.totalStep,
563919
+ 4,
563920
+ 16
563921
+ ),
563906
563922
  expression: isSupertonicExpression(v.expression) ? v.expression : DEFAULT_SUPERTONIC_SETTINGS.expression
563907
563923
  };
563908
563924
  }
@@ -564100,7 +564116,9 @@ function extractToolObject(toolName, args) {
564100
564116
  case "sub_agent": {
564101
564117
  const topic = extractSubAgentTopic(args);
564102
564118
  if (topic) return topic;
564103
- const agentType = String(args["subagent_type"] ?? args["type"] ?? "").replace(/-/g, " ");
564119
+ const agentType = String(
564120
+ args["subagent_type"] ?? args["type"] ?? ""
564121
+ ).replace(/-/g, " ");
564104
564122
  return agentType || "sub agent";
564105
564123
  }
564106
564124
  case "batch_edit":
@@ -564176,7 +564194,11 @@ function extractToolVerb(toolName, args) {
564176
564194
  return ["examining", "looking at", "examined"];
564177
564195
  default: {
564178
564196
  const readable = toolName.replace(/[_-]/g, " ");
564179
- return [`invoking ${readable}`, `calling ${readable}`, `invoked ${readable}`];
564197
+ return [
564198
+ `invoking ${readable}`,
564199
+ `calling ${readable}`,
564200
+ `invoked ${readable}`
564201
+ ];
564180
564202
  }
564181
564203
  }
564182
564204
  }
@@ -564272,13 +564294,16 @@ function extractShellEssence(cmd) {
564272
564294
  if (npmTest) return "running tests";
564273
564295
  const npmBuild = cmd.match(/npm\s+run\s+(\S+)/);
564274
564296
  if (npmBuild) return `running ${npmBuild[1]}`;
564275
- const gitCmd = cmd.match(/git\s+(commit|push|pull|merge|rebase|checkout|diff|status|log|stash|add)\b/);
564297
+ const gitCmd = cmd.match(
564298
+ /git\s+(commit|push|pull|merge|rebase|checkout|diff|status|log|stash|add)\b/
564299
+ );
564276
564300
  if (gitCmd) return `git ${gitCmd[1]}`;
564277
564301
  if (/npm\s+publish/.test(cmd)) return "publishing to npm";
564278
564302
  const nodeScript = cmd.match(/(?:node|tsx?)\s+(\S+)/);
564279
564303
  if (nodeScript) return `running ${nodeScript[1].split("/").pop()}`;
564280
564304
  const curlUrl = cmd.match(/curl\s+.*?(https?:\/\/\S{10,40})/);
564281
- if (curlUrl) return `fetching ${curlUrl[1].replace(/https?:\/\//, "").split("/")[0]}`;
564305
+ if (curlUrl)
564306
+ return `fetching ${curlUrl[1].replace(/https?:\/\//, "").split("/")[0]}`;
564282
564307
  const pnpm = cmd.match(/pnpm\s+(-r\s+)?(\S+)/);
564283
564308
  if (pnpm) return `pnpm ${pnpm[1] || ""}${pnpm[2]}`.trim();
564284
564309
  return "";
@@ -564336,10 +564361,8 @@ function computeStateInterjection(quadrant, stark) {
564336
564361
  return "";
564337
564362
  }
564338
564363
  case 2: {
564339
- if (errCount >= 3)
564340
- return `${errCount} consecutive errors now. `;
564341
- if (errCount === 2)
564342
- return `Second failure in a row. `;
564364
+ if (errCount >= 3) return `${errCount} consecutive errors now. `;
564365
+ if (errCount === 2) return `Second failure in a row. `;
564343
564366
  if (totalErrors >= 5)
564344
564367
  return `${totalErrors} errors this session, pushing through. `;
564345
564368
  if (totalErrors >= 2 && totalCalls > 5)
@@ -564351,21 +564374,17 @@ function computeStateInterjection(quadrant, stark) {
564351
564374
  return `${totalCalls} operations, zero errors. `;
564352
564375
  if (uniqueFiles >= 4 && totalErrors === 0)
564353
564376
  return `${uniqueFiles} files, all clean. `;
564354
- if (streak >= 5)
564355
- return `Steady, ${streak} clean operations. `;
564377
+ if (streak >= 5) return `Steady, ${streak} clean operations. `;
564356
564378
  if (totalCalls > 8 && errCount === 0)
564357
564379
  return `Smooth at step ${totalCalls}. `;
564358
564380
  return "";
564359
564381
  }
564360
564382
  case 4: {
564361
- if (uniqueFiles >= 6)
564362
- return `${uniqueFiles} files in play. `;
564383
+ if (uniqueFiles >= 6) return `${uniqueFiles} files in play. `;
564363
564384
  if (totalErrors > 0 && errCount === 0)
564364
564385
  return `Past ${totalErrors} error${totalErrors > 1 ? "s" : ""}, being careful. `;
564365
- if (sameToolCount >= 4)
564366
- return `Pass ${sameToolCount} on this file. `;
564367
- if (totalCalls > 10)
564368
- return `Step ${totalCalls}, measured pace. `;
564386
+ if (sameToolCount >= 4) return `Pass ${sameToolCount} on this file. `;
564387
+ if (totalCalls > 10) return `Step ${totalCalls}, measured pace. `;
564369
564388
  return "";
564370
564389
  }
564371
564390
  default:
@@ -564422,8 +564441,11 @@ function extractResultDigest(toolName, content) {
564422
564441
  const nuggets = [];
564423
564442
  const ethMatch = text.match(/([\d.]+)\s*ETH/i);
564424
564443
  if (ethMatch) nuggets.push(`${ethMatch[1]} ETH`);
564425
- const tokenMatch = text.match(/([\d,.]+)\s*(USDC|USDT|DAI|BTC|SOL|MATIC|tokens?)\b/i);
564426
- if (tokenMatch && !nuggets.length) nuggets.push(`${tokenMatch[1]} ${tokenMatch[2]}`);
564444
+ const tokenMatch = text.match(
564445
+ /([\d,.]+)\s*(USDC|USDT|DAI|BTC|SOL|MATIC|tokens?)\b/i
564446
+ );
564447
+ if (tokenMatch && !nuggets.length)
564448
+ nuggets.push(`${tokenMatch[1]} ${tokenMatch[2]}`);
564427
564449
  const addrMatch = text.match(/(0x[0-9a-fA-F]{8})[0-9a-fA-F]+/);
564428
564450
  if (addrMatch) nuggets.push(`address ${addrMatch[1]}...`);
564429
564451
  const httpMatch = text.match(/(?:status|code)[:\s]*(\d{3})\b/i);
@@ -564438,7 +564460,9 @@ function extractResultDigest(toolName, content) {
564438
564460
  }
564439
564461
  const errMatch = text.match(/(?:error|Error|ERROR)[:\s]+(.{5,50}?)(?:\n|$)/);
564440
564462
  if (errMatch) nuggets.push(`error: ${errMatch[1].trim()}`);
564441
- const statusMatch = text.match(/\[(running|complete|completed|failed|pending|success|stopped|error)\]/i);
564463
+ const statusMatch = text.match(
564464
+ /\[(running|complete|completed|failed|pending|success|stopped|error)\]/i
564465
+ );
564442
564466
  if (statusMatch) nuggets.push(statusMatch[1].toLowerCase());
564443
564467
  const versionMatch = text.match(/\bv?(\d+\.\d+\.\d+)\b/);
564444
564468
  if (versionMatch && !nuggets.some((n2) => n2.includes(versionMatch[1]))) {
@@ -564451,7 +564475,8 @@ function extractResultDigest(toolName, content) {
564451
564475
  const gasMatch = text.match(/gas[:\s]*([\d,]+)/i);
564452
564476
  if (gasMatch) nuggets.push(`gas ${gasMatch[1]}`);
564453
564477
  const exitMatch = text.match(/exit\s*(?:code)?[:\s]*(\d+)/i);
564454
- if (exitMatch && exitMatch[1] !== "0") nuggets.push(`exit code ${exitMatch[1]}`);
564478
+ if (exitMatch && exitMatch[1] !== "0")
564479
+ nuggets.push(`exit code ${exitMatch[1]}`);
564455
564480
  if (nuggets.length === 0) {
564456
564481
  const contentDigest = extractContentSummary(text, toolName);
564457
564482
  if (contentDigest) nuggets.push(contentDigest);
@@ -564460,7 +564485,10 @@ function extractResultDigest(toolName, content) {
564460
564485
  return digest3.length > 100 ? digest3.slice(0, 97) + "..." : digest3;
564461
564486
  }
564462
564487
  function extractContentSummary(text, toolName) {
564463
- let cleaned = text.replace(/^\s*\d+[│|:→]\s*/gm, "").replace(/\d{4}-\d{2}-\d{2}T[\d:.]+Z?\s*/g, "").replace(/^[\s*#=-]+$/gm, "").replace(/```[\s\S]*?```/g, "").replace(/^\s*(import|export|const|let|var|function|class|interface|type)\s/gm, "").replace(/[{}()\[\];]/g, "").trim();
564488
+ let cleaned = text.replace(/^\s*\d+[│|:→]\s*/gm, "").replace(/\d{4}-\d{2}-\d{2}T[\d:.]+Z?\s*/g, "").replace(/^[\s*#=-]+$/gm, "").replace(/```[\s\S]*?```/g, "").replace(
564489
+ /^\s*(import|export|const|let|var|function|class|interface|type)\s/gm,
564490
+ ""
564491
+ ).replace(/[{}()\[\];]/g, "").trim();
564464
564492
  const lines = cleaned.split("\n").map((l2) => l2.trim()).filter((l2) => l2.length > 10);
564465
564493
  for (const line of lines) {
564466
564494
  const wordChars = line.replace(/[^a-zA-Z\s]/g, "").trim();
@@ -564479,7 +564507,9 @@ function extractContentSummary(text, toolName) {
564479
564507
  return summary;
564480
564508
  }
564481
564509
  if (toolName === "sub_agent") {
564482
- const summaryMatch = text.match(/(?:summary|created|completed|result)[:\s]+(.{10,80}?)(?:\n|$)/i);
564510
+ const summaryMatch = text.match(
564511
+ /(?:summary|created|completed|result)[:\s]+(.{10,80}?)(?:\n|$)/i
564512
+ );
564483
564513
  if (summaryMatch) {
564484
564514
  let s2 = summaryMatch[1].trim();
564485
564515
  if (s2.length > 0) s2 = s2.charAt(0).toLowerCase() + s2.slice(1);
@@ -564660,8 +564690,51 @@ var init_voice = __esm({
564660
564690
  supertonicLang: "en"
564661
564691
  }
564662
564692
  };
564663
- SUPERTONIC_LANGS = ["en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi"];
564664
- SUPERTONIC_VOICES = ["M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5"];
564693
+ SUPERTONIC_LANGS = [
564694
+ "en",
564695
+ "ko",
564696
+ "ja",
564697
+ "ar",
564698
+ "bg",
564699
+ "cs",
564700
+ "da",
564701
+ "de",
564702
+ "el",
564703
+ "es",
564704
+ "et",
564705
+ "fi",
564706
+ "fr",
564707
+ "hi",
564708
+ "hr",
564709
+ "hu",
564710
+ "id",
564711
+ "it",
564712
+ "lt",
564713
+ "lv",
564714
+ "nl",
564715
+ "pl",
564716
+ "pt",
564717
+ "ro",
564718
+ "ru",
564719
+ "sk",
564720
+ "sl",
564721
+ "sv",
564722
+ "tr",
564723
+ "uk",
564724
+ "vi"
564725
+ ];
564726
+ SUPERTONIC_VOICES = [
564727
+ "M1",
564728
+ "M2",
564729
+ "M3",
564730
+ "M4",
564731
+ "M5",
564732
+ "F1",
564733
+ "F2",
564734
+ "F3",
564735
+ "F4",
564736
+ "F5"
564737
+ ];
564665
564738
  DEFAULT_SUPERTONIC_SETTINGS = {
564666
564739
  voiceName: "M4",
564667
564740
  lang: "en",
@@ -564754,7 +564827,9 @@ except Exception as exc:
564754
564827
  /** True when current model uses Supertonic3 backend */
564755
564828
  supertonicActive = false;
564756
564829
  supertonicInstalled = null;
564757
- supertonicSettings = { ...DEFAULT_SUPERTONIC_SETTINGS };
564830
+ supertonicSettings = {
564831
+ ...DEFAULT_SUPERTONIC_SETTINGS
564832
+ };
564758
564833
  /** Whether LuxTTS voice-clone backend is currently active */
564759
564834
  get isLuxtts() {
564760
564835
  return this.luxttsActive;
@@ -564835,17 +564910,25 @@ except Exception as exc:
564835
564910
  const b = VOICE_MODELS[k].backend;
564836
564911
  return !b || b === "onnx";
564837
564912
  });
564838
- const mlxModels = Object.keys(VOICE_MODELS).filter((k) => VOICE_MODELS[k].backend === "mlx");
564839
- const luxttsModels = Object.keys(VOICE_MODELS).filter((k) => VOICE_MODELS[k].backend === "luxtts");
564840
- const supertonicModels = Object.keys(VOICE_MODELS).filter((k) => VOICE_MODELS[k].backend === "supertonic");
564913
+ const mlxModels = Object.keys(VOICE_MODELS).filter(
564914
+ (k) => VOICE_MODELS[k].backend === "mlx"
564915
+ );
564916
+ const luxttsModels = Object.keys(VOICE_MODELS).filter(
564917
+ (k) => VOICE_MODELS[k].backend === "luxtts"
564918
+ );
564919
+ const supertonicModels = Object.keys(VOICE_MODELS).filter(
564920
+ (k) => VOICE_MODELS[k].backend === "supertonic"
564921
+ );
564841
564922
  let msg = `Unknown voice model: "${id}". Available:`;
564842
564923
  msg += `
564843
564924
  ONNX: ${onnxModels.join(", ")}`;
564844
564925
  if (mlxModels.length) msg += `
564845
564926
  MLX (macOS): ${mlxModels.join(", ")}`;
564846
- if (luxttsModels.length) msg += `
564927
+ if (luxttsModels.length)
564928
+ msg += `
564847
564929
  LuxTTS (voice clone): ${luxttsModels.join(", ")}`;
564848
- if (supertonicModels.length) msg += `
564930
+ if (supertonicModels.length)
564931
+ msg += `
564849
564932
  Supertonic3: ${supertonicModels.join(", ")}`;
564850
564933
  return msg;
564851
564934
  }
@@ -564996,7 +565079,15 @@ except Exception as exc:
564996
565079
  writeFileSync46(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
564997
565080
  }
564998
565081
  /** Audio file extensions recognized as clone references */
564999
- static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
565082
+ static AUDIO_EXTS = /* @__PURE__ */ new Set([
565083
+ "wav",
565084
+ "mp3",
565085
+ "ogg",
565086
+ "flac",
565087
+ "m4a",
565088
+ "opus",
565089
+ "aac"
565090
+ ]);
565000
565091
  /**
565001
565092
  * List all clone reference audio files with metadata.
565002
565093
  * Returns array of { filename, path, name, size, isActive }.
@@ -565099,7 +565190,13 @@ except Exception as exc:
565099
565190
  return;
565100
565191
  }
565101
565192
  for (const chunk of chunks) {
565102
- this.speakQueue.push({ text: chunk, volume, pitchFactor, speedFactor, stereoDelayMs });
565193
+ this.speakQueue.push({
565194
+ text: chunk,
565195
+ volume,
565196
+ pitchFactor,
565197
+ speedFactor,
565198
+ stereoDelayMs
565199
+ });
565103
565200
  }
565104
565201
  if (!this.speaking) {
565105
565202
  this.drainQueue().catch(() => {
@@ -565329,10 +565426,18 @@ except Exception as exc:
565329
565426
  );
565330
565427
  }
565331
565428
  if (!wavPath) {
565332
- wavPath = await this.synthesizeLuxttsWav(item.text, item.speedFactor);
565429
+ wavPath = await this.synthesizeLuxttsWav(
565430
+ item.text,
565431
+ item.speedFactor
565432
+ );
565333
565433
  }
565334
565434
  if (wavPath) {
565335
- await this.postProcessAndPlayLuxtts(wavPath, item.volume, item.pitchFactor, item.stereoDelayMs);
565435
+ await this.postProcessAndPlayLuxtts(
565436
+ wavPath,
565437
+ item.volume,
565438
+ item.pitchFactor,
565439
+ item.stereoDelayMs
565440
+ );
565336
565441
  }
565337
565442
  if (prefetchPromise && nextItem) {
565338
565443
  try {
@@ -565344,7 +565449,13 @@ except Exception as exc:
565344
565449
  }
565345
565450
  }
565346
565451
  } else {
565347
- await this.synthesizeAndPlay(item.text, item.volume, item.pitchFactor, item.speedFactor, item.stereoDelayMs);
565452
+ await this.synthesizeAndPlay(
565453
+ item.text,
565454
+ item.volume,
565455
+ item.pitchFactor,
565456
+ item.speedFactor,
565457
+ item.stereoDelayMs
565458
+ );
565348
565459
  }
565349
565460
  } catch {
565350
565461
  }
@@ -565373,11 +565484,23 @@ except Exception as exc:
565373
565484
  // -------------------------------------------------------------------------
565374
565485
  async synthesizeAndPlay(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
565375
565486
  if (this.luxttsActive) {
565376
- await this.synthesizeWithLuxtts(text, volume, pitchFactor, speedFactor, stereoDelayMs);
565487
+ await this.synthesizeWithLuxtts(
565488
+ text,
565489
+ volume,
565490
+ pitchFactor,
565491
+ speedFactor,
565492
+ stereoDelayMs
565493
+ );
565377
565494
  return;
565378
565495
  }
565379
565496
  if (this.supertonicActive) {
565380
- await this.synthesizeWithSupertonic(text, volume, pitchFactor, speedFactor, stereoDelayMs);
565497
+ await this.synthesizeWithSupertonic(
565498
+ text,
565499
+ volume,
565500
+ pitchFactor,
565501
+ speedFactor,
565502
+ stereoDelayMs
565503
+ );
565381
565504
  return;
565382
565505
  }
565383
565506
  if (this.mlxActive) {
@@ -565552,9 +565675,15 @@ except Exception as exc:
565552
565675
  for (let i2 = 0; i2 < numSamples; i2++) {
565553
565676
  const lSample = Math.max(-1, Math.min(1, left[i2]));
565554
565677
  const rSample = Math.max(-1, Math.min(1, right[i2]));
565555
- buffer2.writeInt16LE(lSample < 0 ? lSample * 32768 : lSample * 32767, pos);
565678
+ buffer2.writeInt16LE(
565679
+ lSample < 0 ? lSample * 32768 : lSample * 32767,
565680
+ pos
565681
+ );
565556
565682
  pos += 2;
565557
- buffer2.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
565683
+ buffer2.writeInt16LE(
565684
+ rSample < 0 ? rSample * 32768 : rSample * 32767,
565685
+ pos
565686
+ );
565558
565687
  pos += 2;
565559
565688
  }
565560
565689
  writeFileSync46(path11, buffer2);
@@ -565575,7 +565704,9 @@ except Exception as exc:
565575
565704
  const phonemes = await this.phonemizeFn(text, voice);
565576
565705
  const phonemeText = Array.isArray(phonemes) ? phonemes.join(" ") : String(phonemes || text);
565577
565706
  const sentences = phonemeText.split(/[.!?]+/).filter((s2) => s2.trim().length > 0);
565578
- return sentences.map((sentence) => Array.from(sentence.trim().normalize("NFD")));
565707
+ return sentences.map(
565708
+ (sentence) => Array.from(sentence.trim().normalize("NFD"))
565709
+ );
565579
565710
  }
565580
565711
  /**
565581
565712
  * Convert phoneme character arrays to integer IDs using the model's phoneme_id_map.
@@ -565627,7 +565758,10 @@ except Exception as exc:
565627
565758
  buffer2.writeUInt16LE(bitsPerSample, 34);
565628
565759
  buffer2.write("data", 36);
565629
565760
  buffer2.writeUInt32LE(dataSize, 40);
565630
- Buffer.from(int16.buffer, int16.byteOffset, int16.byteLength).copy(buffer2, 44);
565761
+ Buffer.from(int16.buffer, int16.byteOffset, int16.byteLength).copy(
565762
+ buffer2,
565763
+ 44
565764
+ );
565631
565765
  return buffer2;
565632
565766
  }
565633
565767
  writeWav(samples, sampleRate, path11) {
@@ -565703,7 +565837,9 @@ except Exception as exc:
565703
565837
  setSupertonicSettings(patch) {
565704
565838
  const current = this.getSupertonicSettings();
565705
565839
  const next = {
565706
- voiceName: SUPERTONIC_VOICES.includes(String(patch.voiceName ?? current.voiceName)) ? String(patch.voiceName ?? current.voiceName) : current.voiceName,
565840
+ voiceName: SUPERTONIC_VOICES.includes(
565841
+ String(patch.voiceName ?? current.voiceName)
565842
+ ) ? String(patch.voiceName ?? current.voiceName) : current.voiceName,
565707
565843
  lang: SUPERTONIC_LANGS.includes(String(patch.lang ?? current.lang)) ? String(patch.lang ?? current.lang) : current.lang,
565708
565844
  speed: clampFloat(patch.speed, current.speed, 0.7, 1.8),
565709
565845
  totalStep: clampInt(patch.totalStep, current.totalStep, 4, 16),
@@ -565717,7 +565853,10 @@ except Exception as exc:
565717
565853
  }
565718
565854
  listSupertonicProfiles() {
565719
565855
  const store2 = this.loadSupertonicStore();
565720
- return Object.entries(store2.profiles).map(([name10, settings]) => ({ name: name10, settings }));
565856
+ return Object.entries(store2.profiles).map(([name10, settings]) => ({
565857
+ name: name10,
565858
+ settings
565859
+ }));
565721
565860
  }
565722
565861
  saveSupertonicProfile(name10) {
565723
565862
  const clean3 = name10.trim().replace(/[^a-zA-Z0-9_.-]/g, "-");
@@ -565744,7 +565883,9 @@ except Exception as exc:
565744
565883
  }
565745
565884
  loadSupertonicStore() {
565746
565885
  try {
565747
- const raw = JSON.parse(readFileSync71(supertonicProfilesFile(), "utf-8"));
565886
+ const raw = JSON.parse(
565887
+ readFileSync71(supertonicProfilesFile(), "utf-8")
565888
+ );
565748
565889
  const profiles = {};
565749
565890
  for (const [name10, settings] of Object.entries(raw.profiles ?? {})) {
565750
565891
  profiles[name10] = normalizeSupertonicSettings(settings);
@@ -565759,12 +565900,18 @@ except Exception as exc:
565759
565900
  }
565760
565901
  saveSupertonicStore(store2) {
565761
565902
  mkdirSync49(voiceDir(), { recursive: true });
565762
- writeFileSync46(supertonicProfilesFile(), JSON.stringify(store2, null, 2), "utf-8");
565903
+ writeFileSync46(
565904
+ supertonicProfilesFile(),
565905
+ JSON.stringify(store2, null, 2),
565906
+ "utf-8"
565907
+ );
565763
565908
  }
565764
565909
  async ensureSupertonic() {
565765
565910
  const py = await this.findPython3Async();
565766
565911
  if (!py) {
565767
- throw new Error("python3 not found. Install Python 3.10+ to use Supertonic3.");
565912
+ throw new Error(
565913
+ "python3 not found. Install Python 3.10+ to use Supertonic3."
565914
+ );
565768
565915
  }
565769
565916
  const venvDir = supertonicVenvDir();
565770
565917
  const venvPy = supertonicVenvPy();
@@ -565774,8 +565921,14 @@ except Exception as exc:
565774
565921
  }
565775
565922
  if (!this.checkSupertonicInstalled()) {
565776
565923
  renderInfo2("Installing Supertonic3 TTS (first-time setup)...");
565777
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet --upgrade pip`, 12e4);
565778
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet supertonic`, 6e5);
565924
+ await this.asyncShell(
565925
+ `${JSON.stringify(venvPy)} -m pip install --quiet --upgrade pip`,
565926
+ 12e4
565927
+ );
565928
+ await this.asyncShell(
565929
+ `${JSON.stringify(venvPy)} -m pip install --quiet supertonic`,
565930
+ 6e5
565931
+ );
565779
565932
  this.supertonicInstalled = true;
565780
565933
  }
565781
565934
  this.writeSupertonicInferScript();
@@ -565788,7 +565941,10 @@ except Exception as exc:
565788
565941
  return false;
565789
565942
  }
565790
565943
  try {
565791
- execSync51(`${JSON.stringify(venvPy)} -c "import supertonic"`, { stdio: "pipe", timeout: 1e4 });
565944
+ execSync51(`${JSON.stringify(venvPy)} -c "import supertonic"`, {
565945
+ stdio: "pipe",
565946
+ timeout: 1e4
565947
+ });
565792
565948
  this.supertonicInstalled = true;
565793
565949
  return true;
565794
565950
  } catch {
@@ -565813,7 +565969,11 @@ except Exception as exc:
565813
565969
  child.kill("SIGKILL");
565814
565970
  } catch {
565815
565971
  }
565816
- reject(new Error(`Supertonic3 synthesis timed out after ${Math.round(timeoutMs / 1e3)}s`));
565972
+ reject(
565973
+ new Error(
565974
+ `Supertonic3 synthesis timed out after ${Math.round(timeoutMs / 1e3)}s`
565975
+ )
565976
+ );
565817
565977
  }, timeoutMs);
565818
565978
  child.stdout?.on("data", (d2) => {
565819
565979
  stdout += d2.toString();
@@ -565830,10 +565990,22 @@ except Exception as exc:
565830
565990
  const line = stdout.trim().split("\n").pop() ?? "";
565831
565991
  try {
565832
565992
  const parsed = JSON.parse(line);
565833
- if (parsed.ok === false) reject(new Error(String(parsed.error ?? (stderr || "Supertonic3 failed"))));
565993
+ if (parsed.ok === false)
565994
+ reject(
565995
+ new Error(
565996
+ String(parsed.error ?? (stderr || "Supertonic3 failed"))
565997
+ )
565998
+ );
565834
565999
  else resolve43(parsed);
565835
566000
  } catch {
565836
- reject(new Error((stderr || stdout || "Supertonic3 returned no JSON").slice(0, 500)));
566001
+ reject(
566002
+ new Error(
566003
+ (stderr || stdout || "Supertonic3 returned no JSON").slice(
566004
+ 0,
566005
+ 500
566006
+ )
566007
+ )
566008
+ );
565837
566009
  }
565838
566010
  });
565839
566011
  child.stdin?.end(JSON.stringify(req2));
@@ -565842,9 +566014,15 @@ except Exception as exc:
565842
566014
  async synthesizeSupertonicWav(text, speedFactor = 1) {
565843
566015
  await this.ensureSupertonic();
565844
566016
  const settings = this.getSupertonicSettings();
565845
- const cleaned = applySupertonicExpression(text.replace(/\*/g, "").trim(), settings.expression);
566017
+ const cleaned = applySupertonicExpression(
566018
+ text.replace(/\*/g, "").trim(),
566019
+ settings.expression
566020
+ );
565846
566021
  if (!cleaned) return null;
565847
- const wavPath = join104(tmpdir20(), `oa-supertonic3-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
566022
+ const wavPath = join104(
566023
+ tmpdir20(),
566024
+ `oa-supertonic3-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`
566025
+ );
565848
566026
  try {
565849
566027
  await this.supertonicRequest({
565850
566028
  text: cleaned,
@@ -565862,7 +566040,12 @@ except Exception as exc:
565862
566040
  async synthesizeWithSupertonic(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
565863
566041
  const wavPath = await this.synthesizeSupertonicWav(text, speedFactor);
565864
566042
  if (!wavPath) return;
565865
- await this.postProcessAndPlayLuxtts(wavPath, volume, pitchFactor, stereoDelayMs);
566043
+ await this.postProcessAndPlayLuxtts(
566044
+ wavPath,
566045
+ volume,
566046
+ pitchFactor,
566047
+ stereoDelayMs
566048
+ );
565866
566049
  }
565867
566050
  async synthesizeSupertonicToBuffer(text) {
565868
566051
  const wavPath = await this.synthesizeSupertonicWav(text, 1);
@@ -565950,7 +566133,10 @@ except Exception as exc:
565950
566133
  return false;
565951
566134
  }
565952
566135
  try {
565953
- execSync51(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
566136
+ execSync51(`${py} -c "import mlx_audio"`, {
566137
+ stdio: "pipe",
566138
+ timeout: 1e4
566139
+ });
565954
566140
  this.mlxInstalled = true;
565955
566141
  return true;
565956
566142
  } catch {
@@ -565981,7 +566167,10 @@ except Exception as exc:
565981
566167
  this.mlxInstalled = true;
565982
566168
  } catch (err) {
565983
566169
  try {
565984
- await this.asyncShell(`${py} -m pip install mlx-audio --user --quiet`, 3e5);
566170
+ await this.asyncShell(
566171
+ `${py} -m pip install mlx-audio --user --quiet`,
566172
+ 3e5
566173
+ );
565985
566174
  this.mlxInstalled = true;
565986
566175
  } catch (err2) {
565987
566176
  throw new Error(
@@ -566042,7 +566231,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566042
566231
  for (let i2 = 0; i2 < samples.length; i2++) {
566043
566232
  samples[i2] = Math.round(samples[i2] * volume);
566044
566233
  }
566045
- const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
566234
+ const scaled = Buffer.concat([
566235
+ header,
566236
+ Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)
566237
+ ]);
566046
566238
  writeFileSync46(wavPath, scaled);
566047
566239
  }
566048
566240
  } catch {
@@ -566052,7 +566244,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566052
566244
  try {
566053
566245
  const wavData = readFileSync71(wavPath);
566054
566246
  if (wavData.length > 44) {
566055
- const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
566247
+ const pcm = Buffer.from(
566248
+ wavData.buffer,
566249
+ wavData.byteOffset + 44,
566250
+ wavData.length - 44
566251
+ );
566056
566252
  const sampleRate = wavData.readUInt32LE(24);
566057
566253
  this.onPCMOutput(pcm, sampleRate);
566058
566254
  }
@@ -566149,13 +566345,18 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566149
566345
  15e3
566150
566346
  ).then(async (torchCheck) => {
566151
566347
  if (torchCheck === "cpu") {
566152
- renderWarning2("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
566348
+ renderWarning2(
566349
+ "GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background..."
566350
+ );
566153
566351
  try {
566154
566352
  const detectScript = join104(voiceDir(), "detect-torch.py");
566155
566353
  writeDetectTorchScript(detectScript);
566156
566354
  let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
566157
566355
  try {
566158
- const args = await this.asyncShell(`python3 ${JSON.stringify(detectScript)} --pip-args`, 1e4);
566356
+ const args = await this.asyncShell(
566357
+ `python3 ${JSON.stringify(detectScript)} --pip-args`,
566358
+ 1e4
566359
+ );
566159
566360
  if (args.trim()) pipArgs = args.trim();
566160
566361
  } catch {
566161
566362
  }
@@ -566177,11 +566378,16 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566177
566378
  renderWarning2("LuxTTS venv found but import failed. Reinstalling...");
566178
566379
  }
566179
566380
  }
566180
- renderInfo2("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
566381
+ renderInfo2(
566382
+ "Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)..."
566383
+ );
566181
566384
  if (!existsSync87(venvDir)) {
566182
566385
  renderInfo2(" Creating Python virtual environment...");
566183
566386
  try {
566184
- await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
566387
+ await this.asyncShell(
566388
+ `${py} -m venv ${JSON.stringify(venvDir)}`,
566389
+ 6e4
566390
+ );
566185
566391
  } catch (err) {
566186
566392
  throw new Error(
566187
566393
  `Failed to create venv: ${err instanceof Error ? err.message : String(err)}`
@@ -566194,7 +566400,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566194
566400
  let pipArgsStr = "torch torchaudio";
566195
566401
  let torchDesc = "unknown platform";
566196
566402
  try {
566197
- const detectResult = await this.asyncShell(`${py} ${JSON.stringify(detectScript)} --json`, 15e3);
566403
+ const detectResult = await this.asyncShell(
566404
+ `${py} ${JSON.stringify(detectScript)} --json`,
566405
+ 15e3
566406
+ );
566198
566407
  const spec = JSON.parse(detectResult.trim());
566199
566408
  pipArgsStr = spec.pip_args_str || "torch torchaudio";
566200
566409
  torchDesc = spec.description || `${spec.platform} ${spec.arch} ${spec.accelerator}`;
@@ -566255,7 +566464,9 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566255
566464
  const pipCmd = JSON.stringify(venvPy);
566256
566465
  const isArm = process.arch === "arm64" || process.arch === "arm";
566257
566466
  if (isArm) {
566258
- renderInfo2(" ARM device detected — installing build prerequisites then deps individually.");
566467
+ renderInfo2(
566468
+ " ARM device detected — installing build prerequisites then deps individually."
566469
+ );
566259
566470
  const isMac = process.platform === "darwin";
566260
566471
  try {
566261
566472
  const { spawnSync: spawnSync7 } = await import("node:child_process");
@@ -566263,23 +566474,38 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566263
566474
  process.stdout.write("\x1B[?1002l\x1B[?1003l\x1B[?1006l");
566264
566475
  }
566265
566476
  if (isMac) {
566266
- renderInfo2(" macOS ARM detected — installing build deps via Homebrew...");
566267
- const brewCheck = spawnSync7("which", ["brew"], { stdio: "pipe", timeout: 5e3 });
566477
+ renderInfo2(
566478
+ " macOS ARM detected installing build deps via Homebrew..."
566479
+ );
566480
+ const brewCheck = spawnSync7("which", ["brew"], {
566481
+ stdio: "pipe",
566482
+ timeout: 5e3
566483
+ });
566268
566484
  if (brewCheck.status === 0) {
566269
- const brewResult = spawnSync7("brew", ["install", "llvm", "gcc", "openblas", "libsndfile"], {
566270
- stdio: "pipe",
566271
- timeout: 3e5
566272
- });
566485
+ const brewResult = spawnSync7(
566486
+ "brew",
566487
+ ["install", "llvm", "gcc", "openblas", "libsndfile"],
566488
+ {
566489
+ stdio: "pipe",
566490
+ timeout: 3e5
566491
+ }
566492
+ );
566273
566493
  if (brewResult.stdout) process.stdout.write(brewResult.stdout);
566274
566494
  if (brewResult.stderr) {
566275
566495
  const { renderVerbose: renderVerbose2 } = await Promise.resolve().then(() => (init_render2(), render_exports));
566276
566496
  renderVerbose2(brewResult.stderr.toString());
566277
566497
  }
566278
- const llvmPrefix = spawnSync7("brew", ["--prefix", "llvm"], { stdio: "pipe", timeout: 5e3 });
566498
+ const llvmPrefix = spawnSync7("brew", ["--prefix", "llvm"], {
566499
+ stdio: "pipe",
566500
+ timeout: 5e3
566501
+ });
566279
566502
  if (llvmPrefix.stdout) {
566280
566503
  const prefix = llvmPrefix.stdout.toString().trim();
566281
566504
  process.env.LLVM_CONFIG = `${prefix}/bin/llvm-config`;
566282
- const openblas = spawnSync7("brew", ["--prefix", "openblas"], { stdio: "pipe", timeout: 5e3 });
566505
+ const openblas = spawnSync7("brew", ["--prefix", "openblas"], {
566506
+ stdio: "pipe",
566507
+ timeout: 5e3
566508
+ });
566283
566509
  if (openblas.stdout) {
566284
566510
  const obPrefix = openblas.stdout.toString().trim();
566285
566511
  process.env.LDFLAGS = `${process.env.LDFLAGS ?? ""} -L${obPrefix}/lib`.trim();
@@ -566288,32 +566514,47 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566288
566514
  }
566289
566515
  } else {
566290
566516
  renderWarning2(" Homebrew not found. Install it: https://brew.sh");
566291
- renderWarning2(" Then run: brew install llvm gcc openblas libsndfile");
566517
+ renderWarning2(
566518
+ " Then run: brew install llvm gcc openblas libsndfile"
566519
+ );
566292
566520
  }
566293
566521
  } else {
566294
- renderInfo2(" System build tools needed (llvm, gcc). Requesting sudo access...");
566295
- const sudoCheck = spawnSync7("sudo", ["-v"], { stdio: "inherit", timeout: 6e4 });
566522
+ renderInfo2(
566523
+ " System build tools needed (llvm, gcc). Requesting sudo access..."
566524
+ );
566525
+ const sudoCheck = spawnSync7("sudo", ["-v"], {
566526
+ stdio: "inherit",
566527
+ timeout: 6e4
566528
+ });
566296
566529
  if (sudoCheck.status === 0) {
566297
- renderInfo2(" Installing system build dependencies (this may take a minute)...");
566298
- const aptResult = spawnSync7("sudo", [
566299
- "apt-get",
566300
- "install",
566301
- "-y",
566302
- "--no-install-recommends",
566303
- "llvm-dev",
566304
- "gcc",
566305
- "g++",
566306
- "gfortran",
566307
- "libopenblas-dev",
566308
- "libsndfile1-dev"
566309
- ], { stdio: "pipe", timeout: 12e4 });
566530
+ renderInfo2(
566531
+ " Installing system build dependencies (this may take a minute)..."
566532
+ );
566533
+ const aptResult = spawnSync7(
566534
+ "sudo",
566535
+ [
566536
+ "apt-get",
566537
+ "install",
566538
+ "-y",
566539
+ "--no-install-recommends",
566540
+ "llvm-dev",
566541
+ "gcc",
566542
+ "g++",
566543
+ "gfortran",
566544
+ "libopenblas-dev",
566545
+ "libsndfile1-dev"
566546
+ ],
566547
+ { stdio: "pipe", timeout: 12e4 }
566548
+ );
566310
566549
  if (aptResult.stdout) process.stdout.write(aptResult.stdout);
566311
566550
  if (aptResult.stderr) {
566312
566551
  const { renderVerbose: renderVerbose2 } = await Promise.resolve().then(() => (init_render2(), render_exports));
566313
566552
  renderVerbose2(aptResult.stderr.toString());
566314
566553
  }
566315
566554
  } else {
566316
- renderWarning2(" sudo not available — skipping system build deps. librosa/lhotse may fail to compile.");
566555
+ renderWarning2(
566556
+ " sudo not available — skipping system build deps. librosa/lhotse may fail to compile."
566557
+ );
566317
566558
  }
566318
566559
  }
566319
566560
  if (process.stdout.isTTY) {
@@ -566323,14 +566564,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566323
566564
  process.stdout.write("\x1B[?1002l\x1B[?1003l");
566324
566565
  }
566325
566566
  } catch (err) {
566326
- renderWarning2(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
566567
+ renderWarning2(
566568
+ ` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`
566569
+ );
566327
566570
  }
566328
566571
  }
566329
566572
  const isJetson = isArm && (existsSync87("/etc/nv_tegra_release") || existsSync87("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
566330
566573
  const installSteps = isArm ? [
566331
566574
  // ARM: install individually so we get clear error messages per package.
566332
566575
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
566333
- { cmd: `${pipCmd} -m pip install --quiet "setuptools<81" wheel`, fatal: true, label: "setuptools" },
566576
+ {
566577
+ cmd: `${pipCmd} -m pip install --quiet "setuptools<81" wheel`,
566578
+ fatal: true,
566579
+ label: "setuptools"
566580
+ },
566334
566581
  // Jetson: try NVIDIA's prebuilt PyTorch wheel for detected JetPack version.
566335
566582
  // JetPack versions have different PyTorch wheel URLs:
566336
566583
  // JP6.x: https://developer.download.nvidia.com/compute/redist/jp/v60/pytorch/
@@ -566339,46 +566586,119 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566339
566586
  ...isJetson ? (() => {
566340
566587
  let jpVer = "v60";
566341
566588
  try {
566342
- const tegra = existsSync87("/etc/nv_tegra_release") ? execSync51("cat /etc/nv_tegra_release 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim() : "";
566343
- const dpkg = execSync51("dpkg -l nvidia-jetpack 2>/dev/null | grep nvidia-jetpack | awk '{print $3}'", { encoding: "utf8", timeout: 5e3 }).trim();
566589
+ const tegra = existsSync87("/etc/nv_tegra_release") ? execSync51("cat /etc/nv_tegra_release 2>/dev/null", {
566590
+ encoding: "utf8",
566591
+ timeout: 3e3
566592
+ }).trim() : "";
566593
+ const dpkg = execSync51(
566594
+ "dpkg -l nvidia-jetpack 2>/dev/null | grep nvidia-jetpack | awk '{print $3}'",
566595
+ { encoding: "utf8", timeout: 5e3 }
566596
+ ).trim();
566344
566597
  const ver = dpkg || process.env.JETSON_L4T_VERSION || "";
566345
- if (ver.startsWith("5.") || tegra.includes("R35") || tegra.includes("R34")) jpVer = "v51";
566346
- else if (ver.startsWith("6.1") || tegra.includes("R36.4")) jpVer = "v61";
566347
- else if (ver.startsWith("6.") || tegra.includes("R36")) jpVer = "v60";
566598
+ if (ver.startsWith("5.") || tegra.includes("R35") || tegra.includes("R34"))
566599
+ jpVer = "v51";
566600
+ else if (ver.startsWith("6.1") || tegra.includes("R36.4"))
566601
+ jpVer = "v61";
566602
+ else if (ver.startsWith("6.") || tegra.includes("R36"))
566603
+ jpVer = "v60";
566348
566604
  } catch {
566349
566605
  }
566350
566606
  return [
566351
- { cmd: `${pipCmd} -m pip install --quiet torch torchvision torchaudio --index-url https://developer.download.nvidia.com/compute/redist/jp/${jpVer}/pytorch/ 2>/dev/null || ${pipCmd} -m pip install --quiet torch torchaudio`, fatal: true, label: `PyTorch (Jetson JP ${jpVer})` },
566352
- { cmd: `${pipCmd} -m pip install --quiet onnxruntime-gpu 2>/dev/null || true`, fatal: false, label: "onnxruntime-gpu (Jetson, optional)" }
566607
+ {
566608
+ cmd: `${pipCmd} -m pip install --quiet torch torchvision torchaudio --index-url https://developer.download.nvidia.com/compute/redist/jp/${jpVer}/pytorch/ 2>/dev/null || ${pipCmd} -m pip install --quiet torch torchaudio`,
566609
+ fatal: true,
566610
+ label: `PyTorch (Jetson JP ${jpVer})`
566611
+ },
566612
+ {
566613
+ cmd: `${pipCmd} -m pip install --quiet onnxruntime-gpu 2>/dev/null || true`,
566614
+ fatal: false,
566615
+ label: "onnxruntime-gpu (Jetson, optional)"
566616
+ }
566353
566617
  ];
566354
566618
  })() : [
566355
566619
  // Non-Jetson ARM: use default PyPI (has aarch64 wheels).
566356
566620
  // DO NOT use --index-url https://download.pytorch.org/whl/cpu — that index
566357
566621
  // only has x86_64 wheels. ARM needs the standard PyPI torch package.
566358
- { cmd: `${pipCmd} -m pip install --quiet torch torchaudio`, fatal: true, label: "PyTorch (ARM aarch64 from PyPI)" }
566622
+ {
566623
+ cmd: `${pipCmd} -m pip install --quiet torch torchaudio`,
566624
+ fatal: true,
566625
+ label: "PyTorch (ARM aarch64 from PyPI)"
566626
+ }
566359
566627
  ],
566360
- { cmd: `${pipCmd} -m pip install --quiet numpy`, fatal: true, label: "numpy" },
566361
- { cmd: `${pipCmd} -m pip install --quiet huggingface_hub safetensors`, fatal: true, label: "huggingface_hub + safetensors" },
566362
- { cmd: `${pipCmd} -m pip install --quiet "transformers<=4.57.6"`, fatal: true, label: "transformers" },
566363
- { cmd: `${pipCmd} -m pip install --quiet pydub inflect`, fatal: true, label: "pydub + inflect" },
566628
+ {
566629
+ cmd: `${pipCmd} -m pip install --quiet numpy`,
566630
+ fatal: true,
566631
+ label: "numpy"
566632
+ },
566633
+ {
566634
+ cmd: `${pipCmd} -m pip install --quiet huggingface_hub safetensors`,
566635
+ fatal: true,
566636
+ label: "huggingface_hub + safetensors"
566637
+ },
566638
+ {
566639
+ cmd: `${pipCmd} -m pip install --quiet "transformers<=4.57.6"`,
566640
+ fatal: true,
566641
+ label: "transformers"
566642
+ },
566643
+ {
566644
+ cmd: `${pipCmd} -m pip install --quiet pydub inflect`,
566645
+ fatal: true,
566646
+ label: "pydub + inflect"
566647
+ },
566364
566648
  // llvmlite (needed by numba, needed by librosa): try prebuilt first, then compile
566365
- { cmd: `${pipCmd} -m pip install --quiet llvmlite 2>/dev/null || LLVM_CONFIG=$(which llvm-config || which llvm-config-14 || echo llvm-config) ${pipCmd} -m pip install --quiet llvmlite`, fatal: false, label: "llvmlite (ARM — trying prebuilt, then compiling)" },
566366
- { cmd: `${pipCmd} -m pip install --quiet numba`, fatal: false, label: "numba" },
566649
+ {
566650
+ cmd: `${pipCmd} -m pip install --quiet llvmlite 2>/dev/null || LLVM_CONFIG=$(which llvm-config || which llvm-config-14 || echo llvm-config) ${pipCmd} -m pip install --quiet llvmlite`,
566651
+ fatal: false,
566652
+ label: "llvmlite (ARM — trying prebuilt, then compiling)"
566653
+ },
566654
+ {
566655
+ cmd: `${pipCmd} -m pip install --quiet numba`,
566656
+ fatal: false,
566657
+ label: "numba"
566658
+ },
566367
566659
  // librosa: if numba/llvmlite failed, librosa degrades but still works for basic audio loading
566368
- { cmd: `${pipCmd} -m pip install --quiet librosa`, fatal: true, label: "librosa" },
566369
- { cmd: `${pipCmd} -m pip install --quiet lhotse`, fatal: true, label: "lhotse" },
566660
+ {
566661
+ cmd: `${pipCmd} -m pip install --quiet librosa`,
566662
+ fatal: true,
566663
+ label: "librosa"
566664
+ },
566665
+ {
566666
+ cmd: `${pipCmd} -m pip install --quiet lhotse`,
566667
+ fatal: true,
566668
+ label: "lhotse"
566669
+ },
566370
566670
  // vocos: try pip, fallback to building from source if wheels missing
566371
- { cmd: `${pipCmd} -m pip install --quiet vocos 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation vocos`, fatal: true, label: "vocos" },
566671
+ {
566672
+ cmd: `${pipCmd} -m pip install --quiet vocos 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation vocos`,
566673
+ fatal: true,
566674
+ label: "vocos"
566675
+ },
566372
566676
  // LinaCodec: needs C++ build tools on ARM. Install with --no-build-isolation
566373
566677
  // and fallback to CPU-only if CUDA compilation fails.
566374
- { cmd: `${pipCmd} -m pip install --quiet "git+https://github.com/ysharma3501/LinaCodec.git" 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation "git+https://github.com/ysharma3501/LinaCodec.git"`, fatal: true, label: "LinaCodec (voice cloning codec)" },
566678
+ {
566679
+ cmd: `${pipCmd} -m pip install --quiet "git+https://github.com/ysharma3501/LinaCodec.git" 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation "git+https://github.com/ysharma3501/LinaCodec.git"`,
566680
+ fatal: true,
566681
+ label: "LinaCodec (voice cloning codec)"
566682
+ },
566375
566683
  // Non-fatal (not hard-imported by LuxTTS):
566376
- { cmd: `${pipCmd} -m pip install --quiet piper-phonemize --find-links https://k2-fsa.github.io/icefall/piper_phonemize.html`, fatal: false, label: "piper-phonemize (optional)" },
566377
- { cmd: `${pipCmd} -m pip install --quiet jieba pypinyin cn2an`, fatal: true, label: "Chinese text processing" },
566684
+ {
566685
+ cmd: `${pipCmd} -m pip install --quiet piper-phonemize --find-links https://k2-fsa.github.io/icefall/piper_phonemize.html`,
566686
+ fatal: false,
566687
+ label: "piper-phonemize (optional)"
566688
+ },
566689
+ {
566690
+ cmd: `${pipCmd} -m pip install --quiet jieba pypinyin cn2an`,
566691
+ fatal: true,
566692
+ label: "Chinese text processing"
566693
+ },
566378
566694
  // LuxTTS itself: use --no-deps on ARM because we installed deps individually above.
566379
566695
  // Without --no-deps, pip tries to resolve zipvoice's full dependency tree which
566380
566696
  // includes piper-phonemize — and that has no macOS ARM wheel, causing fatal failure.
566381
- { cmd: `${pipCmd} -m pip install --quiet --no-deps -e ${JSON.stringify(repoDir)}`, fatal: true, label: "LuxTTS (editable install)" }
566697
+ {
566698
+ cmd: `${pipCmd} -m pip install --quiet --no-deps -e ${JSON.stringify(repoDir)}`,
566699
+ fatal: true,
566700
+ label: "LuxTTS (editable install)"
566701
+ }
566382
566702
  ] : [
566383
566703
  // x86_64: all-in-one (fast, all wheels available)
566384
566704
  {
@@ -566386,10 +566706,26 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566386
566706
  fatal: true,
566387
566707
  label: "core LuxTTS deps"
566388
566708
  },
566389
- { cmd: `${pipCmd} -m pip install --quiet piper-phonemize --find-links https://k2-fsa.github.io/icefall/piper_phonemize.html`, fatal: false, label: "piper-phonemize" },
566390
- { cmd: `${pipCmd} -m pip install --quiet jieba pypinyin cn2an`, fatal: true, label: "Chinese text processing" },
566391
- { cmd: `${pipCmd} -m pip install --quiet "git+https://github.com/ysharma3501/LinaCodec.git"`, fatal: false, label: "LinaCodec" },
566392
- { cmd: `${pipCmd} -m pip install --quiet -e ${JSON.stringify(repoDir)}`, fatal: true, label: "LuxTTS (editable install)" }
566709
+ {
566710
+ cmd: `${pipCmd} -m pip install --quiet piper-phonemize --find-links https://k2-fsa.github.io/icefall/piper_phonemize.html`,
566711
+ fatal: false,
566712
+ label: "piper-phonemize"
566713
+ },
566714
+ {
566715
+ cmd: `${pipCmd} -m pip install --quiet jieba pypinyin cn2an`,
566716
+ fatal: true,
566717
+ label: "Chinese text processing"
566718
+ },
566719
+ {
566720
+ cmd: `${pipCmd} -m pip install --quiet "git+https://github.com/ysharma3501/LinaCodec.git"`,
566721
+ fatal: false,
566722
+ label: "LinaCodec"
566723
+ },
566724
+ {
566725
+ cmd: `${pipCmd} -m pip install --quiet -e ${JSON.stringify(repoDir)}`,
566726
+ fatal: true,
566727
+ label: "LuxTTS (editable install)"
566728
+ }
566393
566729
  ];
566394
566730
  for (const step of installSteps) {
566395
566731
  try {
@@ -566399,7 +566735,9 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566399
566735
  if (!step.fatal) {
566400
566736
  renderWarning2(` Skipped (${step.label}): ${msg.slice(0, 150)}`);
566401
566737
  } else {
566402
- throw new Error(`Failed to install LuxTTS dependencies (${step.label}): ${msg}`);
566738
+ throw new Error(
566739
+ `Failed to install LuxTTS dependencies (${step.label}): ${msg}`
566740
+ );
566403
566741
  }
566404
566742
  }
566405
566743
  }
@@ -566422,7 +566760,12 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
566422
566760
  if (this.luxttsCloneRef && existsSync87(this.luxttsCloneRef)) return;
566423
566761
  const refsDir = luxttsCloneRefsDir();
566424
566762
  if (!existsSync87(refsDir)) return;
566425
- for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
566763
+ for (const name10 of [
566764
+ "custom-clone.wav",
566765
+ "custom-clone.mp3",
566766
+ "glados-ref.wav",
566767
+ "overwatch-ref.wav"
566768
+ ]) {
566426
566769
  const p2 = join104(refsDir, name10);
566427
566770
  if (existsSync87(p2)) {
566428
566771
  this.luxttsCloneRef = p2;
@@ -566625,7 +566968,10 @@ if __name__ == '__main__':
566625
566968
  if (!cleaned) return null;
566626
566969
  const ready = await this.ensureLuxttsDaemon();
566627
566970
  if (!ready) return null;
566628
- const wavPath = join104(tmpdir20(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
566971
+ const wavPath = join104(
566972
+ tmpdir20(),
566973
+ `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`
566974
+ );
566629
566975
  try {
566630
566976
  await this.luxttsRequest({
566631
566977
  action: "synthesize",
@@ -566654,7 +567000,10 @@ if __name__ == '__main__':
566654
567000
  wavData.byteOffset + 44,
566655
567001
  (wavData.length - 44) / 2
566656
567002
  );
566657
- const fadeInSamples = Math.min(Math.round(sampleRate * 0.35), samples.length);
567003
+ const fadeInSamples = Math.min(
567004
+ Math.round(sampleRate * 0.35),
567005
+ samples.length
567006
+ );
566658
567007
  for (let i2 = 0; i2 < fadeInSamples; i2++) {
566659
567008
  samples[i2] = Math.round(samples[i2] * (i2 / fadeInSamples));
566660
567009
  }
@@ -566664,7 +567013,10 @@ if __name__ == '__main__':
566664
567013
  }
566665
567014
  }
566666
567015
  const header = wavData.subarray(0, 44);
566667
- const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
567016
+ const scaled = Buffer.concat([
567017
+ header,
567018
+ Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)
567019
+ ]);
566668
567020
  writeFileSync46(wavPath, scaled);
566669
567021
  }
566670
567022
  } catch {
@@ -566692,7 +567044,11 @@ if __name__ == '__main__':
566692
567044
  try {
566693
567045
  const wavData = readFileSync71(wavPath);
566694
567046
  if (wavData.length > 44) {
566695
- const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
567047
+ const pcm = Buffer.from(
567048
+ wavData.buffer,
567049
+ wavData.byteOffset + 44,
567050
+ wavData.length - 44
567051
+ );
566696
567052
  const sampleRate = wavData.readUInt32LE(24);
566697
567053
  this.onPCMOutput(pcm, sampleRate);
566698
567054
  }
@@ -566715,7 +567071,11 @@ if __name__ == '__main__':
566715
567071
  for (let i2 = 0; i2 < int16.length; i2++) {
566716
567072
  float32[i2] = int16[i2] / 32768;
566717
567073
  }
566718
- const stereo = this.applyStereoDelay(float32, sampleRate, stereoDelayMs);
567074
+ const stereo = this.applyStereoDelay(
567075
+ float32,
567076
+ sampleRate,
567077
+ stereoDelayMs
567078
+ );
566719
567079
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
566720
567080
  }
566721
567081
  }
@@ -566733,7 +567093,12 @@ if __name__ == '__main__':
566733
567093
  async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
566734
567094
  const wavPath = await this.synthesizeLuxttsWav(text, speedFactor);
566735
567095
  if (!wavPath) return;
566736
- await this.postProcessAndPlayLuxtts(wavPath, volume, pitchFactor, stereoDelayMs);
567096
+ await this.postProcessAndPlayLuxtts(
567097
+ wavPath,
567098
+ volume,
567099
+ pitchFactor,
567100
+ stereoDelayMs
567101
+ );
566737
567102
  }
566738
567103
  /**
566739
567104
  * Synthesize text to WAV buffer using LuxTTS (no playback).
@@ -566776,7 +567141,7 @@ if __name__ == '__main__':
566776
567141
  const pkgPath = join104(voiceDir(), "package.json");
566777
567142
  const expectedDeps = {
566778
567143
  "onnxruntime-node": "^1.21.0",
566779
- "phonemizer": "^1.2.1"
567144
+ phonemizer: "^1.2.1"
566780
567145
  };
566781
567146
  if (existsSync87(pkgPath)) {
566782
567147
  try {
@@ -566789,11 +567154,18 @@ if __name__ == '__main__':
566789
567154
  }
566790
567155
  }
566791
567156
  if (!existsSync87(pkgPath)) {
566792
- writeFileSync46(pkgPath, JSON.stringify({
566793
- name: "open-agents-voice",
566794
- private: true,
566795
- dependencies: expectedDeps
566796
- }, null, 2));
567157
+ writeFileSync46(
567158
+ pkgPath,
567159
+ JSON.stringify(
567160
+ {
567161
+ name: "open-agents-voice",
567162
+ private: true,
567163
+ dependencies: expectedDeps
567164
+ },
567165
+ null,
567166
+ 2
567167
+ )
567168
+ );
566797
567169
  }
566798
567170
  const voiceRequire = createRequire4(join104(voiceDir(), "index.js"));
566799
567171
  const probeOnnx = async () => {
@@ -566807,7 +567179,11 @@ if __name__ == '__main__':
566807
567179
  return false;
566808
567180
  }
566809
567181
  };
566810
- const onnxNodeModules = join104(voiceDir(), "node_modules", "onnxruntime-node");
567182
+ const onnxNodeModules = join104(
567183
+ voiceDir(),
567184
+ "node_modules",
567185
+ "onnxruntime-node"
567186
+ );
566811
567187
  const onnxInstalled = existsSync87(onnxNodeModules);
566812
567188
  if (onnxInstalled && !await probeOnnx()) {
566813
567189
  throw new Error(
@@ -566819,7 +567195,10 @@ if __name__ == '__main__':
566819
567195
  } catch {
566820
567196
  renderInfo2("Installing ONNX runtime for voice synthesis (background)...");
566821
567197
  try {
566822
- await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
567198
+ await this.asyncShell(
567199
+ `cd "${voiceDir()}" && npm install --no-audit --no-fund`,
567200
+ 12e4
567201
+ );
566823
567202
  } catch (err) {
566824
567203
  const archHint = arch3 !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch3}.` : "";
566825
567204
  throw new Error(
@@ -566846,7 +567225,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`
566846
567225
  } catch {
566847
567226
  renderInfo2("Installing phonemizer for voice synthesis (background)...");
566848
567227
  try {
566849
- await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
567228
+ await this.asyncShell(
567229
+ `cd "${voiceDir()}" && npm install --no-audit --no-fund`,
567230
+ 12e4
567231
+ );
566850
567232
  const phonemizerMod = voiceRequire("phonemizer");
566851
567233
  this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
566852
567234
  } catch (err) {
@@ -566872,17 +567254,24 @@ Error: ${err instanceof Error ? err.message : String(err)}`
566872
567254
  if (!existsSync87(configPath2)) {
566873
567255
  renderInfo2(`Downloading ${model.label} voice config...`);
566874
567256
  const configResp = await fetch(model.configUrl);
566875
- if (!configResp.ok) throw new Error(`Failed to download config: HTTP ${configResp.status}`);
567257
+ if (!configResp.ok)
567258
+ throw new Error(`Failed to download config: HTTP ${configResp.status}`);
566876
567259
  const configText = await configResp.text();
566877
567260
  writeFileSync46(configPath2, configText);
566878
567261
  }
566879
567262
  if (!existsSync87(onnxPath)) {
566880
- renderInfo2(`Downloading ${model.label} voice model (this may take a minute)...`);
567263
+ renderInfo2(
567264
+ `Downloading ${model.label} voice model (this may take a minute)...`
567265
+ );
566881
567266
  const onnxResp = await fetch(model.onnxUrl);
566882
- if (!onnxResp.ok) throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
567267
+ if (!onnxResp.ok)
567268
+ throw new Error(`Failed to download model: HTTP ${onnxResp.status}`);
566883
567269
  const reader = onnxResp.body?.getReader();
566884
567270
  if (!reader) throw new Error("No response body");
566885
- const contentLength = parseInt(onnxResp.headers.get("content-length") || "0", 10);
567271
+ const contentLength = parseInt(
567272
+ onnxResp.headers.get("content-length") || "0",
567273
+ 10
567274
+ );
566886
567275
  const chunks = [];
566887
567276
  let received = 0;
566888
567277
  while (true) {
@@ -566893,13 +567282,17 @@ Error: ${err instanceof Error ? err.message : String(err)}`
566893
567282
  if (contentLength > 0) {
566894
567283
  const pct = Math.round(received / contentLength * 100);
566895
567284
  if (pct === 25 || pct === 50 || pct === 75 || pct === 100) {
566896
- renderInfo2(` ${pct}% (${formatBytes2(received)} / ${formatBytes2(contentLength)})`);
567285
+ renderInfo2(
567286
+ ` ${pct}% (${formatBytes2(received)} / ${formatBytes2(contentLength)})`
567287
+ );
566897
567288
  }
566898
567289
  }
566899
567290
  }
566900
567291
  const fullBuffer = Buffer.concat(chunks);
566901
567292
  writeFileSync46(onnxPath, fullBuffer);
566902
- renderInfo2(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
567293
+ renderInfo2(
567294
+ `${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`
567295
+ );
566903
567296
  }
566904
567297
  }
566905
567298
  // -------------------------------------------------------------------------
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.564",
3
+ "version": "0.187.565",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.564",
9
+ "version": "0.187.565",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.564",
3
+ "version": "0.187.565",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",