open-agents-ai 0.150.0 → 0.152.0
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.
- package/dist/index.js +612 -186
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18541,9 +18541,9 @@ function getVersion(binary) {
|
|
|
18541
18541
|
}
|
|
18542
18542
|
}
|
|
18543
18543
|
function installOpencode() {
|
|
18544
|
-
const
|
|
18544
|
+
const platform6 = process.platform;
|
|
18545
18545
|
try {
|
|
18546
|
-
if (
|
|
18546
|
+
if (platform6 === "win32") {
|
|
18547
18547
|
execSync19('powershell -Command "irm https://opencode.ai/install | iex"', {
|
|
18548
18548
|
stdio: "pipe",
|
|
18549
18549
|
timeout: 12e4
|
|
@@ -18815,9 +18815,9 @@ function getVersion2(binary) {
|
|
|
18815
18815
|
}
|
|
18816
18816
|
}
|
|
18817
18817
|
function installDroid() {
|
|
18818
|
-
const
|
|
18818
|
+
const platform6 = process.platform;
|
|
18819
18819
|
try {
|
|
18820
|
-
if (
|
|
18820
|
+
if (platform6 === "win32") {
|
|
18821
18821
|
execSync20('powershell -Command "irm https://app.factory.ai/cli/windows | iex"', {
|
|
18822
18822
|
stdio: "pipe",
|
|
18823
18823
|
timeout: 12e4
|
|
@@ -20524,6 +20524,301 @@ var init_repo_map = __esm({
|
|
|
20524
20524
|
}
|
|
20525
20525
|
});
|
|
20526
20526
|
|
|
20527
|
+
// packages/execution/dist/tools/process-health.js
|
|
20528
|
+
import { execSync as execSync22 } from "node:child_process";
|
|
20529
|
+
function getSystemStatus() {
|
|
20530
|
+
const lines = ["# System Health\n"];
|
|
20531
|
+
try {
|
|
20532
|
+
const uptime2 = execSync22("uptime", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
20533
|
+
const loadMatch = uptime2.match(/load average:\s*([\d.]+),\s*([\d.]+),\s*([\d.]+)/);
|
|
20534
|
+
if (loadMatch) {
|
|
20535
|
+
lines.push(`CPU Load: ${loadMatch[1]} (1m) ${loadMatch[2]} (5m) ${loadMatch[3]} (15m)`);
|
|
20536
|
+
}
|
|
20537
|
+
} catch {
|
|
20538
|
+
}
|
|
20539
|
+
try {
|
|
20540
|
+
const cpuCount = __require("node:os").cpus().length;
|
|
20541
|
+
lines.push(`CPU Cores: ${cpuCount}`);
|
|
20542
|
+
} catch {
|
|
20543
|
+
}
|
|
20544
|
+
try {
|
|
20545
|
+
const mem = execSync22("free -h | head -2", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
20546
|
+
lines.push(`
|
|
20547
|
+
${mem}`);
|
|
20548
|
+
} catch {
|
|
20549
|
+
}
|
|
20550
|
+
try {
|
|
20551
|
+
const top = execSync22("ps aux --sort=-%cpu | head -8", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
20552
|
+
lines.push(`
|
|
20553
|
+
Top processes by CPU:
|
|
20554
|
+
${top}`);
|
|
20555
|
+
} catch {
|
|
20556
|
+
}
|
|
20557
|
+
try {
|
|
20558
|
+
const nodeCount = execSync22("ps aux | grep 'node ' | grep -v grep | wc -l", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
20559
|
+
lines.push(`
|
|
20560
|
+
Node.js processes: ${nodeCount}`);
|
|
20561
|
+
} catch {
|
|
20562
|
+
}
|
|
20563
|
+
return lines.join("\n");
|
|
20564
|
+
}
|
|
20565
|
+
function findOrphans() {
|
|
20566
|
+
try {
|
|
20567
|
+
const psOutput = execSync22(`ps -eo pid,ppid,%cpu,%mem,etime,args --no-headers 2>/dev/null | grep -E "${OA_PATTERNS}" | grep -v grep`, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
20568
|
+
if (!psOutput)
|
|
20569
|
+
return "No OA-related orphan processes found.";
|
|
20570
|
+
const myPid = process.pid;
|
|
20571
|
+
const myPpid = process.ppid;
|
|
20572
|
+
const lines = ["OA-related processes:\n"];
|
|
20573
|
+
lines.push(" PID PPID CPU% MEM% ELAPSED COMMAND");
|
|
20574
|
+
lines.push(" " + "-".repeat(75));
|
|
20575
|
+
for (const line of psOutput.split("\n")) {
|
|
20576
|
+
const parts = line.trim().split(/\s+/);
|
|
20577
|
+
const pid = parseInt(parts[0], 10);
|
|
20578
|
+
if (pid === myPid || pid === myPpid)
|
|
20579
|
+
continue;
|
|
20580
|
+
const ppid = parts[1];
|
|
20581
|
+
const cpu = parts[2];
|
|
20582
|
+
const mem = parts[3];
|
|
20583
|
+
const elapsed = parts[4];
|
|
20584
|
+
const cmd = parts.slice(5).join(" ");
|
|
20585
|
+
const shortCmd = cmd.length > 50 ? cmd.slice(0, 47) + "..." : cmd;
|
|
20586
|
+
const isHot = parseFloat(cpu) > 10 ? " \u26A0 HIGH CPU" : "";
|
|
20587
|
+
lines.push(` ${String(pid).padStart(7)} ${String(ppid).padStart(7)} ${String(cpu).padStart(6)} ${String(mem).padStart(5)} ${String(elapsed).padStart(9)} ${shortCmd}${isHot}`);
|
|
20588
|
+
}
|
|
20589
|
+
lines.push(`
|
|
20590
|
+
To kill a process: process_health(action='kill', pid=PID)`);
|
|
20591
|
+
lines.push(`Or from the prompt: /destroy processes --global`);
|
|
20592
|
+
return lines.join("\n");
|
|
20593
|
+
} catch {
|
|
20594
|
+
return "Could not scan for orphan processes.";
|
|
20595
|
+
}
|
|
20596
|
+
}
|
|
20597
|
+
function killProcess(pid) {
|
|
20598
|
+
try {
|
|
20599
|
+
try {
|
|
20600
|
+
process.kill(-pid, "SIGTERM");
|
|
20601
|
+
} catch {
|
|
20602
|
+
}
|
|
20603
|
+
process.kill(pid, "SIGTERM");
|
|
20604
|
+
try {
|
|
20605
|
+
execSync22(`sleep 1 && kill -0 ${pid} 2>/dev/null && kill -9 ${pid} 2>/dev/null`, {
|
|
20606
|
+
timeout: 3e3,
|
|
20607
|
+
stdio: "pipe"
|
|
20608
|
+
});
|
|
20609
|
+
} catch {
|
|
20610
|
+
}
|
|
20611
|
+
return `Killed PID ${pid} (SIGTERM \u2192 SIGKILL)`;
|
|
20612
|
+
} catch (err) {
|
|
20613
|
+
return `Failed to kill PID ${pid}: ${err instanceof Error ? err.message : String(err)}`;
|
|
20614
|
+
}
|
|
20615
|
+
}
|
|
20616
|
+
var OA_PATTERNS, ProcessHealthTool;
|
|
20617
|
+
var init_process_health = __esm({
|
|
20618
|
+
"packages/execution/dist/tools/process-health.js"() {
|
|
20619
|
+
"use strict";
|
|
20620
|
+
OA_PATTERNS = [
|
|
20621
|
+
"open-agents",
|
|
20622
|
+
"nexus-daemon",
|
|
20623
|
+
"vitest",
|
|
20624
|
+
"jest",
|
|
20625
|
+
"esbuild.*--service",
|
|
20626
|
+
"python3 -u -i",
|
|
20627
|
+
"chromium.*headless",
|
|
20628
|
+
"chrome.*headless",
|
|
20629
|
+
"crawlee-scraper",
|
|
20630
|
+
"web_scrape",
|
|
20631
|
+
"start-moondream",
|
|
20632
|
+
"live-whisper"
|
|
20633
|
+
].join("|");
|
|
20634
|
+
ProcessHealthTool = class {
|
|
20635
|
+
name = "process_health";
|
|
20636
|
+
description = "Check system CPU/memory load and find orphaned processes. Actions: 'status' (CPU + memory + top processes), 'orphans' (find stale OA-related processes), 'kill' (kill a specific PID). Use this when the system feels slow or when a shell command seems stuck.";
|
|
20637
|
+
parameters = {
|
|
20638
|
+
type: "object",
|
|
20639
|
+
properties: {
|
|
20640
|
+
action: {
|
|
20641
|
+
type: "string",
|
|
20642
|
+
enum: ["status", "orphans", "kill"],
|
|
20643
|
+
description: "Action (default: status)"
|
|
20644
|
+
},
|
|
20645
|
+
pid: {
|
|
20646
|
+
type: "number",
|
|
20647
|
+
description: "Process ID to kill (for 'kill' action)"
|
|
20648
|
+
}
|
|
20649
|
+
},
|
|
20650
|
+
required: []
|
|
20651
|
+
};
|
|
20652
|
+
async execute(args) {
|
|
20653
|
+
const action = String(args["action"] ?? "status");
|
|
20654
|
+
const start = performance.now();
|
|
20655
|
+
try {
|
|
20656
|
+
switch (action) {
|
|
20657
|
+
case "status":
|
|
20658
|
+
return { success: true, output: getSystemStatus(), durationMs: performance.now() - start };
|
|
20659
|
+
case "orphans":
|
|
20660
|
+
return { success: true, output: findOrphans(), durationMs: performance.now() - start };
|
|
20661
|
+
case "kill": {
|
|
20662
|
+
const pid = Number(args["pid"]);
|
|
20663
|
+
if (!pid || pid <= 10)
|
|
20664
|
+
return { success: false, output: "", error: "Valid PID required", durationMs: performance.now() - start };
|
|
20665
|
+
if (pid === process.pid || pid === process.ppid) {
|
|
20666
|
+
return { success: false, output: "", error: "Cannot kill self or parent process", durationMs: performance.now() - start };
|
|
20667
|
+
}
|
|
20668
|
+
return { success: true, output: killProcess(pid), durationMs: performance.now() - start };
|
|
20669
|
+
}
|
|
20670
|
+
default:
|
|
20671
|
+
return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start };
|
|
20672
|
+
}
|
|
20673
|
+
} catch (err) {
|
|
20674
|
+
return { success: false, output: "", error: String(err instanceof Error ? err.message : err), durationMs: performance.now() - start };
|
|
20675
|
+
}
|
|
20676
|
+
}
|
|
20677
|
+
};
|
|
20678
|
+
}
|
|
20679
|
+
});
|
|
20680
|
+
|
|
20681
|
+
// packages/execution/dist/tools/environment-snapshot.js
|
|
20682
|
+
import { execSync as execSync23 } from "node:child_process";
|
|
20683
|
+
import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
|
|
20684
|
+
import { statfsSync } from "node:fs";
|
|
20685
|
+
function collectSnapshot(workingDir) {
|
|
20686
|
+
const now = /* @__PURE__ */ new Date();
|
|
20687
|
+
const cpuInfo = cpus();
|
|
20688
|
+
const totalRAM = totalmem();
|
|
20689
|
+
const freeRAM = freemem();
|
|
20690
|
+
let load1 = 0, load5 = 0, load15 = 0;
|
|
20691
|
+
try {
|
|
20692
|
+
const loadavg4 = __require("node:os").loadavg();
|
|
20693
|
+
load1 = loadavg4[0];
|
|
20694
|
+
load5 = loadavg4[1];
|
|
20695
|
+
load15 = loadavg4[2];
|
|
20696
|
+
} catch {
|
|
20697
|
+
}
|
|
20698
|
+
let gpu = void 0;
|
|
20699
|
+
try {
|
|
20700
|
+
const nvOut = execSync23("nvidia-smi --query-gpu=name,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split(",").map((s) => s.trim());
|
|
20701
|
+
if (nvOut.length >= 3) {
|
|
20702
|
+
gpu = {
|
|
20703
|
+
name: nvOut[0],
|
|
20704
|
+
vramTotalMB: parseInt(nvOut[1], 10),
|
|
20705
|
+
vramUsedMB: parseInt(nvOut[2], 10),
|
|
20706
|
+
vramUsedPercent: Math.round(parseInt(nvOut[2], 10) / parseInt(nvOut[1], 10) * 100),
|
|
20707
|
+
tempC: nvOut[3] ? parseInt(nvOut[3], 10) : void 0
|
|
20708
|
+
};
|
|
20709
|
+
}
|
|
20710
|
+
} catch {
|
|
20711
|
+
}
|
|
20712
|
+
let battery = void 0;
|
|
20713
|
+
try {
|
|
20714
|
+
if (platform() === "linux") {
|
|
20715
|
+
const cap = execSync23("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
20716
|
+
const status = execSync23("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
20717
|
+
if (cap)
|
|
20718
|
+
battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
|
|
20719
|
+
} else if (platform() === "darwin") {
|
|
20720
|
+
const pmOut = execSync23("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
|
|
20721
|
+
const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
|
|
20722
|
+
if (match)
|
|
20723
|
+
battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
|
|
20724
|
+
}
|
|
20725
|
+
} catch {
|
|
20726
|
+
}
|
|
20727
|
+
let disk = { availableGB: 0, totalGB: 0, usedPercent: 0 };
|
|
20728
|
+
try {
|
|
20729
|
+
const stats = statfsSync(workingDir || "/");
|
|
20730
|
+
const totalBytes = stats.blocks * stats.bsize;
|
|
20731
|
+
const availBytes = stats.bavail * stats.bsize;
|
|
20732
|
+
disk = {
|
|
20733
|
+
totalGB: Math.round(totalBytes / 1024 ** 3),
|
|
20734
|
+
availableGB: Math.round(availBytes / 1024 ** 3),
|
|
20735
|
+
usedPercent: Math.round((1 - availBytes / totalBytes) * 100)
|
|
20736
|
+
};
|
|
20737
|
+
} catch {
|
|
20738
|
+
}
|
|
20739
|
+
let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
|
|
20740
|
+
try {
|
|
20741
|
+
const psLines = execSync23("ps -eo pid,%cpu,args --sort=-%cpu --no-headers 2>/dev/null | head -50", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n");
|
|
20742
|
+
const total = parseInt(execSync23("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
|
|
20743
|
+
let nodeCount = 0;
|
|
20744
|
+
let oaSpawned = 0;
|
|
20745
|
+
const topCpu = [];
|
|
20746
|
+
const oaPattern = /open-agents|nexus-daemon|vitest|esbuild.*service|python3 -u -i|start-moondream|live-whisper/;
|
|
20747
|
+
for (const line of psLines) {
|
|
20748
|
+
const parts = line.trim().split(/\s+/);
|
|
20749
|
+
if (parts.length < 3)
|
|
20750
|
+
continue;
|
|
20751
|
+
const pid = parseInt(parts[0], 10);
|
|
20752
|
+
const cpu = parseFloat(parts[1]);
|
|
20753
|
+
const cmd = parts.slice(2).join(" ");
|
|
20754
|
+
if (/node\b/.test(cmd))
|
|
20755
|
+
nodeCount++;
|
|
20756
|
+
if (oaPattern.test(cmd))
|
|
20757
|
+
oaSpawned++;
|
|
20758
|
+
if (cpu > 1 && topCpu.length < 5) {
|
|
20759
|
+
topCpu.push({ pid, cpu, cmd: cmd.slice(0, 60) });
|
|
20760
|
+
}
|
|
20761
|
+
}
|
|
20762
|
+
processInfo = { total, nodeCount, oaSpawned, topCpu };
|
|
20763
|
+
} catch {
|
|
20764
|
+
}
|
|
20765
|
+
let uptimeStr = "";
|
|
20766
|
+
const secs = uptime();
|
|
20767
|
+
const days = Math.floor(secs / 86400);
|
|
20768
|
+
const hours = Math.floor(secs % 86400 / 3600);
|
|
20769
|
+
uptimeStr = days > 0 ? `${days}d ${hours}h` : `${hours}h ${Math.floor(secs % 3600 / 60)}m`;
|
|
20770
|
+
return {
|
|
20771
|
+
timestamp: now.toISOString(),
|
|
20772
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
20773
|
+
uptime: uptimeStr,
|
|
20774
|
+
cpu: {
|
|
20775
|
+
model: cpuInfo[0]?.model?.replace(/\s+/g, " ").trim() ?? "unknown",
|
|
20776
|
+
cores: cpuInfo.length,
|
|
20777
|
+
load1m: Math.round(load1 * 100) / 100,
|
|
20778
|
+
load5m: Math.round(load5 * 100) / 100,
|
|
20779
|
+
load15m: Math.round(load15 * 100) / 100
|
|
20780
|
+
},
|
|
20781
|
+
ram: {
|
|
20782
|
+
totalGB: Math.round(totalRAM / 1024 ** 3),
|
|
20783
|
+
availableGB: Math.round(freeRAM / 1024 ** 3),
|
|
20784
|
+
usedPercent: Math.round((1 - freeRAM / totalRAM) * 100)
|
|
20785
|
+
},
|
|
20786
|
+
gpu,
|
|
20787
|
+
battery,
|
|
20788
|
+
disk,
|
|
20789
|
+
network: { hostname: hostname2(), platform: platform(), arch: arch() },
|
|
20790
|
+
processes: processInfo
|
|
20791
|
+
};
|
|
20792
|
+
}
|
|
20793
|
+
function formatSnapshotForContext(snap) {
|
|
20794
|
+
const lines = [];
|
|
20795
|
+
lines.push(`<environment>`);
|
|
20796
|
+
lines.push(`Time: ${snap.timestamp.replace("T", " ").replace(/\.\d+Z$/, "Z")} (${snap.timezone})`);
|
|
20797
|
+
lines.push(`System: ${snap.network.platform}/${snap.network.arch} | ${snap.cpu.cores} cores | ${snap.cpu.model.slice(0, 40)}`);
|
|
20798
|
+
lines.push(`CPU Load: ${snap.cpu.load1m} (1m) ${snap.cpu.load5m} (5m) \u2014 ${snap.cpu.load1m > snap.cpu.cores * 0.8 ? "HIGH" : "normal"}`);
|
|
20799
|
+
lines.push(`RAM: ${snap.ram.availableGB}GB free / ${snap.ram.totalGB}GB (${snap.ram.usedPercent}% used)`);
|
|
20800
|
+
if (snap.gpu) {
|
|
20801
|
+
lines.push(`GPU: ${snap.gpu.name} | ${snap.gpu.vramUsedMB}MB / ${snap.gpu.vramTotalMB}MB VRAM (${snap.gpu.vramUsedPercent}%)${snap.gpu.tempC ? ` ${snap.gpu.tempC}\xB0C` : ""}`);
|
|
20802
|
+
}
|
|
20803
|
+
if (snap.battery) {
|
|
20804
|
+
const icon = snap.battery.charging ? "\u26A1" : snap.battery.percent < 20 ? "\u{1FAAB}" : "\u{1F50B}";
|
|
20805
|
+
lines.push(`Battery: ${icon} ${snap.battery.percent}% ${snap.battery.charging ? "(charging)" : "(discharging)"}`);
|
|
20806
|
+
}
|
|
20807
|
+
lines.push(`Disk: ${snap.disk.availableGB}GB free / ${snap.disk.totalGB}GB (${snap.disk.usedPercent}% used)`);
|
|
20808
|
+
lines.push(`Processes: ${snap.processes.total} total | ${snap.processes.nodeCount} node | ${snap.processes.oaSpawned} OA-spawned`);
|
|
20809
|
+
lines.push(`Uptime: ${snap.uptime}`);
|
|
20810
|
+
if (snap.processes.topCpu.length > 0) {
|
|
20811
|
+
lines.push(`Top CPU: ${snap.processes.topCpu.map((p) => `${p.cmd.slice(0, 25)}(${p.cpu}%)`).join(", ")}`);
|
|
20812
|
+
}
|
|
20813
|
+
lines.push(`</environment>`);
|
|
20814
|
+
return lines.join("\n");
|
|
20815
|
+
}
|
|
20816
|
+
var init_environment_snapshot = __esm({
|
|
20817
|
+
"packages/execution/dist/tools/environment-snapshot.js"() {
|
|
20818
|
+
"use strict";
|
|
20819
|
+
}
|
|
20820
|
+
});
|
|
20821
|
+
|
|
20527
20822
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
20528
20823
|
import { existsSync as existsSync27, readFileSync as readFileSync20 } from "node:fs";
|
|
20529
20824
|
import { join as join41 } from "node:path";
|
|
@@ -21321,6 +21616,7 @@ __export(dist_exports, {
|
|
|
21321
21616
|
OcrPdfTool: () => OcrPdfTool,
|
|
21322
21617
|
OpenCodeTool: () => OpenCodeTool,
|
|
21323
21618
|
PdfToTextTool: () => PdfToTextTool,
|
|
21619
|
+
ProcessHealthTool: () => ProcessHealthTool,
|
|
21324
21620
|
ReflectionIntegrityTool: () => ReflectionIntegrityTool,
|
|
21325
21621
|
ReminderTool: () => ReminderTool,
|
|
21326
21622
|
ReplTool: () => ReplTool,
|
|
@@ -21353,6 +21649,7 @@ __export(dist_exports, {
|
|
|
21353
21649
|
checkDesktopDeps: () => checkDesktopDeps,
|
|
21354
21650
|
clearExploreNotes: () => clearExploreNotes,
|
|
21355
21651
|
clearWorkingNotes: () => clearWorkingNotes,
|
|
21652
|
+
collectSnapshot: () => collectSnapshot,
|
|
21356
21653
|
createFortemiBridgeTools: () => createFortemiBridgeTools,
|
|
21357
21654
|
createWorktree: () => createWorktree,
|
|
21358
21655
|
detectSearchProvider: () => detectSearchProvider,
|
|
@@ -21360,6 +21657,7 @@ __export(dist_exports, {
|
|
|
21360
21657
|
ensureAllDesktopDeps: () => ensureAllDesktopDeps,
|
|
21361
21658
|
ensureCommand: () => ensureCommand,
|
|
21362
21659
|
ensureDepsForGroup: () => ensureDepsForGroup,
|
|
21660
|
+
formatSnapshotForContext: () => formatSnapshotForContext,
|
|
21363
21661
|
getActiveAttentionItems: () => getActiveAttentionItems,
|
|
21364
21662
|
getDueReminders: () => getDueReminders,
|
|
21365
21663
|
getExploreNotes: () => getExploreNotes,
|
|
@@ -21458,6 +21756,8 @@ var init_dist2 = __esm({
|
|
|
21458
21756
|
init_semantic_map();
|
|
21459
21757
|
init_change_log();
|
|
21460
21758
|
init_repo_map();
|
|
21759
|
+
init_process_health();
|
|
21760
|
+
init_environment_snapshot();
|
|
21461
21761
|
init_nexus();
|
|
21462
21762
|
init_fortemi_bridge();
|
|
21463
21763
|
init_system_deps();
|
|
@@ -28267,7 +28567,7 @@ __export(listen_exports, {
|
|
|
28267
28567
|
isVideoPath: () => isVideoPath,
|
|
28268
28568
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
28269
28569
|
});
|
|
28270
|
-
import { spawn as spawn15, execSync as
|
|
28570
|
+
import { spawn as spawn15, execSync as execSync24 } from "node:child_process";
|
|
28271
28571
|
import { existsSync as existsSync31, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readdirSync as readdirSync7 } from "node:fs";
|
|
28272
28572
|
import { join as join46, dirname as dirname14 } from "node:path";
|
|
28273
28573
|
import { homedir as homedir10 } from "node:os";
|
|
@@ -28286,10 +28586,10 @@ function isTranscribablePath(path) {
|
|
|
28286
28586
|
return isAudioPath(path) || isVideoPath(path);
|
|
28287
28587
|
}
|
|
28288
28588
|
function findMicCaptureCommand() {
|
|
28289
|
-
const
|
|
28290
|
-
if (
|
|
28589
|
+
const platform6 = process.platform;
|
|
28590
|
+
if (platform6 === "linux") {
|
|
28291
28591
|
try {
|
|
28292
|
-
|
|
28592
|
+
execSync24("which arecord", { stdio: "pipe" });
|
|
28293
28593
|
return {
|
|
28294
28594
|
cmd: "arecord",
|
|
28295
28595
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -28297,9 +28597,9 @@ function findMicCaptureCommand() {
|
|
|
28297
28597
|
} catch {
|
|
28298
28598
|
}
|
|
28299
28599
|
}
|
|
28300
|
-
if (
|
|
28600
|
+
if (platform6 === "darwin") {
|
|
28301
28601
|
try {
|
|
28302
|
-
|
|
28602
|
+
execSync24("which sox", { stdio: "pipe" });
|
|
28303
28603
|
return {
|
|
28304
28604
|
cmd: "sox",
|
|
28305
28605
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -28308,8 +28608,8 @@ function findMicCaptureCommand() {
|
|
|
28308
28608
|
}
|
|
28309
28609
|
}
|
|
28310
28610
|
try {
|
|
28311
|
-
|
|
28312
|
-
if (
|
|
28611
|
+
execSync24("which ffmpeg", { stdio: "pipe" });
|
|
28612
|
+
if (platform6 === "linux") {
|
|
28313
28613
|
return {
|
|
28314
28614
|
cmd: "ffmpeg",
|
|
28315
28615
|
args: [
|
|
@@ -28328,7 +28628,7 @@ function findMicCaptureCommand() {
|
|
|
28328
28628
|
"pipe:1"
|
|
28329
28629
|
]
|
|
28330
28630
|
};
|
|
28331
|
-
} else if (
|
|
28631
|
+
} else if (platform6 === "darwin") {
|
|
28332
28632
|
return {
|
|
28333
28633
|
cmd: "ffmpeg",
|
|
28334
28634
|
args: [
|
|
@@ -28367,7 +28667,7 @@ function findLiveWhisperScript() {
|
|
|
28367
28667
|
return p;
|
|
28368
28668
|
}
|
|
28369
28669
|
try {
|
|
28370
|
-
const globalRoot =
|
|
28670
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28371
28671
|
encoding: "utf-8",
|
|
28372
28672
|
timeout: 5e3,
|
|
28373
28673
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28400,7 +28700,7 @@ function ensureTranscribeCliBackground() {
|
|
|
28400
28700
|
return;
|
|
28401
28701
|
_bgInstallPromise = (async () => {
|
|
28402
28702
|
try {
|
|
28403
|
-
const globalRoot =
|
|
28703
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28404
28704
|
encoding: "utf-8",
|
|
28405
28705
|
timeout: 5e3,
|
|
28406
28706
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28606,7 +28906,7 @@ var init_listen = __esm({
|
|
|
28606
28906
|
}
|
|
28607
28907
|
if (!this.transcribeCliAvailable) {
|
|
28608
28908
|
try {
|
|
28609
|
-
|
|
28909
|
+
execSync24("which transcribe-cli", { stdio: "pipe" });
|
|
28610
28910
|
this.transcribeCliAvailable = true;
|
|
28611
28911
|
} catch {
|
|
28612
28912
|
this.transcribeCliAvailable = false;
|
|
@@ -28623,7 +28923,7 @@ var init_listen = __esm({
|
|
|
28623
28923
|
} catch {
|
|
28624
28924
|
}
|
|
28625
28925
|
try {
|
|
28626
|
-
const globalRoot =
|
|
28926
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28627
28927
|
encoding: "utf-8",
|
|
28628
28928
|
timeout: 5e3,
|
|
28629
28929
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28673,7 +28973,7 @@ var init_listen = __esm({
|
|
|
28673
28973
|
}
|
|
28674
28974
|
if (!tc) {
|
|
28675
28975
|
try {
|
|
28676
|
-
|
|
28976
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
28677
28977
|
this.transcribeCliAvailable = null;
|
|
28678
28978
|
tc = await this.loadTranscribeCli();
|
|
28679
28979
|
} catch {
|
|
@@ -28856,7 +29156,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
28856
29156
|
}
|
|
28857
29157
|
if (!tc) {
|
|
28858
29158
|
try {
|
|
28859
|
-
|
|
29159
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
28860
29160
|
this.transcribeCliAvailable = null;
|
|
28861
29161
|
tc = await this.loadTranscribeCli();
|
|
28862
29162
|
} catch {
|
|
@@ -28910,7 +29210,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
28910
29210
|
}
|
|
28911
29211
|
if (!tc) {
|
|
28912
29212
|
try {
|
|
28913
|
-
|
|
29213
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
28914
29214
|
this.transcribeCliAvailable = null;
|
|
28915
29215
|
tc = await this.loadTranscribeCli();
|
|
28916
29216
|
} catch {
|
|
@@ -33358,7 +33658,9 @@ var init_render = __esm({
|
|
|
33358
33658
|
["/pause", "Pause after current turn finishes (gentle halt, /resume to continue)"],
|
|
33359
33659
|
["/stop", "Kill current inference immediately and save state (/resume to continue)"],
|
|
33360
33660
|
["/resume", "Resume a paused or stopped task"],
|
|
33361
|
-
["/destroy", "
|
|
33661
|
+
["/destroy processes", "Find and kill orphaned OA child processes (this project)"],
|
|
33662
|
+
["/destroy processes --global", "Kill ALL orphaned OA processes system-wide"],
|
|
33663
|
+
["/destroy project", "Remove .oa folder, kill all tasks, clear console, and exit"],
|
|
33362
33664
|
["/context save", "Force-save session context to .oa/context/"],
|
|
33363
33665
|
["/context restore", "Restore context from previous sessions into next task"],
|
|
33364
33666
|
["/context show", "Show saved session context status"],
|
|
@@ -33415,7 +33717,7 @@ var init_render = __esm({
|
|
|
33415
33717
|
|
|
33416
33718
|
// packages/cli/dist/tui/voice-session.js
|
|
33417
33719
|
import { createServer as createServer2 } from "node:http";
|
|
33418
|
-
import { spawn as spawn16, execSync as
|
|
33720
|
+
import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
|
|
33419
33721
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
33420
33722
|
function generateFrontendHTML() {
|
|
33421
33723
|
return `<!DOCTYPE html>
|
|
@@ -34147,7 +34449,7 @@ import { spawn as spawn17, exec } from "node:child_process";
|
|
|
34147
34449
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
34148
34450
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
34149
34451
|
import { URL as URL2 } from "node:url";
|
|
34150
|
-
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
34452
|
+
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
34151
34453
|
import { existsSync as existsSync32, readFileSync as readFileSync23, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, mkdirSync as mkdirSync11, readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
|
|
34152
34454
|
import { join as join47 } from "node:path";
|
|
34153
34455
|
function cleanForwardHeaders(raw, targetHost) {
|
|
@@ -34239,9 +34541,9 @@ function parseRateLimitHeaders(headers) {
|
|
|
34239
34541
|
}
|
|
34240
34542
|
async function collectSystemMetricsAsync() {
|
|
34241
34543
|
const [l1, l5, l15] = loadavg();
|
|
34242
|
-
const cores =
|
|
34243
|
-
const totalMem =
|
|
34244
|
-
const freeMem =
|
|
34544
|
+
const cores = cpus2().length;
|
|
34545
|
+
const totalMem = totalmem2();
|
|
34546
|
+
const freeMem = freemem2();
|
|
34245
34547
|
const usedMem = totalMem - freeMem;
|
|
34246
34548
|
const gpu = {
|
|
34247
34549
|
available: false,
|
|
@@ -36784,7 +37086,7 @@ ${activitySummary}
|
|
|
36784
37086
|
});
|
|
36785
37087
|
|
|
36786
37088
|
// packages/cli/dist/tui/model-picker.js
|
|
36787
|
-
import { totalmem as
|
|
37089
|
+
import { totalmem as totalmem3 } from "node:os";
|
|
36788
37090
|
function isImageGenModel(name, family) {
|
|
36789
37091
|
return IMAGE_GEN_PATTERNS.some((p) => p.test(name) || family && p.test(family));
|
|
36790
37092
|
}
|
|
@@ -36833,15 +37135,15 @@ async function fetchOllamaModels(baseUrl) {
|
|
|
36833
37135
|
}
|
|
36834
37136
|
if (show.model_info) {
|
|
36835
37137
|
const info = show.model_info;
|
|
36836
|
-
const
|
|
37138
|
+
const arch2 = info["general.architecture"];
|
|
36837
37139
|
const paramCount = info["general.parameter_count"];
|
|
36838
37140
|
const fileSizeGB = result[i].sizeBytes > 0 ? result[i].sizeBytes / 1024 ** 3 : paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
36839
|
-
if (
|
|
36840
|
-
const archMax = info[`${
|
|
36841
|
-
const nLayers = info[`${
|
|
36842
|
-
const nKVHeads = info[`${
|
|
36843
|
-
const keyDim = info[`${
|
|
36844
|
-
const valDim = info[`${
|
|
37141
|
+
if (arch2) {
|
|
37142
|
+
const archMax = info[`${arch2}.context_length`];
|
|
37143
|
+
const nLayers = info[`${arch2}.block_count`];
|
|
37144
|
+
const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
|
|
37145
|
+
const keyDim = info[`${arch2}.attention.key_length`];
|
|
37146
|
+
const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
|
|
36845
37147
|
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
36846
37148
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
36847
37149
|
result[i].contextLength = estimateRealisticContext(kvBytesPerToken, archMax, fileSizeGB);
|
|
@@ -37144,15 +37446,15 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
37144
37446
|
}
|
|
37145
37447
|
if (data.model_info) {
|
|
37146
37448
|
const info = data.model_info;
|
|
37147
|
-
const
|
|
37449
|
+
const arch2 = info["general.architecture"];
|
|
37148
37450
|
const paramCount = info["general.parameter_count"];
|
|
37149
37451
|
const modelSizeGB2 = paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
37150
|
-
if (
|
|
37151
|
-
const archMax = info[`${
|
|
37152
|
-
const nLayers = info[`${
|
|
37153
|
-
const nKVHeads = info[`${
|
|
37154
|
-
const keyDim = info[`${
|
|
37155
|
-
const valDim = info[`${
|
|
37452
|
+
if (arch2) {
|
|
37453
|
+
const archMax = info[`${arch2}.context_length`];
|
|
37454
|
+
const nLayers = info[`${arch2}.block_count`];
|
|
37455
|
+
const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
|
|
37456
|
+
const keyDim = info[`${arch2}.attention.key_length`];
|
|
37457
|
+
const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
|
|
37156
37458
|
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
37157
37459
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
37158
37460
|
return estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2);
|
|
@@ -37169,7 +37471,7 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
37169
37471
|
}
|
|
37170
37472
|
}
|
|
37171
37473
|
function estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2) {
|
|
37172
|
-
const totalMemGB =
|
|
37474
|
+
const totalMemGB = totalmem3() / 1024 ** 3;
|
|
37173
37475
|
const usableBytes = totalMemGB * 0.7 * 1024 ** 3;
|
|
37174
37476
|
const maxTokens = Math.floor(usableBytes / kvBytesPerToken);
|
|
37175
37477
|
let numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
|
|
@@ -38045,18 +38347,18 @@ var init_oa_directory = __esm({
|
|
|
38045
38347
|
|
|
38046
38348
|
// packages/cli/dist/tui/setup.js
|
|
38047
38349
|
import * as readline from "node:readline";
|
|
38048
|
-
import { execSync as
|
|
38350
|
+
import { execSync as execSync26, spawn as spawn18, exec as exec2 } from "node:child_process";
|
|
38049
38351
|
import { promisify as promisify6 } from "node:util";
|
|
38050
38352
|
import { existsSync as existsSync36, writeFileSync as writeFileSync15, readFileSync as readFileSync27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync14 } from "node:fs";
|
|
38051
38353
|
import { join as join52 } from "node:path";
|
|
38052
|
-
import { homedir as homedir12, platform } from "node:os";
|
|
38354
|
+
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
38053
38355
|
function detectSystemSpecs() {
|
|
38054
38356
|
let totalRamGB = 0;
|
|
38055
38357
|
let availableRamGB = 0;
|
|
38056
38358
|
let gpuVramGB = 0;
|
|
38057
38359
|
let gpuName = "";
|
|
38058
38360
|
try {
|
|
38059
|
-
const memInfo =
|
|
38361
|
+
const memInfo = execSync26("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
38060
38362
|
encoding: "utf8",
|
|
38061
38363
|
timeout: 5e3
|
|
38062
38364
|
});
|
|
@@ -38076,7 +38378,7 @@ function detectSystemSpecs() {
|
|
|
38076
38378
|
} catch {
|
|
38077
38379
|
}
|
|
38078
38380
|
try {
|
|
38079
|
-
const nvidiaSmi =
|
|
38381
|
+
const nvidiaSmi = execSync26("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
38080
38382
|
const lines = nvidiaSmi.trim().split("\n");
|
|
38081
38383
|
if (lines.length > 0) {
|
|
38082
38384
|
for (const line of lines) {
|
|
@@ -38236,7 +38538,7 @@ function askSecret(rl, question) {
|
|
|
38236
38538
|
function ensureCurl() {
|
|
38237
38539
|
if (hasCmd("curl"))
|
|
38238
38540
|
return true;
|
|
38239
|
-
const plat =
|
|
38541
|
+
const plat = platform2();
|
|
38240
38542
|
if (plat === "win32") {
|
|
38241
38543
|
process.stdout.write(` ${c2.yellow("\u26A0")} curl not found on Windows \u2014 install it manually.
|
|
38242
38544
|
`);
|
|
@@ -38255,7 +38557,7 @@ function ensureCurl() {
|
|
|
38255
38557
|
for (const s of strategies) {
|
|
38256
38558
|
if (hasCmd(s.check)) {
|
|
38257
38559
|
try {
|
|
38258
|
-
|
|
38560
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38259
38561
|
if (hasCmd("curl")) {
|
|
38260
38562
|
process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
|
|
38261
38563
|
`);
|
|
@@ -38269,7 +38571,7 @@ function ensureCurl() {
|
|
|
38269
38571
|
}
|
|
38270
38572
|
if (plat === "darwin") {
|
|
38271
38573
|
try {
|
|
38272
|
-
|
|
38574
|
+
execSync26("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
38273
38575
|
if (hasCmd("curl"))
|
|
38274
38576
|
return true;
|
|
38275
38577
|
} catch {
|
|
@@ -38280,7 +38582,7 @@ function ensureCurl() {
|
|
|
38280
38582
|
return false;
|
|
38281
38583
|
}
|
|
38282
38584
|
async function autoInstallOllama(rl) {
|
|
38283
|
-
const plat =
|
|
38585
|
+
const plat = platform2();
|
|
38284
38586
|
if (plat !== "win32" && !ensureCurl()) {
|
|
38285
38587
|
return false;
|
|
38286
38588
|
}
|
|
@@ -38304,7 +38606,7 @@ function installOllamaLinux() {
|
|
|
38304
38606
|
|
|
38305
38607
|
`);
|
|
38306
38608
|
try {
|
|
38307
|
-
|
|
38609
|
+
execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
38308
38610
|
stdio: "inherit",
|
|
38309
38611
|
timeout: 3e5
|
|
38310
38612
|
});
|
|
@@ -38332,7 +38634,7 @@ async function installOllamaMac(_rl) {
|
|
|
38332
38634
|
|
|
38333
38635
|
`);
|
|
38334
38636
|
try {
|
|
38335
|
-
|
|
38637
|
+
execSync26('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
38336
38638
|
if (!hasCmd("brew")) {
|
|
38337
38639
|
try {
|
|
38338
38640
|
const brewPrefix = existsSync36("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
@@ -38365,7 +38667,7 @@ async function installOllamaMac(_rl) {
|
|
|
38365
38667
|
|
|
38366
38668
|
`);
|
|
38367
38669
|
try {
|
|
38368
|
-
|
|
38670
|
+
execSync26("brew install ollama", {
|
|
38369
38671
|
stdio: "inherit",
|
|
38370
38672
|
timeout: 3e5
|
|
38371
38673
|
});
|
|
@@ -38392,7 +38694,7 @@ function installOllamaWindows() {
|
|
|
38392
38694
|
|
|
38393
38695
|
`);
|
|
38394
38696
|
try {
|
|
38395
|
-
|
|
38697
|
+
execSync26('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
38396
38698
|
stdio: "inherit",
|
|
38397
38699
|
timeout: 3e5
|
|
38398
38700
|
});
|
|
@@ -38473,7 +38775,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
38473
38775
|
}
|
|
38474
38776
|
function pullModelWithAutoUpdate(tag) {
|
|
38475
38777
|
try {
|
|
38476
|
-
|
|
38778
|
+
execSync26(`ollama pull ${tag}`, {
|
|
38477
38779
|
stdio: "inherit",
|
|
38478
38780
|
timeout: 36e5
|
|
38479
38781
|
// 1 hour max
|
|
@@ -38493,7 +38795,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
38493
38795
|
|
|
38494
38796
|
`);
|
|
38495
38797
|
try {
|
|
38496
|
-
|
|
38798
|
+
execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
38497
38799
|
stdio: "inherit",
|
|
38498
38800
|
timeout: 3e5
|
|
38499
38801
|
// 5 min max for install
|
|
@@ -38504,7 +38806,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
38504
38806
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
38505
38807
|
|
|
38506
38808
|
`);
|
|
38507
|
-
|
|
38809
|
+
execSync26(`ollama pull ${tag}`, {
|
|
38508
38810
|
stdio: "inherit",
|
|
38509
38811
|
timeout: 36e5
|
|
38510
38812
|
});
|
|
@@ -38588,7 +38890,7 @@ function renderScoreBar(score, width = 20) {
|
|
|
38588
38890
|
function ensurePython3() {
|
|
38589
38891
|
process.stdout.write(` ${c2.cyan("\u25CF")} Installing Python3...
|
|
38590
38892
|
`);
|
|
38591
|
-
const plat =
|
|
38893
|
+
const plat = platform2();
|
|
38592
38894
|
if (plat === "win32") {
|
|
38593
38895
|
process.stdout.write(` ${c2.dim("Download Python from https://python.org/downloads/")}
|
|
38594
38896
|
|
|
@@ -38606,7 +38908,7 @@ function ensurePython3() {
|
|
|
38606
38908
|
if (plat === "darwin") {
|
|
38607
38909
|
if (hasCmd("brew")) {
|
|
38608
38910
|
try {
|
|
38609
|
-
|
|
38911
|
+
execSync26("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
38610
38912
|
if (hasCmd("python3")) {
|
|
38611
38913
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
|
|
38612
38914
|
`);
|
|
@@ -38619,7 +38921,7 @@ function ensurePython3() {
|
|
|
38619
38921
|
for (const s of strategies) {
|
|
38620
38922
|
if (hasCmd(s.check)) {
|
|
38621
38923
|
try {
|
|
38622
|
-
|
|
38924
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38623
38925
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
38624
38926
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
|
|
38625
38927
|
`);
|
|
@@ -38635,11 +38937,11 @@ function ensurePython3() {
|
|
|
38635
38937
|
}
|
|
38636
38938
|
function checkPythonVenv() {
|
|
38637
38939
|
try {
|
|
38638
|
-
|
|
38940
|
+
execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
38639
38941
|
return true;
|
|
38640
38942
|
} catch {
|
|
38641
38943
|
try {
|
|
38642
|
-
|
|
38944
|
+
execSync26("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
38643
38945
|
return true;
|
|
38644
38946
|
} catch {
|
|
38645
38947
|
return false;
|
|
@@ -38658,7 +38960,7 @@ function ensurePythonVenv() {
|
|
|
38658
38960
|
for (const s of strategies) {
|
|
38659
38961
|
if (hasCmd(s.check)) {
|
|
38660
38962
|
try {
|
|
38661
|
-
|
|
38963
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38662
38964
|
if (checkPythonVenv()) {
|
|
38663
38965
|
process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
|
|
38664
38966
|
`);
|
|
@@ -39094,7 +39396,7 @@ async function doSetup(config, rl) {
|
|
|
39094
39396
|
const modelfilePath = join52(modelDir2, `Modelfile.${customName}`);
|
|
39095
39397
|
writeFileSync15(modelfilePath, modelfileContent + "\n", "utf8");
|
|
39096
39398
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
39097
|
-
|
|
39399
|
+
execSync26(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
39098
39400
|
stdio: "pipe",
|
|
39099
39401
|
timeout: 12e4
|
|
39100
39402
|
});
|
|
@@ -39145,7 +39447,7 @@ function isFirstRun() {
|
|
|
39145
39447
|
function hasCmd(cmd) {
|
|
39146
39448
|
try {
|
|
39147
39449
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
39148
|
-
|
|
39450
|
+
execSync26(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
39149
39451
|
return true;
|
|
39150
39452
|
} catch {
|
|
39151
39453
|
return false;
|
|
@@ -39178,7 +39480,7 @@ function getVenvDir() {
|
|
|
39178
39480
|
}
|
|
39179
39481
|
function hasVenvModule() {
|
|
39180
39482
|
try {
|
|
39181
|
-
|
|
39483
|
+
execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39182
39484
|
return true;
|
|
39183
39485
|
} catch {
|
|
39184
39486
|
return false;
|
|
@@ -39200,8 +39502,8 @@ function ensureVenv(log) {
|
|
|
39200
39502
|
}
|
|
39201
39503
|
try {
|
|
39202
39504
|
mkdirSync14(join52(homedir12(), ".open-agents"), { recursive: true });
|
|
39203
|
-
|
|
39204
|
-
|
|
39505
|
+
execSync26(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
39506
|
+
execSync26(`"${join52(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
39205
39507
|
stdio: "pipe",
|
|
39206
39508
|
timeout: 6e4
|
|
39207
39509
|
});
|
|
@@ -39214,7 +39516,7 @@ function ensureVenv(log) {
|
|
|
39214
39516
|
}
|
|
39215
39517
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
39216
39518
|
try {
|
|
39217
|
-
|
|
39519
|
+
execSync26(`sudo -n ${cmd}`, {
|
|
39218
39520
|
stdio: "pipe",
|
|
39219
39521
|
timeout: timeoutMs,
|
|
39220
39522
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -39227,7 +39529,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
39227
39529
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
39228
39530
|
try {
|
|
39229
39531
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
39230
|
-
|
|
39532
|
+
execSync26(`sudo -S bash -c '${escaped}'`, {
|
|
39231
39533
|
input: password + "\n",
|
|
39232
39534
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39233
39535
|
timeout: timeoutMs,
|
|
@@ -39334,7 +39636,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39334
39636
|
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
39335
39637
|
} else {
|
|
39336
39638
|
try {
|
|
39337
|
-
|
|
39639
|
+
execSync26(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
39338
39640
|
ok = true;
|
|
39339
39641
|
} catch {
|
|
39340
39642
|
ok = false;
|
|
@@ -39371,7 +39673,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39371
39673
|
const venvCmds = {
|
|
39372
39674
|
apt: () => {
|
|
39373
39675
|
try {
|
|
39374
|
-
const pyVer =
|
|
39676
|
+
const pyVer = execSync26(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
39375
39677
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
39376
39678
|
} catch {
|
|
39377
39679
|
return "apt-get install -y python3-venv";
|
|
@@ -39399,12 +39701,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39399
39701
|
const venvPip = join52(venvBin, "pip");
|
|
39400
39702
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
39401
39703
|
try {
|
|
39402
|
-
|
|
39704
|
+
execSync26(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
39403
39705
|
if (existsSync36(venvMoondream)) {
|
|
39404
39706
|
log("moondream-station installed successfully.");
|
|
39405
39707
|
} else {
|
|
39406
39708
|
try {
|
|
39407
|
-
const check =
|
|
39709
|
+
const check = execSync26(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
39408
39710
|
if (check.includes("moondream")) {
|
|
39409
39711
|
log("moondream-station package installed.");
|
|
39410
39712
|
}
|
|
@@ -39421,7 +39723,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39421
39723
|
const venvPip2 = join52(venvBin, "pip");
|
|
39422
39724
|
let ocrStackInstalled = false;
|
|
39423
39725
|
try {
|
|
39424
|
-
|
|
39726
|
+
execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
39425
39727
|
ocrStackInstalled = true;
|
|
39426
39728
|
} catch {
|
|
39427
39729
|
}
|
|
@@ -39429,9 +39731,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39429
39731
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
39430
39732
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
39431
39733
|
try {
|
|
39432
|
-
|
|
39734
|
+
execSync26(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
39433
39735
|
try {
|
|
39434
|
-
|
|
39736
|
+
execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
39435
39737
|
log("OCR Python stack installed successfully.");
|
|
39436
39738
|
} catch {
|
|
39437
39739
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -39455,17 +39757,17 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39455
39757
|
});
|
|
39456
39758
|
log("Installing cloudflared for live voice sessions...");
|
|
39457
39759
|
_cloudflaredInstallPromise = (async () => {
|
|
39458
|
-
const
|
|
39459
|
-
const os =
|
|
39760
|
+
const arch2 = process.arch;
|
|
39761
|
+
const os = platform2();
|
|
39460
39762
|
if (os !== "win32" && !ensureCurl()) {
|
|
39461
39763
|
log("curl not available \u2014 cannot install cloudflared.");
|
|
39462
39764
|
return false;
|
|
39463
39765
|
}
|
|
39464
39766
|
if (os === "linux") {
|
|
39465
39767
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
39466
|
-
const cfArch = archMap[
|
|
39768
|
+
const cfArch = archMap[arch2] ?? "amd64";
|
|
39467
39769
|
try {
|
|
39468
|
-
|
|
39770
|
+
execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
39469
39771
|
if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
|
|
39470
39772
|
process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
|
|
39471
39773
|
}
|
|
@@ -39476,7 +39778,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39476
39778
|
} catch {
|
|
39477
39779
|
}
|
|
39478
39780
|
try {
|
|
39479
|
-
|
|
39781
|
+
execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
|
|
39480
39782
|
if (hasCmd("cloudflared")) {
|
|
39481
39783
|
log("cloudflared installed.");
|
|
39482
39784
|
return true;
|
|
@@ -39485,7 +39787,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39485
39787
|
}
|
|
39486
39788
|
} else if (os === "darwin") {
|
|
39487
39789
|
try {
|
|
39488
|
-
|
|
39790
|
+
execSync26("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
39489
39791
|
if (hasCmd("cloudflared")) {
|
|
39490
39792
|
log("cloudflared installed via Homebrew.");
|
|
39491
39793
|
return true;
|
|
@@ -39534,14 +39836,14 @@ async function queryModelKVInfo(backendUrl, modelName) {
|
|
|
39534
39836
|
if (!data.model_info)
|
|
39535
39837
|
return null;
|
|
39536
39838
|
const info = data.model_info;
|
|
39537
|
-
const
|
|
39538
|
-
if (!
|
|
39839
|
+
const arch2 = info["general.architecture"];
|
|
39840
|
+
if (!arch2)
|
|
39539
39841
|
return null;
|
|
39540
|
-
const nLayers = info[`${
|
|
39541
|
-
const nKVHeads = info[`${
|
|
39542
|
-
const keyDim = info[`${
|
|
39543
|
-
const valDim = info[`${
|
|
39544
|
-
const archMax = info[`${
|
|
39842
|
+
const nLayers = info[`${arch2}.block_count`];
|
|
39843
|
+
const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
|
|
39844
|
+
const keyDim = info[`${arch2}.attention.key_length`];
|
|
39845
|
+
const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
|
|
39846
|
+
const archMax = info[`${arch2}.context_length`];
|
|
39545
39847
|
if (!nLayers || !nKVHeads || !keyDim || !valDim || !archMax)
|
|
39546
39848
|
return null;
|
|
39547
39849
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
@@ -39627,7 +39929,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
39627
39929
|
}
|
|
39628
39930
|
async function ensureNeovim() {
|
|
39629
39931
|
try {
|
|
39630
|
-
const nvimPath =
|
|
39932
|
+
const nvimPath = execSync26("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
39631
39933
|
encoding: "utf8",
|
|
39632
39934
|
stdio: "pipe",
|
|
39633
39935
|
timeout: 5e3
|
|
@@ -39636,27 +39938,27 @@ async function ensureNeovim() {
|
|
|
39636
39938
|
return nvimPath;
|
|
39637
39939
|
} catch {
|
|
39638
39940
|
}
|
|
39639
|
-
const
|
|
39640
|
-
const
|
|
39641
|
-
if (
|
|
39941
|
+
const platform6 = process.platform;
|
|
39942
|
+
const arch2 = process.arch;
|
|
39943
|
+
if (platform6 === "linux") {
|
|
39642
39944
|
const binDir = join52(homedir12(), ".local", "bin");
|
|
39643
39945
|
const nvimDest = join52(binDir, "nvim");
|
|
39644
39946
|
try {
|
|
39645
39947
|
mkdirSync14(binDir, { recursive: true });
|
|
39646
39948
|
} catch {
|
|
39647
39949
|
}
|
|
39648
|
-
const appImageName =
|
|
39950
|
+
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
39649
39951
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
39650
39952
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
39651
39953
|
try {
|
|
39652
|
-
|
|
39653
|
-
|
|
39954
|
+
execSync26(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
39955
|
+
execSync26(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
39654
39956
|
} catch (err) {
|
|
39655
39957
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
39656
39958
|
return null;
|
|
39657
39959
|
}
|
|
39658
39960
|
try {
|
|
39659
|
-
const ver =
|
|
39961
|
+
const ver = execSync26(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
39660
39962
|
console.log(` Installed: ${ver}`);
|
|
39661
39963
|
} catch {
|
|
39662
39964
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -39667,12 +39969,12 @@ async function ensureNeovim() {
|
|
|
39667
39969
|
ensurePathInShellRc(binDir);
|
|
39668
39970
|
return nvimDest;
|
|
39669
39971
|
}
|
|
39670
|
-
if (
|
|
39972
|
+
if (platform6 === "darwin") {
|
|
39671
39973
|
if (hasCmd("brew")) {
|
|
39672
39974
|
console.log(" Installing Neovim via Homebrew...");
|
|
39673
39975
|
try {
|
|
39674
|
-
|
|
39675
|
-
const nvimPath =
|
|
39976
|
+
execSync26("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
39977
|
+
const nvimPath = execSync26("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
39676
39978
|
return nvimPath || null;
|
|
39677
39979
|
} catch {
|
|
39678
39980
|
console.log(" brew install neovim failed.");
|
|
@@ -39682,11 +39984,11 @@ async function ensureNeovim() {
|
|
|
39682
39984
|
console.log(" Homebrew not found. Install Neovim: brew install neovim");
|
|
39683
39985
|
return null;
|
|
39684
39986
|
}
|
|
39685
|
-
if (
|
|
39987
|
+
if (platform6 === "win32") {
|
|
39686
39988
|
if (hasCmd("choco")) {
|
|
39687
39989
|
console.log(" Installing Neovim via Chocolatey...");
|
|
39688
39990
|
try {
|
|
39689
|
-
|
|
39991
|
+
execSync26("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
39690
39992
|
return "nvim";
|
|
39691
39993
|
} catch {
|
|
39692
39994
|
console.log(" choco install neovim failed.");
|
|
@@ -39695,7 +39997,7 @@ async function ensureNeovim() {
|
|
|
39695
39997
|
if (hasCmd("winget")) {
|
|
39696
39998
|
console.log(" Installing Neovim via winget...");
|
|
39697
39999
|
try {
|
|
39698
|
-
|
|
40000
|
+
execSync26("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
39699
40001
|
stdio: "inherit",
|
|
39700
40002
|
timeout: 12e4
|
|
39701
40003
|
});
|
|
@@ -40617,7 +40919,7 @@ var init_drop_panel = __esm({
|
|
|
40617
40919
|
import { existsSync as existsSync38, unlinkSync as unlinkSync7 } from "node:fs";
|
|
40618
40920
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
40619
40921
|
import { join as join53 } from "node:path";
|
|
40620
|
-
import { execSync as
|
|
40922
|
+
import { execSync as execSync27 } from "node:child_process";
|
|
40621
40923
|
function isNeovimActive() {
|
|
40622
40924
|
return _state !== null && !_state.cleanedUp;
|
|
40623
40925
|
}
|
|
@@ -40635,7 +40937,7 @@ async function startNeovimMode(opts) {
|
|
|
40635
40937
|
}
|
|
40636
40938
|
let nvimPath;
|
|
40637
40939
|
try {
|
|
40638
|
-
nvimPath =
|
|
40940
|
+
nvimPath = execSync27("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
40639
40941
|
if (!nvimPath)
|
|
40640
40942
|
throw new Error();
|
|
40641
40943
|
} catch {
|
|
@@ -41095,8 +41397,8 @@ __export(voice_exports, {
|
|
|
41095
41397
|
});
|
|
41096
41398
|
import { existsSync as existsSync39, mkdirSync as mkdirSync15, writeFileSync as writeFileSync16, readFileSync as readFileSync28, unlinkSync as unlinkSync8, readdirSync as readdirSync10, renameSync, statSync as statSync13 } from "node:fs";
|
|
41097
41399
|
import { join as join54, dirname as dirname18 } from "node:path";
|
|
41098
|
-
import { homedir as homedir13, tmpdir as tmpdir9, platform as
|
|
41099
|
-
import { execSync as
|
|
41400
|
+
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
41401
|
+
import { execSync as execSync28, spawn as nodeSpawn } from "node:child_process";
|
|
41100
41402
|
import { createRequire } from "node:module";
|
|
41101
41403
|
function sanitizeForTTS(text) {
|
|
41102
41404
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -41137,7 +41439,7 @@ function luxttsVenvDir() {
|
|
|
41137
41439
|
return join54(voiceDir(), "luxtts-venv");
|
|
41138
41440
|
}
|
|
41139
41441
|
function luxttsVenvPy() {
|
|
41140
|
-
return
|
|
41442
|
+
return platform3() === "win32" ? join54(luxttsVenvDir(), "Scripts", "python.exe") : join54(luxttsVenvDir(), "bin", "python3");
|
|
41141
41443
|
}
|
|
41142
41444
|
function luxttsRepoDir() {
|
|
41143
41445
|
return join54(voiceDir(), "LuxTTS");
|
|
@@ -42825,7 +43127,7 @@ var init_voice = __esm({
|
|
|
42825
43127
|
});
|
|
42826
43128
|
}
|
|
42827
43129
|
getPlayCommand(path) {
|
|
42828
|
-
const os =
|
|
43130
|
+
const os = platform3();
|
|
42829
43131
|
if (os === "darwin")
|
|
42830
43132
|
return ["afplay", path];
|
|
42831
43133
|
if (os === "win32") {
|
|
@@ -42837,7 +43139,7 @@ var init_voice = __esm({
|
|
|
42837
43139
|
}
|
|
42838
43140
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
42839
43141
|
try {
|
|
42840
|
-
|
|
43142
|
+
execSync28(`which ${player}`, { stdio: "pipe" });
|
|
42841
43143
|
return [player, path];
|
|
42842
43144
|
} catch {
|
|
42843
43145
|
}
|
|
@@ -42858,7 +43160,7 @@ var init_voice = __esm({
|
|
|
42858
43160
|
// -------------------------------------------------------------------------
|
|
42859
43161
|
/** Check if we're on macOS Apple Silicon */
|
|
42860
43162
|
isMlxCapable() {
|
|
42861
|
-
return
|
|
43163
|
+
return platform3() === "darwin" && process.arch === "arm64";
|
|
42862
43164
|
}
|
|
42863
43165
|
/** Resolve python3 binary path (cached after first call) */
|
|
42864
43166
|
findPython3() {
|
|
@@ -42866,7 +43168,7 @@ var init_voice = __esm({
|
|
|
42866
43168
|
return this.python3Path;
|
|
42867
43169
|
for (const bin of ["python3", "python"]) {
|
|
42868
43170
|
try {
|
|
42869
|
-
const path =
|
|
43171
|
+
const path = execSync28(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
42870
43172
|
if (path) {
|
|
42871
43173
|
this.python3Path = path;
|
|
42872
43174
|
return path;
|
|
@@ -42932,7 +43234,7 @@ var init_voice = __esm({
|
|
|
42932
43234
|
return false;
|
|
42933
43235
|
}
|
|
42934
43236
|
try {
|
|
42935
|
-
|
|
43237
|
+
execSync28(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
42936
43238
|
this.mlxInstalled = true;
|
|
42937
43239
|
return true;
|
|
42938
43240
|
} catch {
|
|
@@ -42993,11 +43295,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
42993
43295
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
42994
43296
|
].join("; ");
|
|
42995
43297
|
try {
|
|
42996
|
-
|
|
43298
|
+
execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
42997
43299
|
} catch (err) {
|
|
42998
43300
|
try {
|
|
42999
43301
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43000
|
-
|
|
43302
|
+
execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43001
43303
|
} catch (err2) {
|
|
43002
43304
|
return;
|
|
43003
43305
|
}
|
|
@@ -43061,11 +43363,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43061
43363
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43062
43364
|
].join("; ");
|
|
43063
43365
|
try {
|
|
43064
|
-
|
|
43366
|
+
execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43065
43367
|
} catch {
|
|
43066
43368
|
try {
|
|
43067
43369
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43068
|
-
|
|
43370
|
+
execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43069
43371
|
} catch {
|
|
43070
43372
|
return null;
|
|
43071
43373
|
}
|
|
@@ -43159,8 +43461,8 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43159
43461
|
pipArgsStr = "torch torchaudio --index-url https://download.pytorch.org/whl/cu124";
|
|
43160
43462
|
torchDesc = "CUDA (fallback)";
|
|
43161
43463
|
} catch {
|
|
43162
|
-
const
|
|
43163
|
-
if (
|
|
43464
|
+
const arch2 = process.arch;
|
|
43465
|
+
if (arch2 === "arm64" || arch2 === "arm") {
|
|
43164
43466
|
pipArgsStr = "torch torchaudio";
|
|
43165
43467
|
torchDesc = "ARM CPU (generic PyPI)";
|
|
43166
43468
|
} else {
|
|
@@ -43632,7 +43934,7 @@ if __name__ == '__main__':
|
|
|
43632
43934
|
async ensureRuntime() {
|
|
43633
43935
|
if (this.ort)
|
|
43634
43936
|
return;
|
|
43635
|
-
const
|
|
43937
|
+
const arch2 = process.arch;
|
|
43636
43938
|
mkdirSync15(voiceDir(), { recursive: true });
|
|
43637
43939
|
const pkgPath = join54(voiceDir(), "package.json");
|
|
43638
43940
|
const expectedDeps = {
|
|
@@ -43668,7 +43970,7 @@ if __name__ == '__main__':
|
|
|
43668
43970
|
const onnxNodeModules = join54(voiceDir(), "node_modules", "onnxruntime-node");
|
|
43669
43971
|
const onnxInstalled = existsSync39(onnxNodeModules);
|
|
43670
43972
|
if (onnxInstalled && !await probeOnnx()) {
|
|
43671
|
-
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${
|
|
43973
|
+
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). 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.`);
|
|
43672
43974
|
}
|
|
43673
43975
|
try {
|
|
43674
43976
|
this.ort = voiceRequire("onnxruntime-node");
|
|
@@ -43677,12 +43979,12 @@ if __name__ == '__main__':
|
|
|
43677
43979
|
try {
|
|
43678
43980
|
await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
|
|
43679
43981
|
} catch (err) {
|
|
43680
|
-
const archHint =
|
|
43982
|
+
const archHint = arch2 !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch2}.` : "";
|
|
43681
43983
|
throw new Error(`Failed to install voice dependencies.${archHint} Try manually: cd ${voiceDir()} && npm install
|
|
43682
43984
|
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
43683
43985
|
}
|
|
43684
43986
|
if (!await probeOnnx()) {
|
|
43685
|
-
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${
|
|
43987
|
+
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). 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.`);
|
|
43686
43988
|
}
|
|
43687
43989
|
try {
|
|
43688
43990
|
this.ort = voiceRequire("onnxruntime-node");
|
|
@@ -43700,7 +44002,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
43700
44002
|
const phonemizerMod = voiceRequire("phonemizer");
|
|
43701
44003
|
this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
|
|
43702
44004
|
} catch (err) {
|
|
43703
|
-
const archHint =
|
|
44005
|
+
const archHint = arch2 !== "x64" ? ` phonemizer WASM may not support ${process.platform}-${arch2}.` : "";
|
|
43704
44006
|
throw new Error(`Failed to install phonemizer.${archHint} Try manually: cd ${voiceDir()} && npm install
|
|
43705
44007
|
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
43706
44008
|
}
|
|
@@ -43803,6 +44105,109 @@ function safeLog(text) {
|
|
|
43803
44105
|
process.stdout.write(text + "\n");
|
|
43804
44106
|
}
|
|
43805
44107
|
}
|
|
44108
|
+
async function destroyOrphanProcesses(ctx, global) {
|
|
44109
|
+
const myPid = process.pid;
|
|
44110
|
+
const myPpid = process.ppid;
|
|
44111
|
+
const cwd4 = ctx.repoRoot || process.cwd();
|
|
44112
|
+
const patterns = [
|
|
44113
|
+
"open-agents.*--non-interactive",
|
|
44114
|
+
// Stale eval/cron OA instances
|
|
44115
|
+
"nexus-daemon\\.mjs",
|
|
44116
|
+
// Detached nexus daemons
|
|
44117
|
+
"vitest",
|
|
44118
|
+
// Orphaned test runners
|
|
44119
|
+
"esbuild.*--service.*--ping",
|
|
44120
|
+
// Leaked esbuild services
|
|
44121
|
+
"python3 -u -i -q",
|
|
44122
|
+
// Orphaned REPL processes (ReplTool)
|
|
44123
|
+
"chromium.*--headless",
|
|
44124
|
+
// Headless Chrome from browser_action/web_crawl
|
|
44125
|
+
"chrome.*--headless",
|
|
44126
|
+
// Chrome from Puppeteer/Playwright scrapers
|
|
44127
|
+
"crawlee-scraper\\.py",
|
|
44128
|
+
// Python crawlee scraper
|
|
44129
|
+
"web_scrape\\.py",
|
|
44130
|
+
// Python web scraper
|
|
44131
|
+
"start-moondream\\.py",
|
|
44132
|
+
// Moondream vision server
|
|
44133
|
+
"live-whisper\\.py",
|
|
44134
|
+
// Whisper ASR server
|
|
44135
|
+
"jest.*--forceExit"
|
|
44136
|
+
// Orphaned Jest runners
|
|
44137
|
+
];
|
|
44138
|
+
const patternArg = patterns.join("|");
|
|
44139
|
+
let killed = 0;
|
|
44140
|
+
try {
|
|
44141
|
+
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();
|
|
44142
|
+
if (!psOutput)
|
|
44143
|
+
return 0;
|
|
44144
|
+
const lines = psOutput.split("\n").filter((l) => l.trim());
|
|
44145
|
+
const candidates = [];
|
|
44146
|
+
for (const line of lines) {
|
|
44147
|
+
const parts = line.trim().split(/\s+/);
|
|
44148
|
+
const pid = parseInt(parts[0], 10);
|
|
44149
|
+
const ppid = parseInt(parts[1], 10);
|
|
44150
|
+
if (pid === myPid || pid === myPpid)
|
|
44151
|
+
continue;
|
|
44152
|
+
if (pid <= 10)
|
|
44153
|
+
continue;
|
|
44154
|
+
const cmd = parts.slice(6).join(" ");
|
|
44155
|
+
candidates.push({ pid, ppid, cmd });
|
|
44156
|
+
}
|
|
44157
|
+
if (!global) {
|
|
44158
|
+
const localCandidates = [];
|
|
44159
|
+
for (const c3 of candidates) {
|
|
44160
|
+
try {
|
|
44161
|
+
const procCwd = nodeExecSync(`readlink /proc/${c3.pid}/cwd 2>/dev/null`, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
44162
|
+
if (procCwd.startsWith(cwd4)) {
|
|
44163
|
+
localCandidates.push(c3);
|
|
44164
|
+
}
|
|
44165
|
+
} catch {
|
|
44166
|
+
if (/open-agents|nexus-daemon/.test(c3.cmd)) {
|
|
44167
|
+
localCandidates.push(c3);
|
|
44168
|
+
}
|
|
44169
|
+
}
|
|
44170
|
+
}
|
|
44171
|
+
candidates.length = 0;
|
|
44172
|
+
candidates.push(...localCandidates);
|
|
44173
|
+
}
|
|
44174
|
+
if (candidates.length === 0)
|
|
44175
|
+
return 0;
|
|
44176
|
+
renderInfo(`Found ${candidates.length} orphaned OA process(es)${global ? " (system-wide)" : ""}:`);
|
|
44177
|
+
for (const c3 of candidates) {
|
|
44178
|
+
const shortCmd = c3.cmd.length > 80 ? c3.cmd.slice(0, 77) + "..." : c3.cmd;
|
|
44179
|
+
process.stdout.write(` PID ${c3.pid}: ${shortCmd}
|
|
44180
|
+
`);
|
|
44181
|
+
}
|
|
44182
|
+
for (const c3 of candidates) {
|
|
44183
|
+
try {
|
|
44184
|
+
try {
|
|
44185
|
+
process.kill(-c3.pid, "SIGTERM");
|
|
44186
|
+
} catch {
|
|
44187
|
+
}
|
|
44188
|
+
process.kill(c3.pid, "SIGTERM");
|
|
44189
|
+
killed++;
|
|
44190
|
+
} catch {
|
|
44191
|
+
try {
|
|
44192
|
+
process.kill(c3.pid, "SIGKILL");
|
|
44193
|
+
killed++;
|
|
44194
|
+
} catch {
|
|
44195
|
+
}
|
|
44196
|
+
}
|
|
44197
|
+
}
|
|
44198
|
+
if (killed > 0) {
|
|
44199
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
44200
|
+
for (const c3 of candidates) {
|
|
44201
|
+
try {
|
|
44202
|
+
process.kill(c3.pid, "SIGKILL");
|
|
44203
|
+
} catch {
|
|
44204
|
+
}
|
|
44205
|
+
}
|
|
44206
|
+
}
|
|
44207
|
+
} catch {
|
|
44208
|
+
}
|
|
44209
|
+
return killed;
|
|
44210
|
+
}
|
|
43806
44211
|
async function handleSlashCommand(input, ctx) {
|
|
43807
44212
|
const trimmed = input.trim();
|
|
43808
44213
|
if (!trimmed.startsWith("/"))
|
|
@@ -45522,11 +45927,26 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45522
45927
|
return "handled";
|
|
45523
45928
|
}
|
|
45524
45929
|
case "destroy": {
|
|
45525
|
-
|
|
45526
|
-
|
|
45930
|
+
const subCmd = (arg || "").toLowerCase().trim();
|
|
45931
|
+
if (subCmd.startsWith("processes") || subCmd.startsWith("procs")) {
|
|
45932
|
+
const isGlobal = subCmd.includes("--global") || subCmd.includes("-g");
|
|
45933
|
+
const killed = await destroyOrphanProcesses(ctx, isGlobal);
|
|
45934
|
+
if (killed === 0) {
|
|
45935
|
+
renderInfo("No orphaned OA processes found.");
|
|
45936
|
+
} else {
|
|
45937
|
+
renderInfo(`Killed ${killed} orphaned OA process(es).`);
|
|
45938
|
+
}
|
|
45939
|
+
return "handled";
|
|
45527
45940
|
}
|
|
45528
|
-
|
|
45529
|
-
|
|
45941
|
+
if (subCmd === "project" || subCmd === "") {
|
|
45942
|
+
if (ctx.hasActiveTask?.()) {
|
|
45943
|
+
ctx.abortTask?.();
|
|
45944
|
+
}
|
|
45945
|
+
ctx.destroyProject?.();
|
|
45946
|
+
return "exit";
|
|
45947
|
+
}
|
|
45948
|
+
renderWarning(`Unknown /destroy target: "${subCmd}". Use: /destroy processes [--global] or /destroy project`);
|
|
45949
|
+
return "handled";
|
|
45530
45950
|
}
|
|
45531
45951
|
case "context": {
|
|
45532
45952
|
const subCmd = arg?.toLowerCase().split(/\s+/)[0] || "";
|
|
@@ -47035,7 +47455,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47035
47455
|
}
|
|
47036
47456
|
}
|
|
47037
47457
|
async function handleParallel(arg, ctx) {
|
|
47038
|
-
const { execSync:
|
|
47458
|
+
const { execSync: execSync33 } = await import("node:child_process");
|
|
47039
47459
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
47040
47460
|
const isRemote = ctx.config.backendType === "nexus";
|
|
47041
47461
|
if (isRemote) {
|
|
@@ -47059,7 +47479,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47059
47479
|
}
|
|
47060
47480
|
let systemdVal = "";
|
|
47061
47481
|
try {
|
|
47062
|
-
const out =
|
|
47482
|
+
const out = execSync33("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
47063
47483
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
47064
47484
|
if (match)
|
|
47065
47485
|
systemdVal = match[1];
|
|
@@ -47088,7 +47508,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47088
47508
|
}
|
|
47089
47509
|
const isSystemd = (() => {
|
|
47090
47510
|
try {
|
|
47091
|
-
const out =
|
|
47511
|
+
const out = execSync33("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
47092
47512
|
return out === "active" || out === "inactive";
|
|
47093
47513
|
} catch {
|
|
47094
47514
|
return false;
|
|
@@ -47102,10 +47522,10 @@ async function handleParallel(arg, ctx) {
|
|
|
47102
47522
|
const overrideContent = `[Service]
|
|
47103
47523
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
47104
47524
|
`;
|
|
47105
|
-
|
|
47106
|
-
|
|
47107
|
-
|
|
47108
|
-
|
|
47525
|
+
execSync33(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
47526
|
+
execSync33(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
47527
|
+
execSync33("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
47528
|
+
execSync33("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
47109
47529
|
let ready = false;
|
|
47110
47530
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
47111
47531
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -47132,7 +47552,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
47132
47552
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
47133
47553
|
try {
|
|
47134
47554
|
try {
|
|
47135
|
-
|
|
47555
|
+
execSync33("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
47136
47556
|
} catch {
|
|
47137
47557
|
}
|
|
47138
47558
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -47681,15 +48101,15 @@ function fmtUptime(ms) {
|
|
|
47681
48101
|
return `${Math.floor(sec / 3600)}h ${Math.floor(sec % 3600 / 60)}m`;
|
|
47682
48102
|
}
|
|
47683
48103
|
function getLocalSystemMetrics() {
|
|
47684
|
-
const
|
|
48104
|
+
const cpus5 = nodeOs.cpus();
|
|
47685
48105
|
const loads = nodeOs.loadavg();
|
|
47686
48106
|
const totalMem = nodeOs.totalmem();
|
|
47687
48107
|
const freeMem = nodeOs.freemem();
|
|
47688
48108
|
const usedMem = totalMem - freeMem;
|
|
47689
48109
|
const result = {
|
|
47690
|
-
cpuModel:
|
|
47691
|
-
cpuCores:
|
|
47692
|
-
cpuUtil: Math.min(100, Math.round(loads[0] /
|
|
48110
|
+
cpuModel: cpus5[0]?.model?.trim() ?? "unknown",
|
|
48111
|
+
cpuCores: cpus5.length,
|
|
48112
|
+
cpuUtil: Math.min(100, Math.round(loads[0] / cpus5.length * 100)),
|
|
47693
48113
|
memTotalGB: Math.round(totalMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
47694
48114
|
memUsedGB: Math.round(usedMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
47695
48115
|
memUtil: Math.round(usedMem / totalMem * 100),
|
|
@@ -47783,12 +48203,12 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
47783
48203
|
const now = Date.now();
|
|
47784
48204
|
const w = cols();
|
|
47785
48205
|
const h = rows();
|
|
47786
|
-
const
|
|
48206
|
+
const uptime2 = s ? fmtUptime(now - (s.startedAt || now)) : "0s";
|
|
47787
48207
|
const lines = [];
|
|
47788
48208
|
const statusDot = !s ? c2.dim("\u25CF") : s.status === "active" ? c2.green("\u25CF") : s.status === "error" ? c2.red("\u25CF") : c2.yellow("\u25CF");
|
|
47789
48209
|
const statusLabel = s?.status || "unknown";
|
|
47790
48210
|
lines.push("");
|
|
47791
|
-
lines.push(` ${c2.bold("Expose Dashboard")} ${statusDot} ${statusLabel} ${c2.dim("uptime")} ${
|
|
48211
|
+
lines.push(` ${c2.bold("Expose Dashboard")} ${statusDot} ${statusLabel} ${c2.dim("uptime")} ${uptime2} ${c2.dim((/* @__PURE__ */ new Date()).toLocaleTimeString())}`);
|
|
47792
48212
|
const isTunnel = !!gateway.tunnelUrl;
|
|
47793
48213
|
const isP2P = !!gateway.peerId;
|
|
47794
48214
|
const endpointId = isTunnel ? gateway.tunnelUrl : isP2P ? gateway.peerId : null;
|
|
@@ -47934,18 +48354,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
47934
48354
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
47935
48355
|
let copied = false;
|
|
47936
48356
|
try {
|
|
47937
|
-
const { execSync:
|
|
47938
|
-
const
|
|
47939
|
-
if (
|
|
47940
|
-
|
|
48357
|
+
const { execSync: execSync33 } = __require("node:child_process");
|
|
48358
|
+
const platform6 = process.platform;
|
|
48359
|
+
if (platform6 === "darwin") {
|
|
48360
|
+
execSync33("pbcopy", { input: cmd, timeout: 3e3 });
|
|
47941
48361
|
copied = true;
|
|
47942
|
-
} else if (
|
|
47943
|
-
|
|
48362
|
+
} else if (platform6 === "win32") {
|
|
48363
|
+
execSync33("clip", { input: cmd, timeout: 3e3 });
|
|
47944
48364
|
copied = true;
|
|
47945
48365
|
} else {
|
|
47946
48366
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
47947
48367
|
try {
|
|
47948
|
-
|
|
48368
|
+
execSync33(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
47949
48369
|
copied = true;
|
|
47950
48370
|
break;
|
|
47951
48371
|
} catch {
|
|
@@ -48034,8 +48454,8 @@ var init_commands = __esm({
|
|
|
48034
48454
|
// packages/cli/dist/tui/project-context.js
|
|
48035
48455
|
import { existsSync as existsSync41, readFileSync as readFileSync30, readdirSync as readdirSync12 } from "node:fs";
|
|
48036
48456
|
import { join as join56, basename as basename11 } from "node:path";
|
|
48037
|
-
import { execSync as
|
|
48038
|
-
import { homedir as homedir15, platform as
|
|
48457
|
+
import { execSync as execSync29 } from "node:child_process";
|
|
48458
|
+
import { homedir as homedir15, platform as platform4, release } from "node:os";
|
|
48039
48459
|
function getModelTier(modelName) {
|
|
48040
48460
|
const m = modelName.toLowerCase();
|
|
48041
48461
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -48080,19 +48500,19 @@ function loadProjectMap(repoRoot) {
|
|
|
48080
48500
|
}
|
|
48081
48501
|
function getGitInfo(repoRoot) {
|
|
48082
48502
|
try {
|
|
48083
|
-
|
|
48503
|
+
execSync29("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
48084
48504
|
} catch {
|
|
48085
48505
|
return "";
|
|
48086
48506
|
}
|
|
48087
48507
|
const lines = [];
|
|
48088
48508
|
try {
|
|
48089
|
-
const branch =
|
|
48509
|
+
const branch = execSync29("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48090
48510
|
if (branch)
|
|
48091
48511
|
lines.push(`Branch: ${branch}`);
|
|
48092
48512
|
} catch {
|
|
48093
48513
|
}
|
|
48094
48514
|
try {
|
|
48095
|
-
const status =
|
|
48515
|
+
const status = execSync29("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48096
48516
|
if (status) {
|
|
48097
48517
|
const changed = status.split("\n").length;
|
|
48098
48518
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -48102,7 +48522,7 @@ function getGitInfo(repoRoot) {
|
|
|
48102
48522
|
} catch {
|
|
48103
48523
|
}
|
|
48104
48524
|
try {
|
|
48105
|
-
const log =
|
|
48525
|
+
const log = execSync29("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48106
48526
|
if (log)
|
|
48107
48527
|
lines.push(`Recent commits:
|
|
48108
48528
|
${log}`);
|
|
@@ -48177,7 +48597,7 @@ function getEnvironment(repoRoot) {
|
|
|
48177
48597
|
const lines = [
|
|
48178
48598
|
`Working directory: ${repoRoot}`,
|
|
48179
48599
|
`Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
|
|
48180
|
-
`Platform: ${
|
|
48600
|
+
`Platform: ${platform4()} ${release()}`,
|
|
48181
48601
|
`Node: ${process.version}`
|
|
48182
48602
|
];
|
|
48183
48603
|
return lines.join("\n");
|
|
@@ -49260,8 +49680,8 @@ function generateMnemonic(seed) {
|
|
|
49260
49680
|
}
|
|
49261
49681
|
function getNodeMnemonic() {
|
|
49262
49682
|
try {
|
|
49263
|
-
const { hostname:
|
|
49264
|
-
return generateMnemonic(`${
|
|
49683
|
+
const { hostname: hostname3, userInfo: userInfo2 } = __require("node:os");
|
|
49684
|
+
return generateMnemonic(`${hostname3()}:${userInfo2().username}`);
|
|
49265
49685
|
} catch {
|
|
49266
49686
|
return generateMnemonic("unknown-node");
|
|
49267
49687
|
}
|
|
@@ -50654,7 +51074,7 @@ var init_promptLoader3 = __esm({
|
|
|
50654
51074
|
// packages/cli/dist/tui/dream-engine.js
|
|
50655
51075
|
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readFileSync as readFileSync33, existsSync as existsSync44, cpSync, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
|
|
50656
51076
|
import { join as join60, basename as basename13 } from "node:path";
|
|
50657
|
-
import { execSync as
|
|
51077
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
50658
51078
|
function loadAutoresearchMemory(repoRoot) {
|
|
50659
51079
|
const memoryPath = join60(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
50660
51080
|
if (!existsSync44(memoryPath))
|
|
@@ -51018,7 +51438,7 @@ var init_dream_engine = __esm({
|
|
|
51018
51438
|
}
|
|
51019
51439
|
}
|
|
51020
51440
|
try {
|
|
51021
|
-
const output =
|
|
51441
|
+
const output = execSync30(cmd, {
|
|
51022
51442
|
cwd: this.repoRoot,
|
|
51023
51443
|
timeout: 3e4,
|
|
51024
51444
|
encoding: "utf-8",
|
|
@@ -51795,17 +52215,17 @@ ${summaryResult}
|
|
|
51795
52215
|
try {
|
|
51796
52216
|
mkdirSync19(checkpointDir, { recursive: true });
|
|
51797
52217
|
try {
|
|
51798
|
-
const gitStatus =
|
|
52218
|
+
const gitStatus = execSync30("git status --porcelain", {
|
|
51799
52219
|
cwd: this.repoRoot,
|
|
51800
52220
|
encoding: "utf-8",
|
|
51801
52221
|
timeout: 1e4
|
|
51802
52222
|
});
|
|
51803
|
-
const gitDiff =
|
|
52223
|
+
const gitDiff = execSync30("git diff", {
|
|
51804
52224
|
cwd: this.repoRoot,
|
|
51805
52225
|
encoding: "utf-8",
|
|
51806
52226
|
timeout: 1e4
|
|
51807
52227
|
});
|
|
51808
|
-
const gitHash =
|
|
52228
|
+
const gitHash = execSync30("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
51809
52229
|
cwd: this.repoRoot,
|
|
51810
52230
|
encoding: "utf-8",
|
|
51811
52231
|
timeout: 5e3
|
|
@@ -55319,7 +55739,7 @@ var init_braille_spinner = __esm({
|
|
|
55319
55739
|
});
|
|
55320
55740
|
|
|
55321
55741
|
// packages/cli/dist/tui/system-metrics.js
|
|
55322
|
-
import { loadavg as loadavg3, cpus as
|
|
55742
|
+
import { loadavg as loadavg3, cpus as cpus4, totalmem as totalmem5, freemem as freemem4, platform as platform5 } from "node:os";
|
|
55323
55743
|
import { exec as exec3 } from "node:child_process";
|
|
55324
55744
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
55325
55745
|
function formatRate(bytesPerSec) {
|
|
@@ -55353,7 +55773,7 @@ async function readProcNetDev() {
|
|
|
55353
55773
|
}
|
|
55354
55774
|
async function collectNetworkMetrics() {
|
|
55355
55775
|
const now = Date.now();
|
|
55356
|
-
const plat =
|
|
55776
|
+
const plat = platform5();
|
|
55357
55777
|
if (plat === "linux") {
|
|
55358
55778
|
const snap = await readProcNetDev();
|
|
55359
55779
|
if (!snap)
|
|
@@ -55451,10 +55871,10 @@ function getInstantSnapshot() {
|
|
|
55451
55871
|
}
|
|
55452
55872
|
function collectCpuRam() {
|
|
55453
55873
|
const [l1] = loadavg3();
|
|
55454
|
-
const cores =
|
|
55455
|
-
const cpuModel =
|
|
55456
|
-
const totalMem =
|
|
55457
|
-
const usedMem = totalMem -
|
|
55874
|
+
const cores = cpus4().length;
|
|
55875
|
+
const cpuModel = cpus4()[0]?.model ?? "";
|
|
55876
|
+
const totalMem = totalmem5();
|
|
55877
|
+
const usedMem = totalMem - freemem4();
|
|
55458
55878
|
return {
|
|
55459
55879
|
cpuUtil: Math.min(100, Math.round(l1 / cores * 100)),
|
|
55460
55880
|
cpuCores: cores,
|
|
@@ -55615,7 +56035,7 @@ __export(text_selection_exports, {
|
|
|
55615
56035
|
stripAnsi: () => stripAnsi3,
|
|
55616
56036
|
visibleLength: () => visibleLength
|
|
55617
56037
|
});
|
|
55618
|
-
import { execSync as
|
|
56038
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
55619
56039
|
function stripAnsi3(s) {
|
|
55620
56040
|
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
55621
56041
|
}
|
|
@@ -55624,18 +56044,18 @@ function visibleLength(s) {
|
|
|
55624
56044
|
}
|
|
55625
56045
|
function copyText(text) {
|
|
55626
56046
|
try {
|
|
55627
|
-
const
|
|
55628
|
-
if (
|
|
55629
|
-
|
|
56047
|
+
const platform6 = process.platform;
|
|
56048
|
+
if (platform6 === "darwin") {
|
|
56049
|
+
execSync31("pbcopy", { input: text, timeout: 3e3 });
|
|
55630
56050
|
return true;
|
|
55631
56051
|
}
|
|
55632
|
-
if (
|
|
55633
|
-
|
|
56052
|
+
if (platform6 === "win32") {
|
|
56053
|
+
execSync31("clip", { input: text, timeout: 3e3 });
|
|
55634
56054
|
return true;
|
|
55635
56055
|
}
|
|
55636
56056
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
55637
56057
|
try {
|
|
55638
|
-
|
|
56058
|
+
execSync31(tool, { input: text, timeout: 3e3 });
|
|
55639
56059
|
return true;
|
|
55640
56060
|
} catch {
|
|
55641
56061
|
continue;
|
|
@@ -55644,10 +56064,10 @@ function copyText(text) {
|
|
|
55644
56064
|
if (!_clipboardAutoInstallAttempted) {
|
|
55645
56065
|
_clipboardAutoInstallAttempted = true;
|
|
55646
56066
|
try {
|
|
55647
|
-
|
|
56067
|
+
execSync31("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
55648
56068
|
try {
|
|
55649
|
-
|
|
55650
|
-
|
|
56069
|
+
execSync31("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
56070
|
+
execSync31("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
55651
56071
|
return true;
|
|
55652
56072
|
} catch {
|
|
55653
56073
|
}
|
|
@@ -58088,7 +58508,7 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
58088
58508
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
58089
58509
|
import { readFileSync as readFileSync37, writeFileSync as writeFileSync21, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync18, mkdirSync as mkdirSync22 } from "node:fs";
|
|
58090
58510
|
import { existsSync as existsSync48 } from "node:fs";
|
|
58091
|
-
import { execSync as
|
|
58511
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
58092
58512
|
import { homedir as homedir16 } from "node:os";
|
|
58093
58513
|
function formatTimeAgo(date) {
|
|
58094
58514
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -58245,6 +58665,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
58245
58665
|
new WorkingNotesTool(),
|
|
58246
58666
|
new SemanticMapTool(repoRoot),
|
|
58247
58667
|
new RepoMapTool(repoRoot),
|
|
58668
|
+
new ProcessHealthTool(),
|
|
58248
58669
|
// Nexus P2P networking + x402 micropayments
|
|
58249
58670
|
new NexusTool(repoRoot)
|
|
58250
58671
|
];
|
|
@@ -58469,6 +58890,11 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
58469
58890
|
const modelTier = getModelTier(config.model);
|
|
58470
58891
|
const projectCtx = buildProjectContext(repoRoot, taskStores?.contextStores);
|
|
58471
58892
|
let dynamicContext = formatContextForPrompt(projectCtx, modelTier);
|
|
58893
|
+
try {
|
|
58894
|
+
const snap = collectSnapshot(repoRoot);
|
|
58895
|
+
dynamicContext += "\n\n" + formatSnapshotForContext(snap);
|
|
58896
|
+
} catch {
|
|
58897
|
+
}
|
|
58472
58898
|
try {
|
|
58473
58899
|
const { MemoryMetabolismTool: MemoryMetabolismTool2 } = __require("@open-agents/execution");
|
|
58474
58900
|
const mm = new MemoryMetabolismTool2(repoRoot);
|
|
@@ -61360,7 +61786,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61360
61786
|
try {
|
|
61361
61787
|
if (process.platform === "win32") {
|
|
61362
61788
|
try {
|
|
61363
|
-
|
|
61789
|
+
execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
61364
61790
|
} catch {
|
|
61365
61791
|
}
|
|
61366
61792
|
} else {
|
|
@@ -61387,7 +61813,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61387
61813
|
if (pid > 0) {
|
|
61388
61814
|
if (process.platform === "win32") {
|
|
61389
61815
|
try {
|
|
61390
|
-
|
|
61816
|
+
execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
61391
61817
|
} catch {
|
|
61392
61818
|
}
|
|
61393
61819
|
} else {
|
|
@@ -61404,7 +61830,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61404
61830
|
} catch {
|
|
61405
61831
|
}
|
|
61406
61832
|
try {
|
|
61407
|
-
|
|
61833
|
+
execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
61408
61834
|
} catch {
|
|
61409
61835
|
}
|
|
61410
61836
|
const oaPath = join64(repoRoot, OA_DIR);
|
|
@@ -61418,14 +61844,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61418
61844
|
} catch (err) {
|
|
61419
61845
|
if (attempt < 2) {
|
|
61420
61846
|
try {
|
|
61421
|
-
|
|
61847
|
+
execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
61422
61848
|
} catch {
|
|
61423
61849
|
}
|
|
61424
61850
|
} else {
|
|
61425
61851
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
61426
61852
|
if (process.platform === "win32") {
|
|
61427
61853
|
try {
|
|
61428
|
-
|
|
61854
|
+
execSync32(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
61429
61855
|
deleted = true;
|
|
61430
61856
|
} catch {
|
|
61431
61857
|
}
|