open-agents-ai 0.185.33 → 0.185.34

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.
Files changed (2) hide show
  1. package/dist/index.js +85 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -49640,6 +49640,36 @@ async function handleSlashCommand(input, ctx) {
49640
49640
  }
49641
49641
  if (arg.startsWith("clone")) {
49642
49642
  const cloneArg = arg.replace(/^clone\s*/, "").trim();
49643
+ const currentVoiceModel = ctx.voiceGetModel?.() ?? "glados";
49644
+ if (currentVoiceModel === "personaplex") {
49645
+ if (!cloneArg) {
49646
+ const dropResult = await showDropPanel({
49647
+ title: "PersonaPlex Voice Clone \u2014 Drop Audio File",
49648
+ instruction: "Drop a WAV file (4-10s clean speech) to clone into PersonaPlex",
49649
+ allowedExtensions: [".wav", ".mp3", ".ogg", ".flac", ".m4a", ".opus", ".aac"],
49650
+ typeLabel: "Audio files",
49651
+ rl: ctx.rl
49652
+ });
49653
+ if (dropResult.confirmed && dropResult.path) {
49654
+ const voiceName2 = dropResult.path.replace(/.*[\\/]/, "").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "_");
49655
+ const { clonePersonaPlexVoice: clonePersonaPlexVoice3 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
49656
+ const result2 = await clonePersonaPlexVoice3(dropResult.path, voiceName2, (m) => renderInfo(m));
49657
+ if (result2)
49658
+ renderInfo(`Voice "${voiceName2}" ready \u2014 use /voice list to see all voices`);
49659
+ } else {
49660
+ renderInfo("Voice clone cancelled.");
49661
+ }
49662
+ return "handled";
49663
+ }
49664
+ const parts = cloneArg.split(/\s+/);
49665
+ const wavPath = parts[0];
49666
+ const voiceName = parts[1] || wavPath.replace(/.*[\\/]/, "").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "_");
49667
+ const { clonePersonaPlexVoice: clonePersonaPlexVoice2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
49668
+ const result = await clonePersonaPlexVoice2(wavPath, voiceName, (m) => renderInfo(m));
49669
+ if (result)
49670
+ renderInfo(`Voice "${voiceName}" ready for PersonaPlex`);
49671
+ return "handled";
49672
+ }
49643
49673
  if (!cloneArg) {
49644
49674
  const dropResult = await showDropPanel({
49645
49675
  title: "Voice Clone \u2014 Drop Audio File",
@@ -49679,7 +49709,60 @@ async function handleSlashCommand(input, ctx) {
49679
49709
  return "handled";
49680
49710
  }
49681
49711
  if (arg === "list" || arg === "ls" || arg === "voices") {
49682
- await handleVoiceList(ctx);
49712
+ const currentVoiceModel = ctx.voiceGetModel?.() ?? "glados";
49713
+ if (currentVoiceModel === "personaplex") {
49714
+ const { listPersonaPlexVoices: listPersonaPlexVoices2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
49715
+ const voices = listPersonaPlexVoices2();
49716
+ const builtins = voices.filter((v) => v.type === "builtin");
49717
+ const customs = voices.filter((v) => v.type === "custom");
49718
+ renderInfo("PersonaPlex Voices:");
49719
+ renderInfo(" Natural (F): " + builtins.filter((v) => v.name.startsWith("NATF")).map((v) => v.name).join(", "));
49720
+ renderInfo(" Natural (M): " + builtins.filter((v) => v.name.startsWith("NATM")).map((v) => v.name).join(", "));
49721
+ renderInfo(" Variety (F): " + builtins.filter((v) => v.name.startsWith("VARF")).map((v) => v.name).join(", "));
49722
+ renderInfo(" Variety (M): " + builtins.filter((v) => v.name.startsWith("VARM")).map((v) => v.name).join(", "));
49723
+ if (customs.length > 0) {
49724
+ renderInfo(" Custom: " + customs.map((v) => v.name).join(", "));
49725
+ }
49726
+ renderInfo(`
49727
+ Clone a new voice: /voice clone <wav-file> [name]`);
49728
+ } else {
49729
+ await handleVoiceList(ctx);
49730
+ }
49731
+ return "handled";
49732
+ }
49733
+ if (arg === "personaplex" || arg === "pp") {
49734
+ const { detectPersonaPlexCapability: detectPersonaPlexCapability2, isPersonaPlexInstalled: isPersonaPlexInstalled2, installPersonaPlex: installPersonaPlex2, startPersonaPlexDaemon: startPersonaPlexDaemon2, isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
49735
+ const caps = detectPersonaPlexCapability2();
49736
+ if (!caps.supported) {
49737
+ renderWarning(`PersonaPlex not available: ${caps.reason}`);
49738
+ renderInfo("Requirements: NVIDIA GPU with \u22658GB VRAM (RTX 3060+, Jetson AGX Orin), CUDA, PyTorch");
49739
+ return "handled";
49740
+ }
49741
+ save({ voice: true, voiceModel: "personaplex" });
49742
+ renderInfo(`Voice system: personaplex (${caps.weightTier} tier, ${caps.vramGB.toFixed(0)}GB VRAM)`);
49743
+ if (!isPersonaPlexInstalled2()) {
49744
+ renderInfo("Setting up PersonaPlex in background...");
49745
+ (async () => {
49746
+ try {
49747
+ const ok = await installPersonaPlex2((m) => renderInfo(m), caps.weightTier);
49748
+ if (ok && !isPersonaPlexRunning2()) {
49749
+ const url = await startPersonaPlexDaemon2((m) => renderInfo(m));
49750
+ if (url)
49751
+ renderInfo(`PersonaPlex ready at ${url}`);
49752
+ }
49753
+ } catch (e) {
49754
+ renderError(`PersonaPlex: ${e instanceof Error ? e.message : String(e)}`);
49755
+ }
49756
+ })();
49757
+ } else if (!isPersonaPlexRunning2()) {
49758
+ startPersonaPlexDaemon2((m) => renderInfo(m)).then((url) => {
49759
+ if (url)
49760
+ renderInfo(`PersonaPlex ready at ${url}`);
49761
+ }).catch(() => {
49762
+ });
49763
+ } else {
49764
+ renderInfo("PersonaPlex daemon already running. Use /call for full-duplex voice.");
49765
+ }
49683
49766
  return "handled";
49684
49767
  }
49685
49768
  const msg = await ctx.voiceSetModel(arg);
@@ -50780,7 +50863,7 @@ async function showConfigEditor(ctx) {
50780
50863
  { key: "style", label: "style", kind: "enum", value: String(ctx.getStyle?.() ?? merged.style ?? "balanced"), detail: String(ctx.getStyle?.() ?? merged.style ?? "balanced"), options: [...PRESET_NAMES], settingsKey: "style" },
50781
50864
  { key: "__h_voice__", label: c2.dim("\u2500\u2500 Voice \u2500\u2500"), detail: "", kind: "header", value: "" },
50782
50865
  { key: "voice", label: "voice", kind: "boolean", value: String(merged.voice ?? false), detail: String(merged.voice ?? false), settingsKey: "voice" },
50783
- { key: "voiceModel", label: "voiceModel", kind: "enum", value: String(merged.voiceModel ?? "glados"), detail: String(merged.voiceModel ?? "glados"), options: ["glados", "overwatch", "kokoro", "luxtts"], settingsKey: "voiceModel" },
50866
+ { key: "voiceModel", label: "voiceModel", kind: "enum", value: String(merged.voiceModel ?? "glados"), detail: String(merged.voiceModel ?? "glados"), options: ["glados", "overwatch", "kokoro", "luxtts", "personaplex"], settingsKey: "voiceModel" },
50784
50867
  { key: "__h_auto__", label: c2.dim("\u2500\u2500 Autonomy \u2500\u2500"), detail: "", kind: "header", value: "" },
50785
50868
  { key: "commandsMode", label: "commandsMode", kind: "enum", value: String(ctx.getCommandsMode?.() ?? merged.commandsMode ?? "manual"), detail: String(ctx.getCommandsMode?.() ?? merged.commandsMode ?? "manual"), options: ["manual", "auto"], settingsKey: "commandsMode" },
50786
50869
  { key: "updateMode", label: "updateMode", kind: "enum", value: String(merged.updateMode ?? "auto"), detail: String(merged.updateMode ?? "auto"), options: ["auto", "manual"], settingsKey: "updateMode" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.185.33",
3
+ "version": "0.185.34",
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",