open-agents-ai 0.103.98 → 0.103.99
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 +223 -169
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35165,6 +35165,8 @@ var init_voice = __esm({
|
|
|
35165
35165
|
* Accepts a path to a WAV/MP3/OGG/FLAC file (min 3 seconds).
|
|
35166
35166
|
* Returns status message.
|
|
35167
35167
|
*/
|
|
35168
|
+
/** Filename of the last cloned voice (set by setCloneVoice for UI to locate new entry) */
|
|
35169
|
+
lastClonedFilename = null;
|
|
35168
35170
|
async setCloneVoice(audioPath) {
|
|
35169
35171
|
let p = audioPath.trim();
|
|
35170
35172
|
if (p.startsWith("'") && p.endsWith("'") || p.startsWith('"') && p.endsWith('"')) {
|
|
@@ -35183,16 +35185,22 @@ var init_voice = __esm({
|
|
|
35183
35185
|
if (!existsSync33(refsDir))
|
|
35184
35186
|
mkdirSync13(refsDir, { recursive: true });
|
|
35185
35187
|
const ext = audioPath.split(".").pop() || "wav";
|
|
35186
|
-
const
|
|
35188
|
+
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
35189
|
+
const ts = Date.now().toString(36);
|
|
35190
|
+
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
35191
|
+
const destPath = join41(refsDir, destFilename);
|
|
35187
35192
|
try {
|
|
35188
35193
|
const data = readFileSync23(audioPath);
|
|
35189
35194
|
writeFileSync13(destPath, data);
|
|
35190
35195
|
} catch (err) {
|
|
35191
35196
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
35192
35197
|
}
|
|
35198
|
+
const meta = this.loadCloneMeta();
|
|
35199
|
+
meta[destFilename] = srcName.replace(/[-_]/g, " ");
|
|
35200
|
+
this.saveCloneMeta(meta);
|
|
35193
35201
|
this.luxttsCloneRef = destPath;
|
|
35194
|
-
|
|
35195
|
-
return `Voice clone reference set: ${
|
|
35202
|
+
this.lastClonedFilename = destFilename;
|
|
35203
|
+
return `Voice clone reference set: ${destFilename}. LuxTTS will use this voice.`;
|
|
35196
35204
|
}
|
|
35197
35205
|
/**
|
|
35198
35206
|
* Generate a synthetic voice clone reference from an existing ONNX voice model.
|
|
@@ -37172,7 +37180,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
37172
37180
|
return "handled";
|
|
37173
37181
|
}
|
|
37174
37182
|
if (arg === "list" || arg === "ls" || arg === "voices") {
|
|
37183
|
+
ctx.setOverlayActive?.(true);
|
|
37175
37184
|
await handleVoiceList(ctx);
|
|
37185
|
+
ctx.setOverlayActive?.(false);
|
|
37176
37186
|
return "handled";
|
|
37177
37187
|
}
|
|
37178
37188
|
const msg = await ctx.voiceSetModel(arg);
|
|
@@ -38238,185 +38248,195 @@ function formatFileSize(bytes) {
|
|
|
38238
38248
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
38239
38249
|
}
|
|
38240
38250
|
async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
38241
|
-
const currentMode = ctx.voiceGetMode?.() ?? "action";
|
|
38242
38251
|
const modeLabels = {
|
|
38243
38252
|
chat: "Chat \u2014 speaks model responses",
|
|
38244
38253
|
action: "Action \u2014 speaks tool narrations",
|
|
38245
38254
|
verbose: "Verbose \u2014 speaks both"
|
|
38246
38255
|
};
|
|
38247
|
-
|
|
38248
|
-
|
|
38249
|
-
|
|
38250
|
-
|
|
38251
|
-
|
|
38252
|
-
|
|
38253
|
-
|
|
38254
|
-
|
|
38255
|
-
|
|
38256
|
-
|
|
38257
|
-
|
|
38258
|
-
|
|
38259
|
-
|
|
38260
|
-
|
|
38261
|
-
|
|
38262
|
-
|
|
38263
|
-
|
|
38264
|
-
|
|
38265
|
-
|
|
38266
|
-
|
|
38267
|
-
|
|
38268
|
-
|
|
38269
|
-
|
|
38270
|
-
|
|
38271
|
-
|
|
38272
|
-
|
|
38273
|
-
|
|
38274
|
-
|
|
38275
|
-
|
|
38276
|
-
|
|
38277
|
-
{
|
|
38278
|
-
|
|
38279
|
-
];
|
|
38280
|
-
const modeResult = await tuiSelect({
|
|
38281
|
-
items: modeItems,
|
|
38282
|
-
activeKey: currentMode,
|
|
38283
|
-
title: "Voice Mode",
|
|
38284
|
-
rl: ctx.rl,
|
|
38285
|
-
availableRows: ctx.availableContentRows?.()
|
|
38286
|
-
});
|
|
38287
|
-
if (modeResult.confirmed && modeResult.key) {
|
|
38288
|
-
const mode = modeResult.key;
|
|
38289
|
-
ctx.voiceSetMode?.(mode);
|
|
38290
|
-
save({ voiceMode: mode });
|
|
38291
|
-
renderInfo(`Voice mode: ${modeLabels[mode]}${hasLocal ? " (project-local)" : ""}`);
|
|
38256
|
+
while (true) {
|
|
38257
|
+
const isEnabled = ctx.voiceIsEnabled?.() ?? false;
|
|
38258
|
+
const currentMode = ctx.voiceGetMode?.() ?? "action";
|
|
38259
|
+
const currentModel = ctx.voiceGetModel?.() ?? "unknown";
|
|
38260
|
+
const enabledLabel = isEnabled ? selectColors.green("\u25CF Voice: Enabled") : selectColors.dim("\u25CB Voice: Disabled");
|
|
38261
|
+
const items = [
|
|
38262
|
+
{ key: "header-status", label: selectColors.dim("\u2500\u2500\u2500 Voice Status \u2500\u2500\u2500") },
|
|
38263
|
+
{ key: "toggle", label: isEnabled ? "Disable Voice" : "Enable Voice", detail: enabledLabel },
|
|
38264
|
+
{ key: "header-config", label: selectColors.dim("\u2500\u2500\u2500 Configuration \u2500\u2500\u2500") },
|
|
38265
|
+
{ key: "mode", label: "Voice Mode", detail: `${selectColors.green(currentMode)} \u2014 ${modeLabels[currentMode]}` },
|
|
38266
|
+
{ key: "voice", label: "Change TTS Voice", detail: `current: ${selectColors.green(currentModel)}` },
|
|
38267
|
+
{ key: "system", label: "Change TTS System", detail: "onnx / mlx / luxtts" },
|
|
38268
|
+
{ key: "clone", label: "Clone Voice", detail: "drag & drop audio file" },
|
|
38269
|
+
{ key: "list", label: "Manage Clone Voices", detail: "rename, play, delete" }
|
|
38270
|
+
];
|
|
38271
|
+
ctx.setOverlayActive?.(true);
|
|
38272
|
+
const result = await tuiSelect({
|
|
38273
|
+
items,
|
|
38274
|
+
title: "Voice Configuration",
|
|
38275
|
+
rl: ctx.rl,
|
|
38276
|
+
availableRows: ctx.availableContentRows?.(),
|
|
38277
|
+
skipKeys: ["header-status", "header-config"]
|
|
38278
|
+
});
|
|
38279
|
+
ctx.setOverlayActive?.(false);
|
|
38280
|
+
if (!result.confirmed || !result.key)
|
|
38281
|
+
return;
|
|
38282
|
+
switch (result.key) {
|
|
38283
|
+
case "toggle": {
|
|
38284
|
+
const msg = await ctx.voiceToggle();
|
|
38285
|
+
const isOn = msg.toLowerCase().includes("enabled") || msg.toLowerCase().includes("on");
|
|
38286
|
+
save({ voice: isOn });
|
|
38287
|
+
continue;
|
|
38292
38288
|
}
|
|
38293
|
-
|
|
38294
|
-
|
|
38295
|
-
|
|
38296
|
-
|
|
38297
|
-
|
|
38298
|
-
|
|
38299
|
-
|
|
38300
|
-
|
|
38301
|
-
|
|
38302
|
-
|
|
38303
|
-
|
|
38304
|
-
|
|
38305
|
-
|
|
38306
|
-
|
|
38307
|
-
|
|
38308
|
-
|
|
38309
|
-
|
|
38310
|
-
|
|
38311
|
-
|
|
38312
|
-
|
|
38313
|
-
|
|
38314
|
-
});
|
|
38315
|
-
if (voiceResult.confirmed && voiceResult.key) {
|
|
38316
|
-
const msg = await ctx.voiceSetModel(voiceResult.key);
|
|
38317
|
-
save({ voice: true, voiceModel: voiceResult.key });
|
|
38318
|
-
renderInfo(msg + (hasLocal ? " (project-local)" : ""));
|
|
38289
|
+
case "mode": {
|
|
38290
|
+
ctx.setOverlayActive?.(true);
|
|
38291
|
+
const modeItems = [
|
|
38292
|
+
{ key: "chat", label: "Chat", detail: "speaks streamed model text at normal pitch" },
|
|
38293
|
+
{ key: "action", label: "Action", detail: "speaks tool call narrations with emotion pitch" },
|
|
38294
|
+
{ key: "verbose", label: "Verbose", detail: "speaks both chat and actions" }
|
|
38295
|
+
];
|
|
38296
|
+
const modeResult = await tuiSelect({
|
|
38297
|
+
items: modeItems,
|
|
38298
|
+
activeKey: currentMode,
|
|
38299
|
+
title: "Voice Mode",
|
|
38300
|
+
rl: ctx.rl,
|
|
38301
|
+
availableRows: ctx.availableContentRows?.()
|
|
38302
|
+
});
|
|
38303
|
+
ctx.setOverlayActive?.(false);
|
|
38304
|
+
if (modeResult.confirmed && modeResult.key) {
|
|
38305
|
+
const mode = modeResult.key;
|
|
38306
|
+
ctx.voiceSetMode?.(mode);
|
|
38307
|
+
save({ voiceMode: mode });
|
|
38308
|
+
}
|
|
38309
|
+
continue;
|
|
38319
38310
|
}
|
|
38320
|
-
|
|
38321
|
-
|
|
38322
|
-
|
|
38323
|
-
|
|
38324
|
-
|
|
38325
|
-
|
|
38326
|
-
|
|
38327
|
-
|
|
38328
|
-
|
|
38329
|
-
|
|
38330
|
-
|
|
38311
|
+
case "voice": {
|
|
38312
|
+
ctx.setOverlayActive?.(true);
|
|
38313
|
+
const voiceItems = [
|
|
38314
|
+
{ key: "header-onnx", label: selectColors.dim("\u2500\u2500\u2500 ONNX Voices \u2500\u2500\u2500") },
|
|
38315
|
+
{ key: "glados", label: "GLaDOS", detail: "Portal AI voice (ONNX)" },
|
|
38316
|
+
{ key: "overwatch", label: "Overwatch", detail: "Overwatch announcer (ONNX)" },
|
|
38317
|
+
{ key: "header-mlx", label: selectColors.dim("\u2500\u2500\u2500 MLX Voices (macOS) \u2500\u2500\u2500") },
|
|
38318
|
+
{ key: "kokoro:af_heart", label: "Kokoro Heart", detail: "warm female (MLX)" },
|
|
38319
|
+
{ key: "kokoro:af_bella", label: "Kokoro Bella", detail: "expressive female (MLX)" },
|
|
38320
|
+
{ key: "kokoro:am_adam", label: "Kokoro Adam", detail: "male (MLX)" },
|
|
38321
|
+
{ key: "kokoro:bf_emma", label: "Kokoro Emma", detail: "British female (MLX)" },
|
|
38322
|
+
{ key: "header-clone", label: selectColors.dim("\u2500\u2500\u2500 Voice Clone \u2500\u2500\u2500") },
|
|
38323
|
+
{ key: "luxtts", label: "LuxTTS", detail: "voice cloning engine" }
|
|
38324
|
+
];
|
|
38325
|
+
const voiceResult = await tuiSelect({
|
|
38326
|
+
items: voiceItems,
|
|
38327
|
+
activeKey: currentModel,
|
|
38328
|
+
title: "Select TTS Voice",
|
|
38329
|
+
rl: ctx.rl,
|
|
38330
|
+
availableRows: ctx.availableContentRows?.(),
|
|
38331
|
+
skipKeys: ["header-onnx", "header-mlx", "header-clone"]
|
|
38332
|
+
});
|
|
38333
|
+
ctx.setOverlayActive?.(false);
|
|
38334
|
+
if (voiceResult.confirmed && voiceResult.key) {
|
|
38335
|
+
const msg = await ctx.voiceSetModel(voiceResult.key);
|
|
38336
|
+
save({ voice: true, voiceModel: voiceResult.key });
|
|
38337
|
+
}
|
|
38338
|
+
continue;
|
|
38331
38339
|
}
|
|
38332
|
-
|
|
38333
|
-
|
|
38334
|
-
|
|
38335
|
-
|
|
38336
|
-
|
|
38337
|
-
|
|
38338
|
-
|
|
38339
|
-
|
|
38340
|
-
if (
|
|
38341
|
-
|
|
38342
|
-
|
|
38343
|
-
|
|
38344
|
-
|
|
38345
|
-
|
|
38346
|
-
|
|
38347
|
-
|
|
38348
|
-
|
|
38349
|
-
|
|
38350
|
-
|
|
38351
|
-
|
|
38352
|
-
|
|
38353
|
-
|
|
38354
|
-
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
|
|
38359
|
-
|
|
38360
|
-
|
|
38361
|
-
|
|
38362
|
-
|
|
38363
|
-
|
|
38340
|
+
case "system": {
|
|
38341
|
+
ctx.setOverlayActive?.(true);
|
|
38342
|
+
const sysItems = [
|
|
38343
|
+
{ key: "onnx", label: "Piper ONNX", detail: "cross-platform, fast, offline" },
|
|
38344
|
+
{ key: "luxtts", label: "LuxTTS", detail: "voice cloning, Python venv" },
|
|
38345
|
+
{ key: "header-import", label: selectColors.dim("\u2500\u2500\u2500 Import \u2500\u2500\u2500") },
|
|
38346
|
+
{ key: "import-onnx", label: "Import Piper Model", detail: "drag & drop .onnx + .onnx.json" }
|
|
38347
|
+
];
|
|
38348
|
+
if (process.platform === "darwin") {
|
|
38349
|
+
sysItems.splice(1, 0, { key: "mlx", label: "MLX Audio", detail: "Apple Silicon, Kokoro voices" });
|
|
38350
|
+
}
|
|
38351
|
+
const sysResult = await tuiSelect({
|
|
38352
|
+
items: sysItems,
|
|
38353
|
+
title: "Select TTS System",
|
|
38354
|
+
rl: ctx.rl,
|
|
38355
|
+
availableRows: ctx.availableContentRows?.(),
|
|
38356
|
+
skipKeys: ["header-import"]
|
|
38357
|
+
});
|
|
38358
|
+
ctx.setOverlayActive?.(false);
|
|
38359
|
+
if (sysResult.confirmed && sysResult.key) {
|
|
38360
|
+
if (sysResult.key === "import-onnx") {
|
|
38361
|
+
ctx.setOverlayActive?.(true);
|
|
38362
|
+
const onnxDrop = await showDropPanel({
|
|
38363
|
+
title: "Import Piper Voice \u2014 Drop .onnx File",
|
|
38364
|
+
instruction: "Drag and drop the .onnx model file",
|
|
38365
|
+
allowedExtensions: [".onnx"],
|
|
38366
|
+
typeLabel: "ONNX model",
|
|
38367
|
+
rl: ctx.rl
|
|
38368
|
+
});
|
|
38369
|
+
ctx.setOverlayActive?.(false);
|
|
38370
|
+
if (!onnxDrop.confirmed || !onnxDrop.path) {
|
|
38371
|
+
continue;
|
|
38372
|
+
}
|
|
38373
|
+
ctx.setOverlayActive?.(true);
|
|
38374
|
+
const jsonDrop = await showDropPanel({
|
|
38375
|
+
title: "Import Piper Voice \u2014 Drop .onnx.json Config",
|
|
38376
|
+
instruction: "Drag and drop the .onnx.json config file for the model",
|
|
38377
|
+
allowedExtensions: [".json"],
|
|
38378
|
+
typeLabel: "JSON config",
|
|
38379
|
+
rl: ctx.rl
|
|
38380
|
+
});
|
|
38381
|
+
ctx.setOverlayActive?.(false);
|
|
38382
|
+
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
38383
|
+
continue;
|
|
38384
|
+
}
|
|
38385
|
+
const { basename: basename16, join: pathJoin } = await import("node:path");
|
|
38386
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync21, existsSync: exists } = await import("node:fs");
|
|
38387
|
+
const { homedir: homedir15 } = await import("node:os");
|
|
38388
|
+
const modelName = basename16(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
38389
|
+
const destDir = pathJoin(homedir15(), ".open-agents", "voice", "models", modelName);
|
|
38390
|
+
if (!exists(destDir))
|
|
38391
|
+
mkdirSync21(destDir, { recursive: true });
|
|
38392
|
+
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
38393
|
+
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
38394
|
+
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
38395
|
+
registerCustomOnnxModel2(modelName, modelName);
|
|
38396
|
+
await ctx.voiceSetModel(modelName);
|
|
38397
|
+
save({ voice: true, voiceModel: modelName });
|
|
38398
|
+
} else {
|
|
38399
|
+
const systemModelMap = {
|
|
38400
|
+
onnx: "glados",
|
|
38401
|
+
mlx: "kokoro:af_heart",
|
|
38402
|
+
luxtts: "luxtts"
|
|
38403
|
+
};
|
|
38404
|
+
const modelId = systemModelMap[sysResult.key] ?? "glados";
|
|
38405
|
+
await ctx.voiceSetModel(modelId);
|
|
38406
|
+
save({ voice: true, voiceModel: modelId });
|
|
38364
38407
|
}
|
|
38365
|
-
const { basename: basename16, join: pathJoin } = await import("node:path");
|
|
38366
|
-
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync21, existsSync: exists } = await import("node:fs");
|
|
38367
|
-
const { homedir: homedir15 } = await import("node:os");
|
|
38368
|
-
const modelName = basename16(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
38369
|
-
const destDir = pathJoin(homedir15(), ".open-agents", "voice", "models", modelName);
|
|
38370
|
-
if (!exists(destDir))
|
|
38371
|
-
mkdirSync21(destDir, { recursive: true });
|
|
38372
|
-
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
38373
|
-
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
38374
|
-
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
38375
|
-
registerCustomOnnxModel2(modelName, modelName);
|
|
38376
|
-
const msg = await ctx.voiceSetModel(modelName);
|
|
38377
|
-
save({ voice: true, voiceModel: modelName });
|
|
38378
|
-
renderInfo(`Imported Piper model "${modelName}". ${msg}`);
|
|
38379
|
-
} else {
|
|
38380
|
-
const systemModelMap = {
|
|
38381
|
-
onnx: "glados",
|
|
38382
|
-
mlx: "kokoro:af_heart",
|
|
38383
|
-
luxtts: "luxtts"
|
|
38384
|
-
};
|
|
38385
|
-
const modelId = systemModelMap[sysResult.key] ?? "glados";
|
|
38386
|
-
const msg = await ctx.voiceSetModel(modelId);
|
|
38387
|
-
save({ voice: true, voiceModel: modelId });
|
|
38388
|
-
renderInfo(msg + (hasLocal ? " (project-local)" : ""));
|
|
38389
38408
|
}
|
|
38409
|
+
continue;
|
|
38390
38410
|
}
|
|
38391
|
-
|
|
38392
|
-
|
|
38393
|
-
|
|
38394
|
-
|
|
38395
|
-
|
|
38396
|
-
|
|
38397
|
-
|
|
38398
|
-
|
|
38399
|
-
|
|
38400
|
-
|
|
38401
|
-
|
|
38402
|
-
|
|
38403
|
-
|
|
38404
|
-
|
|
38411
|
+
case "clone": {
|
|
38412
|
+
ctx.setOverlayActive?.(true);
|
|
38413
|
+
const dropResult = await showDropPanel({
|
|
38414
|
+
title: "Voice Clone \u2014 Drop Audio File",
|
|
38415
|
+
instruction: "Drag and drop an audio file to use as voice clone reference",
|
|
38416
|
+
allowedExtensions: [".wav", ".mp3", ".ogg", ".flac", ".m4a", ".opus", ".aac"],
|
|
38417
|
+
typeLabel: "Audio files",
|
|
38418
|
+
rl: ctx.rl
|
|
38419
|
+
});
|
|
38420
|
+
ctx.setOverlayActive?.(false);
|
|
38421
|
+
if (dropResult.confirmed && dropResult.path && ctx.voiceClone) {
|
|
38422
|
+
await ctx.voiceClone(dropResult.path);
|
|
38423
|
+
const newFilename = ctx.voiceGetLastClonedFilename?.();
|
|
38424
|
+
ctx.setOverlayActive?.(true);
|
|
38425
|
+
await handleVoiceList(ctx, newFilename ?? void 0);
|
|
38426
|
+
ctx.setOverlayActive?.(false);
|
|
38405
38427
|
}
|
|
38406
|
-
|
|
38407
|
-
|
|
38408
|
-
|
|
38409
|
-
|
|
38428
|
+
continue;
|
|
38429
|
+
}
|
|
38430
|
+
case "list": {
|
|
38431
|
+
ctx.setOverlayActive?.(true);
|
|
38432
|
+
await handleVoiceList(ctx);
|
|
38433
|
+
ctx.setOverlayActive?.(false);
|
|
38434
|
+
continue;
|
|
38410
38435
|
}
|
|
38411
|
-
break;
|
|
38412
|
-
}
|
|
38413
|
-
case "list": {
|
|
38414
|
-
await handleVoiceList(ctx);
|
|
38415
|
-
break;
|
|
38416
38436
|
}
|
|
38417
38437
|
}
|
|
38418
38438
|
}
|
|
38419
|
-
async function handleVoiceList(ctx) {
|
|
38439
|
+
async function handleVoiceList(ctx, focusFilename) {
|
|
38420
38440
|
if (!ctx.voiceListClones) {
|
|
38421
38441
|
renderWarning("Voice clone management not available in this context.");
|
|
38422
38442
|
return;
|
|
@@ -38433,11 +38453,12 @@ async function handleVoiceList(ctx) {
|
|
|
38433
38453
|
label: cl.name,
|
|
38434
38454
|
detail: `${cl.filename} ${formatFileSize(cl.size)}`
|
|
38435
38455
|
}));
|
|
38436
|
-
const activeFilename = clones.find((cl) => cl.isActive)?.filename;
|
|
38456
|
+
const activeFilename = focusFilename ?? clones.find((cl) => cl.isActive)?.filename;
|
|
38457
|
+
let pendingAutoRename = focusFilename ?? null;
|
|
38437
38458
|
const result = await tuiSelect({
|
|
38438
38459
|
items,
|
|
38439
38460
|
activeKey: activeFilename,
|
|
38440
|
-
title: "Voice Clone References",
|
|
38461
|
+
title: focusFilename ? "Voice Clone References \u2014 Press any key to name your new voice" : "Voice Clone References",
|
|
38441
38462
|
rl: ctx.rl,
|
|
38442
38463
|
availableRows: ctx.availableContentRows?.(),
|
|
38443
38464
|
customKeyHint: " e rename p play",
|
|
@@ -38449,6 +38470,22 @@ async function handleVoiceList(ctx) {
|
|
|
38449
38470
|
}
|
|
38450
38471
|
},
|
|
38451
38472
|
onCustomKey: (item, key, helpers) => {
|
|
38473
|
+
if (pendingAutoRename && item.key === pendingAutoRename) {
|
|
38474
|
+
pendingAutoRename = null;
|
|
38475
|
+
const currentName = item.label;
|
|
38476
|
+
helpers.getInput("Name this voice:", currentName).then((newName) => {
|
|
38477
|
+
if (newName !== null && newName.trim() && newName.trim() !== currentName) {
|
|
38478
|
+
ctx.voiceRenameClone?.(item.key, newName.trim());
|
|
38479
|
+
const idx = items.findIndex((i) => i.key === item.key);
|
|
38480
|
+
if (idx >= 0) {
|
|
38481
|
+
helpers.updateItem(idx, { label: newName.trim() });
|
|
38482
|
+
}
|
|
38483
|
+
} else {
|
|
38484
|
+
helpers.render();
|
|
38485
|
+
}
|
|
38486
|
+
});
|
|
38487
|
+
return true;
|
|
38488
|
+
}
|
|
38452
38489
|
if (key === "e" || key === "E") {
|
|
38453
38490
|
const currentName = item.label;
|
|
38454
38491
|
helpers.getInput("New name:", currentName).then((newName) => {
|
|
@@ -48620,6 +48657,8 @@ ${entry.fullContent}`
|
|
|
48620
48657
|
let streamStartMs = 0;
|
|
48621
48658
|
let streamTextBuffer = "";
|
|
48622
48659
|
const contentWrite = (fn) => {
|
|
48660
|
+
if (overlayActive)
|
|
48661
|
+
return;
|
|
48623
48662
|
if (statusBar?.isActive) {
|
|
48624
48663
|
statusBar.beginContentWrite();
|
|
48625
48664
|
fn();
|
|
@@ -49371,6 +49410,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
49371
49410
|
}
|
|
49372
49411
|
}
|
|
49373
49412
|
function writeContent(fn) {
|
|
49413
|
+
if (overlayActive)
|
|
49414
|
+
return;
|
|
49374
49415
|
if (statusBar.isActive) {
|
|
49375
49416
|
statusBar.beginContentWrite();
|
|
49376
49417
|
try {
|
|
@@ -49698,6 +49739,18 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
49698
49739
|
voiceSetMode(mode) {
|
|
49699
49740
|
voiceEngine.voiceMode = mode;
|
|
49700
49741
|
},
|
|
49742
|
+
voiceIsEnabled() {
|
|
49743
|
+
return voiceEngine.enabled;
|
|
49744
|
+
},
|
|
49745
|
+
voiceGetModel() {
|
|
49746
|
+
return voiceEngine.modelId ?? "unknown";
|
|
49747
|
+
},
|
|
49748
|
+
voiceGetLastClonedFilename() {
|
|
49749
|
+
return voiceEngine.lastClonedFilename;
|
|
49750
|
+
},
|
|
49751
|
+
setOverlayActive(active) {
|
|
49752
|
+
overlayActive = active;
|
|
49753
|
+
},
|
|
49701
49754
|
streamToggle() {
|
|
49702
49755
|
streamEnabled = !streamEnabled;
|
|
49703
49756
|
return streamEnabled;
|
|
@@ -51386,7 +51439,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
51386
51439
|
process.exit(1);
|
|
51387
51440
|
}
|
|
51388
51441
|
}
|
|
51389
|
-
var taskManager;
|
|
51442
|
+
var overlayActive, taskManager;
|
|
51390
51443
|
var init_interactive = __esm({
|
|
51391
51444
|
"packages/cli/dist/tui/interactive.js"() {
|
|
51392
51445
|
"use strict";
|
|
@@ -51422,6 +51475,7 @@ var init_interactive = __esm({
|
|
|
51422
51475
|
init_telegram_bridge();
|
|
51423
51476
|
init_status_bar();
|
|
51424
51477
|
init_dist6();
|
|
51478
|
+
overlayActive = false;
|
|
51425
51479
|
taskManager = new BackgroundTaskManager();
|
|
51426
51480
|
}
|
|
51427
51481
|
});
|
package/package.json
CHANGED