open-agents-ai 0.138.26 → 0.138.28

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 +84 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -39293,20 +39293,13 @@ var init_voice = __esm({
39293
39293
  }
39294
39294
  if (this.checkMlxInstalled())
39295
39295
  return;
39296
- renderInfo("Installing MLX Audio for voice synthesis (first time setup)...");
39296
+ renderInfo("Installing MLX Audio for voice synthesis (background)...");
39297
39297
  try {
39298
- execSync26(`${py} -m pip install mlx-audio --quiet`, {
39299
- stdio: "pipe",
39300
- timeout: 3e5
39301
- // 5 min — may need to compile
39302
- });
39298
+ await this.asyncShell(`${py} -m pip install mlx-audio --quiet`, 3e5);
39303
39299
  this.mlxInstalled = true;
39304
39300
  } catch (err) {
39305
39301
  try {
39306
- execSync26(`${py} -m pip install mlx-audio --user --quiet`, {
39307
- stdio: "pipe",
39308
- timeout: 3e5
39309
- });
39302
+ await this.asyncShell(`${py} -m pip install mlx-audio --user --quiet`, 3e5);
39310
39303
  this.mlxInstalled = true;
39311
39304
  } catch (err2) {
39312
39305
  throw new Error(`Failed to install mlx-audio. Try manually: pip install mlx-audio
@@ -39913,36 +39906,31 @@ if __name__ == '__main__':
39913
39906
  }, null, 2));
39914
39907
  }
39915
39908
  const voiceRequire = createRequire(join50(voiceDir(), "index.js"));
39916
- const probeOnnx = () => {
39909
+ const probeOnnx = async () => {
39917
39910
  try {
39918
- const result = execSync26(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join50(voiceDir(), "node_modules") } });
39919
- const output = result.toString().trim();
39920
- return output === "OK";
39911
+ const output = await this.asyncShell(`NODE_PATH="${join50(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
39912
+ return output.trim() === "OK";
39921
39913
  } catch {
39922
39914
  return false;
39923
39915
  }
39924
39916
  };
39925
39917
  const onnxNodeModules = join50(voiceDir(), "node_modules", "onnxruntime-node");
39926
39918
  const onnxInstalled = existsSync35(onnxNodeModules);
39927
- if (onnxInstalled && !probeOnnx()) {
39919
+ if (onnxInstalled && !await probeOnnx()) {
39928
39920
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
39929
39921
  }
39930
39922
  try {
39931
39923
  this.ort = voiceRequire("onnxruntime-node");
39932
39924
  } catch {
39933
- renderInfo("Installing ONNX runtime for voice synthesis...");
39925
+ renderInfo("Installing ONNX runtime for voice synthesis (background)...");
39934
39926
  try {
39935
- execSync26("npm install --no-audit --no-fund", {
39936
- cwd: voiceDir(),
39937
- stdio: "pipe",
39938
- timeout: 12e4
39939
- });
39927
+ await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
39940
39928
  } catch (err) {
39941
39929
  const archHint = arch !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch}.` : "";
39942
39930
  throw new Error(`Failed to install voice dependencies.${archHint} Try manually: cd ${voiceDir()} && npm install
39943
39931
  Error: ${err instanceof Error ? err.message : String(err)}`);
39944
39932
  }
39945
- if (!probeOnnx()) {
39933
+ if (!await probeOnnx()) {
39946
39934
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
39947
39935
  }
39948
39936
  try {
@@ -39955,13 +39943,9 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
39955
39943
  const phonemizerMod = voiceRequire("phonemizer");
39956
39944
  this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
39957
39945
  } catch {
39958
- renderInfo("Installing phonemizer for voice synthesis...");
39946
+ renderInfo("Installing phonemizer for voice synthesis (background)...");
39959
39947
  try {
39960
- execSync26("npm install --no-audit --no-fund", {
39961
- cwd: voiceDir(),
39962
- stdio: "pipe",
39963
- timeout: 12e4
39964
- });
39948
+ await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
39965
39949
  const phonemizerMod = voiceRequire("phonemizer");
39966
39950
  this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
39967
39951
  } catch (err) {
@@ -41951,7 +41935,7 @@ async function handleVoiceList(ctx, focusFilename) {
41951
41935
  title: focusFilename ? "Voice Clone References \u2014 Press any key to name your new voice" : "Voice Clone References",
41952
41936
  rl: ctx.rl,
41953
41937
  availableRows: ctx.availableContentRows?.(),
41954
- customKeyHint: " e rename p play",
41938
+ customKeyHint: " e rename p play x export i import",
41955
41939
  onDelete: (item, done) => {
41956
41940
  if (ctx.voiceDeleteClone?.(item.key)) {
41957
41941
  done(true);
@@ -42003,6 +41987,55 @@ async function handleVoiceList(ctx, focusFilename) {
42003
41987
  });
42004
41988
  return true;
42005
41989
  }
41990
+ if (key === "x" || key === "X") {
41991
+ const clone = clones.find((cl) => cl.filename === item.key);
41992
+ if (!clone)
41993
+ return false;
41994
+ const { join: pjoin2 } = __require("node:path");
41995
+ const defaultPath = pjoin2(process.cwd(), clone.filename);
41996
+ helpers.getInput("Export to:", defaultPath).then((destPath) => {
41997
+ if (destPath !== null && destPath.trim()) {
41998
+ try {
41999
+ const { copyFileSync: copyFileSync2 } = __require("node:fs");
42000
+ copyFileSync2(clone.path, destPath.trim());
42001
+ renderInfo(`Exported "${clone.name}" \u2192 ${destPath.trim()}`);
42002
+ } catch (err) {
42003
+ renderError(`Export failed: ${err.message}`);
42004
+ }
42005
+ }
42006
+ helpers.render();
42007
+ });
42008
+ return true;
42009
+ }
42010
+ if (key === "i" || key === "I") {
42011
+ helpers.getInput("Import from (file path):").then((srcPath) => {
42012
+ if (srcPath !== null && srcPath.trim()) {
42013
+ const src = srcPath.trim();
42014
+ try {
42015
+ const { existsSync: fe, copyFileSync: cpf, mkdirSync: mkd } = __require("node:fs");
42016
+ const { basename: basename16, join: pjoin } = __require("node:path");
42017
+ if (!fe(src)) {
42018
+ renderError(`File not found: ${src}`);
42019
+ helpers.render();
42020
+ return;
42021
+ }
42022
+ const refsDir = pjoin(__require("node:os").homedir(), ".open-agents", "voice", "clone-refs");
42023
+ mkd(refsDir, { recursive: true });
42024
+ const destName = basename16(src);
42025
+ const dest = pjoin(refsDir, destName);
42026
+ cpf(src, dest);
42027
+ renderInfo(`Imported "${destName}" \u2192 ${dest}`);
42028
+ helpers.done();
42029
+ } catch (err) {
42030
+ renderError(`Import failed: ${err.message}`);
42031
+ helpers.render();
42032
+ }
42033
+ } else {
42034
+ helpers.render();
42035
+ }
42036
+ });
42037
+ return true;
42038
+ }
42006
42039
  return false;
42007
42040
  }
42008
42041
  });
@@ -53722,17 +53755,26 @@ async function startInteractive(config, repoPath) {
53722
53755
  const streamRenderer = new StreamRenderer();
53723
53756
  streamRenderer.onRenderedLine = (line) => statusBar.bufferContentLine(line);
53724
53757
  if (savedSettings.voice) {
53725
- voiceEngine.toggle().catch((err) => {
53758
+ if (savedSettings.voiceModel) {
53759
+ voiceEngine.modelId = savedSettings.voiceModel;
53760
+ }
53761
+ if (savedSettings.voiceCloneRef) {
53762
+ voiceEngine.luxttsCloneRef = savedSettings.voiceCloneRef;
53763
+ }
53764
+ voiceEngine.toggle().then((msg) => {
53765
+ if (statusBar?.isActive && !statusBar.isStreaming) {
53766
+ statusBar.beginContentWrite();
53767
+ renderInfo(msg);
53768
+ statusBar.endContentWrite();
53769
+ }
53770
+ }).catch((err) => {
53726
53771
  const msg = err instanceof Error ? err.message : String(err);
53727
- if (msg.includes("ONNX runtime crashes") || msg.includes("unavailable")) {
53728
- renderWarning(`Voice disabled: ${msg}`);
53729
- renderInfo("All other features work normally. Use /voice to retry later.");
53772
+ if (statusBar?.isActive && !statusBar.isStreaming) {
53773
+ statusBar.beginContentWrite();
53774
+ renderWarning(`Voice: ${msg.slice(0, 80)}`);
53775
+ statusBar.endContentWrite();
53730
53776
  }
53731
53777
  });
53732
- if (savedSettings.voiceModel) {
53733
- voiceEngine.setModel(savedSettings.voiceModel).catch(() => {
53734
- });
53735
- }
53736
53778
  }
53737
53779
  if (savedSettings.voiceMode) {
53738
53780
  voiceEngine.voiceMode = savedSettings.voiceMode;
@@ -54400,7 +54442,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
54400
54442
  voiceEngine.renameCloneRef(filename, newName);
54401
54443
  },
54402
54444
  voiceSetActiveClone(filename) {
54403
- return voiceEngine.setActiveCloneRef(filename);
54445
+ const msg = voiceEngine.setActiveCloneRef(filename);
54446
+ if (voiceEngine.luxttsCloneRef) {
54447
+ saveGlobalSettings({ voiceCloneRef: voiceEngine.luxttsCloneRef });
54448
+ }
54449
+ return msg;
54404
54450
  },
54405
54451
  voiceSpeak(text) {
54406
54452
  voiceEngine.speak(text);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.26",
3
+ "version": "0.138.28",
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",