open-agents-ai 0.187.335 → 0.187.337

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 +62 -42
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -278120,17 +278120,20 @@ function findLiveWhisperScript() {
278120
278120
  }
278121
278121
  return null;
278122
278122
  }
278123
- function ensureVenvOnPath() {
278123
+ function ensureVenvForTranscribeCli() {
278124
278124
  const bin = process.platform === "win32" ? "Scripts" : "bin";
278125
+ const exe = process.platform === "win32" ? "python.exe" : "python3";
278125
278126
  const venvBin = join69(homedir24(), ".open-agents", "venv", bin);
278126
- if (!existsSync53(venvBin)) return false;
278127
+ const venvPython2 = join69(venvBin, exe);
278128
+ if (!existsSync53(venvPython2)) return false;
278129
+ process.env.TRANSCRIBE_PYTHON = venvPython2;
278127
278130
  const pathSep2 = process.platform === "win32" ? ";" : ":";
278128
278131
  const currentPath = process.env.PATH || "";
278129
278132
  if (!currentPath.split(pathSep2).includes(venvBin)) {
278130
278133
  process.env.PATH = `${venvBin}${pathSep2}${currentPath}`;
278131
278134
  }
278132
278135
  try {
278133
- execSync44('python3 -c "import numpy"', { stdio: "pipe", timeout: 1e4 });
278136
+ execSync44(`"${venvPython2}" -c "import numpy"`, { stdio: "pipe", timeout: 1e4 });
278134
278137
  return true;
278135
278138
  } catch {
278136
278139
  return false;
@@ -278461,7 +278464,7 @@ var init_listen = __esm({
278461
278464
  if (tc) {
278462
278465
  const TranscribeLive = tc.TranscribeLive;
278463
278466
  if (TranscribeLive) {
278464
- const venvReady = ensureVenvOnPath();
278467
+ const venvReady = ensureVenvForTranscribeCli();
278465
278468
  if (!venvReady) {
278466
278469
  transcribeCliError = "venv Python missing numpy (required by transcribe-cli) — using whisper fallback";
278467
278470
  } else {
@@ -278653,7 +278656,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
278653
278656
  } catch {
278654
278657
  }
278655
278658
  }
278656
- if (tc?.TranscribeLive && ensureVenvOnPath()) {
278659
+ if (tc?.TranscribeLive && ensureVenvForTranscribeCli()) {
278657
278660
  try {
278658
278661
  const transcriber = new tc.TranscribeLive({
278659
278662
  model: this.config.model,
@@ -278707,7 +278710,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
278707
278710
  }
278708
278711
  }
278709
278712
  if (!tc) return null;
278710
- ensureVenvOnPath();
278713
+ ensureVenvForTranscribeCli();
278711
278714
  try {
278712
278715
  const result = await tc.transcribe(filePath, {
278713
278716
  model: this.config.model,
@@ -297362,8 +297365,10 @@ async function ensureVoiceDeps(ctx3) {
297362
297365
  if (typeof mod2.getVenvPython === "function") {
297363
297366
  const { dirname: dirname32 } = await import("node:path");
297364
297367
  const { existsSync: existsSync87 } = await import("node:fs");
297365
- const venvBin = dirname32(mod2.getVenvPython());
297366
- if (existsSync87(venvBin)) {
297368
+ const venvPy = mod2.getVenvPython();
297369
+ if (existsSync87(venvPy)) {
297370
+ process.env.TRANSCRIBE_PYTHON = venvPy;
297371
+ const venvBin = dirname32(venvPy);
297367
297372
  const sep = process.platform === "win32" ? ";" : ":";
297368
297373
  const cur = process.env.PATH || "";
297369
297374
  if (!cur.split(sep).includes(venvBin)) {
@@ -299703,51 +299708,66 @@ sleep 1
299703
299708
  done(false);
299704
299709
  return;
299705
299710
  }
299711
+ const isSystemdTimer = String(task.id || "").startsWith("timer:") || task.file === "(systemd)" || task.index === -1;
299706
299712
  (async () => {
299707
299713
  try {
299708
299714
  const r3 = await doFetch(`/v1/scheduled/${encodeURIComponent(task.id)}`, { method: "DELETE", headers: { "Content-Type": "application/json" } });
299709
299715
  if (r3.ok) {
299710
299716
  renderInfo2(`Deleted scheduled task ${task.id}`);
299711
- try {
299712
- const dir = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
299713
- const resp = await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ pattern: dir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") }) });
299717
+ if (isSystemdTimer) {
299714
299718
  try {
299715
- const j = await resp.json();
299716
- const cnt = (Array.isArray(j.killed) ? j.killed.length : 0) + (Array.isArray(j.additionally) ? j.additionally.length : 0);
299717
- if (cnt > 0) renderInfo2(`Killed ${cnt} residual process(es).`);
299719
+ const timerName = String(task.id || "").replace(/^timer:/, "");
299720
+ const { execSync: es } = await import("node:child_process");
299721
+ const userSystemd = `${process.env.HOME}/.config/systemd/user`;
299722
+ for (const suffix of [".timer", ".service"]) {
299723
+ try {
299724
+ es(`rm -f "${userSystemd}/${timerName}${suffix}"`, { stdio: "pipe" });
299725
+ } catch {
299726
+ }
299727
+ }
299728
+ try {
299729
+ es("systemctl --user daemon-reload", { stdio: "pipe" });
299730
+ } catch {
299731
+ }
299732
+ try {
299733
+ es(`pkill -f '${timerName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}' || true`, { stdio: "pipe", timeout: 5e3 });
299734
+ } catch {
299735
+ }
299736
+ renderInfo2(`Cleaned up systemd timer: ${timerName}`);
299718
299737
  } catch {
299719
299738
  }
299720
- } catch {
299721
- }
299722
- try {
299723
- const id = String(task.id || "");
299724
- const dir = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
299725
- const escId = id.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
299726
- const escDir = dir.replace(/['"\\]/g, "\\$&");
299727
- const script = [
299728
- // Disable both naming schemes if present
299729
- `systemctl disable --now "oa-${escId}.timer" 2>/dev/null || true`,
299730
- `systemctl disable --now "oa-${escId}.service" 2>/dev/null || true`,
299731
- `systemctl disable --now "oa-sched-${escId}.timer" 2>/dev/null || true`,
299732
- `systemctl disable --now "oa-sched-${escId}.service" 2>/dev/null || true`,
299733
- // Remove root cron OA markers for this id
299734
- `crontab -l 2>/dev/null | sed '/OPEN-AGENTS-SCHEDULED:${escId}/d' | crontab - || true`,
299735
- // Kill lingering processes broadly
299736
- `pkill -f 'OPEN-AGENTS-SCHEDULED|oa-sched-|open-agents-ai|/bin/oa|nexus-daemon|ollama' || true`,
299737
- `sleep 1`,
299738
- `pkill -9 -f 'OPEN-AGENTS-SCHEDULED|oa-sched-|open-agents-ai|/bin/oa|nexus-daemon|ollama' || true`
299739
- ].join("; ");
299740
- await runSudoScript(ctx3, script);
299739
+ } else {
299741
299740
  try {
299742
- const dir2 = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
299743
- const r22 = await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ pattern: dir2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") }) });
299744
- const j2 = await r22.json();
299745
- const rem2 = Array.isArray(j2.procs_after) ? j2.procs_after.length : 0;
299746
- if (rem2 > 0) renderWarning2(`Remaining after sudo cleanup: ${rem2}`);
299747
- else renderInfo2("No remaining matched processes after sudo cleanup.");
299741
+ const dir = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
299742
+ const resp = await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ pattern: dir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") }) });
299743
+ try {
299744
+ const j = await resp.json();
299745
+ const cnt = (Array.isArray(j.killed) ? j.killed.length : 0) + (Array.isArray(j.additionally) ? j.additionally.length : 0);
299746
+ if (cnt > 0) renderInfo2(`Killed ${cnt} residual process(es).`);
299747
+ } catch {
299748
+ }
299749
+ } catch {
299750
+ }
299751
+ try {
299752
+ const rawId = String(task.id || "");
299753
+ const dir = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
299754
+ const baseId = rawId.replace(/^timer:/, "").replace(/^oa-sched-/, "").replace(/^oa-/, "");
299755
+ const escBase = baseId.replace(/['"\\]/g, "\\$&");
299756
+ const escDir = dir.replace(/['"\\]/g, "\\$&");
299757
+ const script = [
299758
+ // Disable both naming schemes if present
299759
+ `systemctl disable --now "oa-${escBase}.timer" 2>/dev/null || true`,
299760
+ `systemctl disable --now "oa-${escBase}.service" 2>/dev/null || true`,
299761
+ `systemctl disable --now "oa-sched-${escBase}.timer" 2>/dev/null || true`,
299762
+ `systemctl disable --now "oa-sched-${escBase}.service" 2>/dev/null || true`,
299763
+ // Remove root cron OA markers for this id
299764
+ `crontab -l 2>/dev/null | sed '/OPEN-AGENTS-SCHEDULED.*${escBase}/d' | crontab - || true`,
299765
+ // Kill only processes matching this specific task (not all OA/ollama/nexus)
299766
+ `pkill -f 'OPEN-AGENTS-SCHEDULED.*${escBase}' || true`
299767
+ ].join("; ");
299768
+ await runSudoScript(ctx3, script);
299748
299769
  } catch {
299749
299770
  }
299750
- } catch {
299751
299771
  }
299752
299772
  done(true);
299753
299773
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.335",
3
+ "version": "0.187.337",
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",