open-agents-ai 0.184.20 → 0.184.22

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 +109 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -46470,6 +46470,34 @@ function safeLog(text) {
46470
46470
  process.stdout.write(text + "\n");
46471
46471
  }
46472
46472
  }
46473
+ function findPidsByPattern(pattern) {
46474
+ const isWin2 = process.platform === "win32";
46475
+ try {
46476
+ if (isWin2) {
46477
+ const out = nodeExecSync(`wmic process where "CommandLine like '%${pattern.replace(/'/g, "")}%'" get ProcessId /format:csv`, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
46478
+ return out.split("\n").map((l) => parseInt(l.split(",").pop() || "", 10)).filter((p) => p > 0 && !isNaN(p));
46479
+ } else {
46480
+ const out = nodeExecSync(`pgrep -f '${pattern}'`, { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
46481
+ return out.trim().split("\n").map((s) => parseInt(s, 10)).filter((p) => p > 0 && !isNaN(p));
46482
+ }
46483
+ } catch {
46484
+ return [];
46485
+ }
46486
+ }
46487
+ function killPid(pid, signal = "SIGTERM") {
46488
+ try {
46489
+ if (process.platform === "win32") {
46490
+ const flag = signal === "SIGKILL" ? "/F" : "";
46491
+ nodeExecSync(`taskkill /PID ${pid} ${flag}`, { timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
46492
+ return true;
46493
+ } else {
46494
+ process.kill(pid, signal);
46495
+ return true;
46496
+ }
46497
+ } catch {
46498
+ return false;
46499
+ }
46500
+ }
46473
46501
  async function destroyOrphanProcesses(ctx, global) {
46474
46502
  const myPid = process.pid;
46475
46503
  const myPpid = process.ppid;
@@ -46479,6 +46507,8 @@ async function destroyOrphanProcesses(ctx, global) {
46479
46507
  // Stale eval/cron OA instances
46480
46508
  "nexus-daemon\\.mjs",
46481
46509
  // Detached nexus daemons
46510
+ "cloudflared tunnel --url",
46511
+ // Detached cloudflared quick tunnels (NOT named tunnels)
46482
46512
  "vitest",
46483
46513
  // Orphaned test runners
46484
46514
  "esbuild.*--service.*--ping",
@@ -46497,31 +46527,71 @@ async function destroyOrphanProcesses(ctx, global) {
46497
46527
  // Moondream vision server
46498
46528
  "live-whisper\\.py",
46499
46529
  // Whisper ASR server
46500
- "jest.*--forceExit"
46530
+ "jest.*--forceExit",
46501
46531
  // Orphaned Jest runners
46532
+ "node.*open-agents-ai.*dist",
46533
+ // Orphaned OA node processes from previous runs
46534
+ "transcribe-cli\\.py",
46535
+ // Audio transcription workers
46536
+ "kokoro-tts\\.py",
46537
+ // Kokoro TTS server
46538
+ "glados-tts\\.py"
46539
+ // GLaDOS TTS server
46502
46540
  ];
46503
46541
  const patternArg = patterns.join("|");
46504
46542
  let killed = 0;
46543
+ const isWin2 = process.platform === "win32";
46505
46544
  try {
46506
- const psOutput = nodeExecSync(`ps -eo pid,ppid,lstart,args --no-headers 2>/dev/null | grep -E "${patternArg}" | grep -v grep`, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
46545
+ let psOutput;
46546
+ if (isWin2) {
46547
+ psOutput = nodeExecSync(`wmic process get ProcessId,ParentProcessId,WorkingSetSize,CommandLine /format:csv`, { encoding: "utf-8", timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] }).trim();
46548
+ } else {
46549
+ psOutput = nodeExecSync(`ps -eo pid,ppid,rss,%cpu,lstart,args --no-headers 2>/dev/null | grep -E "${patternArg}" | grep -v grep`, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
46550
+ }
46507
46551
  if (!psOutput)
46508
46552
  return 0;
46509
46553
  const lines = psOutput.split("\n").filter((l) => l.trim());
46510
46554
  const candidates = [];
46511
- for (const line of lines) {
46512
- const parts = line.trim().split(/\s+/);
46513
- const pid = parseInt(parts[0], 10);
46514
- const ppid = parseInt(parts[1], 10);
46515
- if (pid === myPid || pid === myPpid)
46516
- continue;
46517
- if (pid <= 10)
46518
- continue;
46519
- const cmd = parts.slice(6).join(" ");
46520
- candidates.push({ pid, ppid, cmd });
46555
+ if (isWin2) {
46556
+ for (const line of lines) {
46557
+ const cols = line.split(",");
46558
+ if (cols.length < 5)
46559
+ continue;
46560
+ const cmdLine = cols[1] || "";
46561
+ const ppid = parseInt(cols[2], 10) || 0;
46562
+ const pid = parseInt(cols[3], 10) || 0;
46563
+ const wsBytes = parseInt(cols[4], 10) || 0;
46564
+ if (pid === myPid || pid === myPpid || pid <= 10)
46565
+ continue;
46566
+ const matchesPattern = patterns.some((p) => new RegExp(p.replace(/\\\\/g, "\\")).test(cmdLine));
46567
+ if (!matchesPattern)
46568
+ continue;
46569
+ candidates.push({ pid, ppid, rssMb: Math.round(wsBytes / 1048576), cpuPct: 0, cmd: cmdLine.slice(0, 200) });
46570
+ }
46571
+ } else {
46572
+ for (const line of lines) {
46573
+ const parts = line.trim().split(/\s+/);
46574
+ const pid = parseInt(parts[0], 10);
46575
+ const ppid = parseInt(parts[1], 10);
46576
+ const rssKb = parseInt(parts[2], 10) || 0;
46577
+ const cpuPct = parseFloat(parts[3]) || 0;
46578
+ if (pid === myPid || pid === myPpid)
46579
+ continue;
46580
+ if (pid <= 10)
46581
+ continue;
46582
+ const cmd = parts.slice(8).join(" ");
46583
+ candidates.push({ pid, ppid, rssMb: Math.round(rssKb / 1024), cpuPct, cmd });
46584
+ }
46521
46585
  }
46522
46586
  if (!global) {
46523
46587
  const localCandidates = [];
46524
46588
  for (const c3 of candidates) {
46589
+ if (isWin2) {
46590
+ if (c3.cmd.includes(cwd4.replace(/\//g, "\\")) || /open-agents|nexus-daemon/.test(c3.cmd)) {
46591
+ localCandidates.push(c3);
46592
+ }
46593
+ continue;
46594
+ }
46525
46595
  try {
46526
46596
  const procCwd = nodeExecSync(`readlink /proc/${c3.pid}/cwd 2>/dev/null`, { encoding: "utf-8", timeout: 2e3 }).trim();
46527
46597
  if (procCwd.startsWith(cwd4)) {
@@ -46538,35 +46608,30 @@ async function destroyOrphanProcesses(ctx, global) {
46538
46608
  }
46539
46609
  if (candidates.length === 0)
46540
46610
  return 0;
46541
- renderInfo(`Found ${candidates.length} orphaned OA process(es)${global ? " (system-wide)" : ""}:`);
46611
+ const totalMb = candidates.reduce((sum, c3) => sum + c3.rssMb, 0);
46612
+ const totalCpu = candidates.reduce((sum, c3) => sum + c3.cpuPct, 0);
46613
+ renderInfo(`Found ${candidates.length} orphaned OA process(es)${global ? " (system-wide)" : ""} \u2014 using ${totalMb}MB RAM, ${totalCpu.toFixed(1)}% CPU:`);
46542
46614
  for (const c3 of candidates) {
46543
- const shortCmd = c3.cmd.length > 80 ? c3.cmd.slice(0, 77) + "..." : c3.cmd;
46544
- process.stdout.write(` PID ${c3.pid}: ${shortCmd}
46615
+ const shortCmd = c3.cmd.length > 60 ? c3.cmd.slice(0, 57) + "..." : c3.cmd;
46616
+ const mem = c3.rssMb > 0 ? `${c3.rssMb}MB` : "0MB";
46617
+ const cpu = c3.cpuPct > 0 ? `${c3.cpuPct.toFixed(1)}%` : "0%";
46618
+ process.stdout.write(` PID ${c3.pid} [${mem} / ${cpu}]: ${shortCmd}
46545
46619
  `);
46546
46620
  }
46547
46621
  for (const c3 of candidates) {
46548
- try {
46622
+ if (!isWin2) {
46549
46623
  try {
46550
46624
  process.kill(-c3.pid, "SIGTERM");
46551
46625
  } catch {
46552
46626
  }
46553
- process.kill(c3.pid, "SIGTERM");
46554
- killed++;
46555
- } catch {
46556
- try {
46557
- process.kill(c3.pid, "SIGKILL");
46558
- killed++;
46559
- } catch {
46560
- }
46561
46627
  }
46628
+ if (killPid(c3.pid, "SIGTERM"))
46629
+ killed++;
46562
46630
  }
46563
46631
  if (killed > 0) {
46564
46632
  await new Promise((r) => setTimeout(r, 2e3));
46565
46633
  for (const c3 of candidates) {
46566
- try {
46567
- process.kill(c3.pid, "SIGKILL");
46568
- } catch {
46569
- }
46634
+ killPid(c3.pid, "SIGKILL");
46570
46635
  }
46571
46636
  }
46572
46637
  } catch {
@@ -47995,22 +48060,14 @@ async function handleSlashCommand(input, ctx) {
47995
48060
  renderWarning(`Gateway stop: ${err instanceof Error ? err.message : String(err)}`);
47996
48061
  }
47997
48062
  }
47998
- try {
47999
- const { execSync: execSync34 } = __require("child_process");
48000
- const pids = execSync34("pgrep -f 'cloudflared tunnel --url http://127.0.0.1'", { encoding: "utf8", timeout: 3e3 }).trim().split("\n");
48001
- for (const pid of pids) {
48002
- const p = parseInt(pid, 10);
48003
- if (p > 0) {
48004
- try {
48005
- process.kill(p, "SIGTERM");
48006
- } catch {
48007
- }
48008
- }
48009
- }
48010
- if (pids.length > 0 && pids[0])
48011
- renderInfo(`Killed ${pids.length} orphaned cloudflared process(es).`);
48012
- } catch {
48063
+ const orphanPids = findPidsByPattern("cloudflared tunnel --url http");
48064
+ let orphansKilled = 0;
48065
+ for (const pid of orphanPids) {
48066
+ if (killPid(pid))
48067
+ orphansKilled++;
48013
48068
  }
48069
+ if (orphansKilled > 0)
48070
+ renderInfo(`Killed ${orphansKilled} orphaned cloudflared process(es).`);
48014
48071
  renderInfo("Sponsorship removed.");
48015
48072
  return "handled";
48016
48073
  }
@@ -48051,20 +48108,15 @@ async function handleSlashCommand(input, ctx) {
48051
48108
  const existingGateway = ctx.getExposeGateway?.();
48052
48109
  const managedPid = existingGateway?._cloudflaredPid || null;
48053
48110
  if (!existingGateway?.isActive) {
48054
- try {
48055
- const { execSync: execSync34 } = __require("child_process");
48056
- const orphanPids = execSync34("pgrep -f 'cloudflared tunnel --url http://127.0.0.1'", { encoding: "utf8", timeout: 3e3 }).trim().split("\n").map((s) => parseInt(s, 10)).filter((p) => p > 0 && p !== managedPid);
48057
- for (const pid of orphanPids) {
48058
- try {
48059
- process.kill(pid, "SIGTERM");
48060
- } catch {
48061
- }
48062
- }
48063
- if (orphanPids.length > 0) {
48064
- renderInfo(`Cleaned up ${orphanPids.length} orphaned tunnel(s) from previous session.`);
48065
- await new Promise((r) => setTimeout(r, 2e3));
48066
- }
48067
- } catch {
48111
+ const staleOrphans = findPidsByPattern("cloudflared tunnel --url http").filter((p) => p !== managedPid);
48112
+ let cleanedUp = 0;
48113
+ for (const pid of staleOrphans) {
48114
+ if (killPid(pid))
48115
+ cleanedUp++;
48116
+ }
48117
+ if (cleanedUp > 0) {
48118
+ renderInfo(`Cleaned up ${cleanedUp} orphaned tunnel(s) from previous session.`);
48119
+ await new Promise((r) => setTimeout(r, 2e3));
48068
48120
  }
48069
48121
  }
48070
48122
  const tunnelAlreadyActive = existingGateway?.isActive && existingGateway?.tunnelUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.184.20",
3
+ "version": "0.184.22",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) \u2014 interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",