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 +536 -143
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -563826,10 +563826,21 @@ __export(voice_exports, {
|
|
|
563826
563826
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
563827
563827
|
resetNarrationContext: () => resetNarrationContext
|
|
563828
563828
|
});
|
|
563829
|
-
import {
|
|
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 {
|
|
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(
|
|
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(
|
|
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 [
|
|
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(
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
564426
|
-
|
|
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(
|
|
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")
|
|
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(
|
|
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(
|
|
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 = [
|
|
564664
|
-
|
|
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 = {
|
|
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(
|
|
564839
|
-
|
|
564840
|
-
|
|
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)
|
|
564927
|
+
if (luxttsModels.length)
|
|
564928
|
+
msg += `
|
|
564847
564929
|
LuxTTS (voice clone): ${luxttsModels.join(", ")}`;
|
|
564848
|
-
if (supertonicModels.length)
|
|
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([
|
|
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({
|
|
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(
|
|
565429
|
+
wavPath = await this.synthesizeLuxttsWav(
|
|
565430
|
+
item.text,
|
|
565431
|
+
item.speedFactor
|
|
565432
|
+
);
|
|
565333
565433
|
}
|
|
565334
565434
|
if (wavPath) {
|
|
565335
|
-
await this.postProcessAndPlayLuxtts(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
565678
|
+
buffer2.writeInt16LE(
|
|
565679
|
+
lSample < 0 ? lSample * 32768 : lSample * 32767,
|
|
565680
|
+
pos
|
|
565681
|
+
);
|
|
565556
565682
|
pos += 2;
|
|
565557
|
-
buffer2.writeInt16LE(
|
|
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(
|
|
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(
|
|
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(
|
|
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]) => ({
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
565778
|
-
|
|
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"`, {
|
|
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(
|
|
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)
|
|
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(
|
|
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(
|
|
566017
|
+
const cleaned = applySupertonicExpression(
|
|
566018
|
+
text.replace(/\*/g, "").trim(),
|
|
566019
|
+
settings.expression
|
|
566020
|
+
);
|
|
565846
566021
|
if (!cleaned) return null;
|
|
565847
|
-
const wavPath = join104(
|
|
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(
|
|
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"`, {
|
|
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(
|
|
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([
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
566267
|
-
|
|
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(
|
|
566270
|
-
|
|
566271
|
-
|
|
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"], {
|
|
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"], {
|
|
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(
|
|
566517
|
+
renderWarning2(
|
|
566518
|
+
" Then run: brew install llvm gcc openblas libsndfile"
|
|
566519
|
+
);
|
|
566292
566520
|
}
|
|
566293
566521
|
} else {
|
|
566294
|
-
renderInfo2(
|
|
566295
|
-
|
|
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(
|
|
566298
|
-
|
|
566299
|
-
|
|
566300
|
-
|
|
566301
|
-
"
|
|
566302
|
-
|
|
566303
|
-
|
|
566304
|
-
|
|
566305
|
-
|
|
566306
|
-
|
|
566307
|
-
|
|
566308
|
-
|
|
566309
|
-
|
|
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(
|
|
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(
|
|
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
|
-
{
|
|
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", {
|
|
566343
|
-
|
|
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"))
|
|
566346
|
-
|
|
566347
|
-
else if (ver.startsWith("6.") || tegra.includes("R36"))
|
|
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
|
-
{
|
|
566352
|
-
|
|
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
|
-
{
|
|
566622
|
+
{
|
|
566623
|
+
cmd: `${pipCmd} -m pip install --quiet torch torchaudio`,
|
|
566624
|
+
fatal: true,
|
|
566625
|
+
label: "PyTorch (ARM aarch64 from PyPI)"
|
|
566626
|
+
}
|
|
566359
566627
|
],
|
|
566360
|
-
{
|
|
566361
|
-
|
|
566362
|
-
|
|
566363
|
-
|
|
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
|
-
{
|
|
566366
|
-
|
|
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
|
-
{
|
|
566369
|
-
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
566377
|
-
|
|
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
|
-
{
|
|
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
|
-
{
|
|
566390
|
-
|
|
566391
|
-
|
|
566392
|
-
|
|
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(
|
|
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 [
|
|
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(
|
|
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(
|
|
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([
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
566793
|
-
|
|
566794
|
-
|
|
566795
|
-
|
|
566796
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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)
|
|
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(
|
|
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)
|
|
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(
|
|
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(
|
|
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(
|
|
567293
|
+
renderInfo2(
|
|
567294
|
+
`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`
|
|
567295
|
+
);
|
|
566903
567296
|
}
|
|
566904
567297
|
}
|
|
566905
567298
|
// -------------------------------------------------------------------------
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
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.
|
|
9
|
+
"version": "0.187.565",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED