open-agents-ai 0.187.169 → 0.187.172

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 +100 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -258533,10 +258533,28 @@ var init_asr_listen = __esm({
258533
258533
  mkdirSync17(captureDir, { recursive: true });
258534
258534
  const audioFile = join51(captureDir, `listen-${Date.now()}.wav`);
258535
258535
  try {
258536
- execSync39(`arecord -D ${device} -f S16_LE -r 16000 -c 1 -d ${duration} -q ${audioFile}`, {
258537
- timeout: (duration + 5) * 1e3,
258538
- stdio: "pipe"
258539
- });
258536
+ try {
258537
+ execSync39(`which pw-record`, { stdio: "pipe", timeout: 2e3 });
258538
+ const child = __require("child_process").spawnSync("pw-record", [
258539
+ "--channels",
258540
+ "1",
258541
+ "--rate",
258542
+ "16000",
258543
+ "--format",
258544
+ "s16",
258545
+ audioFile
258546
+ ], { timeout: (duration + 3) * 1e3, stdio: "pipe", killSignal: "SIGINT" });
258547
+ execSync39(`pw-record --channels 1 --rate 16000 --format s16 ${audioFile} & PID=$!; sleep ${duration}; kill $PID 2>/dev/null; wait $PID 2>/dev/null`, {
258548
+ timeout: (duration + 5) * 1e3,
258549
+ stdio: "pipe",
258550
+ shell: "/bin/bash"
258551
+ });
258552
+ } catch {
258553
+ execSync39(`arecord -D ${device} -f S16_LE -r 16000 -c 1 -d ${duration} -q ${audioFile}`, {
258554
+ timeout: (duration + 5) * 1e3,
258555
+ stdio: "pipe"
258556
+ });
258557
+ }
258540
258558
  } catch (err) {
258541
258559
  return { success: false, output: "", error: `Recording failed: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
258542
258560
  }
@@ -258554,73 +258572,98 @@ var init_asr_listen = __esm({
258554
258572
  return this.doTranscribe(file, language, 0, start2);
258555
258573
  }
258556
258574
  doTranscribe(audioFile, language, recordDuration, start2) {
258557
- try {
258558
- const langArg = language !== "auto" ? `--language ${language}` : "";
258559
- const transcript = execSync39(`transcribe-cli ${langArg} "${audioFile}" 2>/dev/null`, { encoding: "utf8", timeout: 12e4 }).trim();
258560
- if (transcript && transcript.length > 0 && !transcript.includes("transcribe-cli")) {
258561
- return {
258562
- success: true,
258563
- output: `Transcription (${recordDuration > 0 ? recordDuration + "s recording, " : ""}Whisper):
258575
+ const os8 = __require("node:os");
258576
+ const fs4 = __require("node:fs");
258577
+ const path5 = __require("node:path");
258578
+ const homeDir = os8.homedir();
258579
+ const tmpDir = os8.tmpdir();
258580
+ const langArg = language !== "auto" ? `"${language}"` : "None";
258581
+ const whisperScript = `
258582
+ import sys, json, os, warnings
258583
+ warnings.filterwarnings("ignore")
258584
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
258564
258585
 
258565
- "${transcript}"
258586
+ audio_file = "${audioFile.replace(/\\/g, "/")}"
258587
+ lang = ${langArg}
258566
258588
 
258567
- Audio file: ${audioFile}`,
258568
- durationMs: performance.now() - start2
258569
- };
258570
- }
258571
- } catch {
258572
- }
258573
- try {
258574
- const venvPy = join51(__require("os").homedir(), ".open-agents", "venv", "bin", "python3");
258575
- if (existsSync37(venvPy)) {
258576
- const script = `
258577
- import sys
258589
+ # Try faster-whisper first (faster, lower memory)
258578
258590
  try:
258579
258591
  from faster_whisper import WhisperModel
258580
- model = WhisperModel("base", device="cpu", compute_type="int8")
258581
- segments, info = model.transcribe("${audioFile}", language="${language === "auto" ? "" : language}" or None)
258582
- text = " ".join(seg.text.strip() for seg in segments)
258583
- print(text)
258584
- except Exception as e:
258585
- print(f"ERROR: {e}", file=sys.stderr)
258586
- sys.exit(1)
258592
+ model = WhisperModel("base", device="auto", compute_type="int8")
258593
+ segments, info = model.transcribe(audio_file, language=lang if lang else None)
258594
+ text = " ".join(seg.text.strip() for seg in segments).strip()
258595
+ if text:
258596
+ print(json.dumps({"ok": True, "text": text, "backend": "faster-whisper"}))
258597
+ sys.exit(0)
258598
+ except Exception:
258599
+ pass
258600
+
258601
+ # Try openai-whisper
258602
+ try:
258603
+ import whisper
258604
+ model = whisper.load_model("base")
258605
+ result = model.transcribe(audio_file, language=lang if lang else None)
258606
+ text = result.get("text", "").strip()
258607
+ if text:
258608
+ print(json.dumps({"ok": True, "text": text, "backend": "openai-whisper"}))
258609
+ sys.exit(0)
258610
+ except Exception:
258611
+ pass
258612
+
258613
+ print(json.dumps({"ok": False, "error": "No whisper backend available"}))
258587
258614
  `;
258588
- const scriptFile = join51(__require("os").tmpdir(), `oa-whisper-${Date.now()}.py`);
258589
- __require("fs").writeFileSync(scriptFile, script);
258590
- const transcript = execSync39(`${venvPy} ${scriptFile}`, { encoding: "utf8", timeout: 12e4 }).trim();
258591
- if (transcript && !transcript.startsWith("ERROR")) {
258592
- return {
258593
- success: true,
258594
- output: `Transcription (faster-whisper):
258595
-
258596
- "${transcript}"
258597
-
258598
- Audio file: ${audioFile}`,
258599
- durationMs: performance.now() - start2
258600
- };
258615
+ const pyPaths = [
258616
+ path5.join(homeDir, ".open-agents", "venv", "bin", "python3"),
258617
+ "python3",
258618
+ "python"
258619
+ ];
258620
+ for (const pyPath of pyPaths) {
258621
+ if (pyPath.includes("/") && !fs4.existsSync(pyPath))
258622
+ continue;
258623
+ const scriptFile = path5.join(tmpDir, `oa-asr-${Date.now()}.py`);
258624
+ fs4.writeFileSync(scriptFile, whisperScript);
258625
+ try {
258626
+ const output = execSync39(`"${pyPath}" "${scriptFile}"`, {
258627
+ encoding: "utf8",
258628
+ timeout: 12e4,
258629
+ env: { ...process.env, PYTHONUNBUFFERED: "1" }
258630
+ }).trim();
258631
+ try {
258632
+ fs4.unlinkSync(scriptFile);
258633
+ } catch {
258601
258634
  }
258602
- }
258603
- } catch {
258604
- }
258605
- try {
258606
- const transcript = execSync39(`whisper "${audioFile}" --language ${language} --model base --output_format txt 2>/dev/null`, { encoding: "utf8", timeout: 12e4 }).trim();
258607
- if (transcript) {
258608
- return {
258609
- success: true,
258610
- output: `Transcription (whisper):
258635
+ const lines = output.split("\n");
258636
+ for (let i2 = lines.length - 1; i2 >= 0; i2--) {
258637
+ try {
258638
+ const result = JSON.parse(lines[i2]);
258639
+ if (result.ok && result.text) {
258640
+ return {
258641
+ success: true,
258642
+ output: `Transcription (${result.backend}, ${recordDuration > 0 ? recordDuration + "s recording" : "file"}):
258611
258643
 
258612
- "${transcript}"
258644
+ "${result.text}"
258613
258645
 
258614
258646
  Audio file: ${audioFile}`,
258615
- durationMs: performance.now() - start2
258616
- };
258647
+ durationMs: performance.now() - start2
258648
+ };
258649
+ }
258650
+ if (!result.ok)
258651
+ continue;
258652
+ } catch {
258653
+ continue;
258654
+ }
258655
+ }
258656
+ } catch {
258657
+ try {
258658
+ fs4.unlinkSync(scriptFile);
258659
+ } catch {
258660
+ }
258617
258661
  }
258618
- } catch {
258619
258662
  }
258620
258663
  return {
258621
258664
  success: false,
258622
258665
  output: `Audio recorded to: ${audioFile}`,
258623
- error: "Transcription failed \u2014 no Whisper backend available. Install: pip install faster-whisper",
258666
+ error: "Transcription failed. Install whisper: pip install openai-whisper OR pip install faster-whisper",
258624
258667
  durationMs: performance.now() - start2
258625
258668
  };
258626
258669
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.169",
3
+ "version": "0.187.172",
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",