open-agents-ai 0.151.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 +332 -183
- 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
|
|
@@ -20529,8 +20529,8 @@ import { execSync as execSync22 } from "node:child_process";
|
|
|
20529
20529
|
function getSystemStatus() {
|
|
20530
20530
|
const lines = ["# System Health\n"];
|
|
20531
20531
|
try {
|
|
20532
|
-
const
|
|
20533
|
-
const loadMatch =
|
|
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
20534
|
if (loadMatch) {
|
|
20535
20535
|
lines.push(`CPU Load: ${loadMatch[1]} (1m) ${loadMatch[2]} (5m) ${loadMatch[3]} (15m)`);
|
|
20536
20536
|
}
|
|
@@ -20678,6 +20678,147 @@ var init_process_health = __esm({
|
|
|
20678
20678
|
}
|
|
20679
20679
|
});
|
|
20680
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
|
+
|
|
20681
20822
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
20682
20823
|
import { existsSync as existsSync27, readFileSync as readFileSync20 } from "node:fs";
|
|
20683
20824
|
import { join as join41 } from "node:path";
|
|
@@ -21508,6 +21649,7 @@ __export(dist_exports, {
|
|
|
21508
21649
|
checkDesktopDeps: () => checkDesktopDeps,
|
|
21509
21650
|
clearExploreNotes: () => clearExploreNotes,
|
|
21510
21651
|
clearWorkingNotes: () => clearWorkingNotes,
|
|
21652
|
+
collectSnapshot: () => collectSnapshot,
|
|
21511
21653
|
createFortemiBridgeTools: () => createFortemiBridgeTools,
|
|
21512
21654
|
createWorktree: () => createWorktree,
|
|
21513
21655
|
detectSearchProvider: () => detectSearchProvider,
|
|
@@ -21515,6 +21657,7 @@ __export(dist_exports, {
|
|
|
21515
21657
|
ensureAllDesktopDeps: () => ensureAllDesktopDeps,
|
|
21516
21658
|
ensureCommand: () => ensureCommand,
|
|
21517
21659
|
ensureDepsForGroup: () => ensureDepsForGroup,
|
|
21660
|
+
formatSnapshotForContext: () => formatSnapshotForContext,
|
|
21518
21661
|
getActiveAttentionItems: () => getActiveAttentionItems,
|
|
21519
21662
|
getDueReminders: () => getDueReminders,
|
|
21520
21663
|
getExploreNotes: () => getExploreNotes,
|
|
@@ -21614,6 +21757,7 @@ var init_dist2 = __esm({
|
|
|
21614
21757
|
init_change_log();
|
|
21615
21758
|
init_repo_map();
|
|
21616
21759
|
init_process_health();
|
|
21760
|
+
init_environment_snapshot();
|
|
21617
21761
|
init_nexus();
|
|
21618
21762
|
init_fortemi_bridge();
|
|
21619
21763
|
init_system_deps();
|
|
@@ -28423,7 +28567,7 @@ __export(listen_exports, {
|
|
|
28423
28567
|
isVideoPath: () => isVideoPath,
|
|
28424
28568
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
28425
28569
|
});
|
|
28426
|
-
import { spawn as spawn15, execSync as
|
|
28570
|
+
import { spawn as spawn15, execSync as execSync24 } from "node:child_process";
|
|
28427
28571
|
import { existsSync as existsSync31, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readdirSync as readdirSync7 } from "node:fs";
|
|
28428
28572
|
import { join as join46, dirname as dirname14 } from "node:path";
|
|
28429
28573
|
import { homedir as homedir10 } from "node:os";
|
|
@@ -28442,10 +28586,10 @@ function isTranscribablePath(path) {
|
|
|
28442
28586
|
return isAudioPath(path) || isVideoPath(path);
|
|
28443
28587
|
}
|
|
28444
28588
|
function findMicCaptureCommand() {
|
|
28445
|
-
const
|
|
28446
|
-
if (
|
|
28589
|
+
const platform6 = process.platform;
|
|
28590
|
+
if (platform6 === "linux") {
|
|
28447
28591
|
try {
|
|
28448
|
-
|
|
28592
|
+
execSync24("which arecord", { stdio: "pipe" });
|
|
28449
28593
|
return {
|
|
28450
28594
|
cmd: "arecord",
|
|
28451
28595
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -28453,9 +28597,9 @@ function findMicCaptureCommand() {
|
|
|
28453
28597
|
} catch {
|
|
28454
28598
|
}
|
|
28455
28599
|
}
|
|
28456
|
-
if (
|
|
28600
|
+
if (platform6 === "darwin") {
|
|
28457
28601
|
try {
|
|
28458
|
-
|
|
28602
|
+
execSync24("which sox", { stdio: "pipe" });
|
|
28459
28603
|
return {
|
|
28460
28604
|
cmd: "sox",
|
|
28461
28605
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -28464,8 +28608,8 @@ function findMicCaptureCommand() {
|
|
|
28464
28608
|
}
|
|
28465
28609
|
}
|
|
28466
28610
|
try {
|
|
28467
|
-
|
|
28468
|
-
if (
|
|
28611
|
+
execSync24("which ffmpeg", { stdio: "pipe" });
|
|
28612
|
+
if (platform6 === "linux") {
|
|
28469
28613
|
return {
|
|
28470
28614
|
cmd: "ffmpeg",
|
|
28471
28615
|
args: [
|
|
@@ -28484,7 +28628,7 @@ function findMicCaptureCommand() {
|
|
|
28484
28628
|
"pipe:1"
|
|
28485
28629
|
]
|
|
28486
28630
|
};
|
|
28487
|
-
} else if (
|
|
28631
|
+
} else if (platform6 === "darwin") {
|
|
28488
28632
|
return {
|
|
28489
28633
|
cmd: "ffmpeg",
|
|
28490
28634
|
args: [
|
|
@@ -28523,7 +28667,7 @@ function findLiveWhisperScript() {
|
|
|
28523
28667
|
return p;
|
|
28524
28668
|
}
|
|
28525
28669
|
try {
|
|
28526
|
-
const globalRoot =
|
|
28670
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28527
28671
|
encoding: "utf-8",
|
|
28528
28672
|
timeout: 5e3,
|
|
28529
28673
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28556,7 +28700,7 @@ function ensureTranscribeCliBackground() {
|
|
|
28556
28700
|
return;
|
|
28557
28701
|
_bgInstallPromise = (async () => {
|
|
28558
28702
|
try {
|
|
28559
|
-
const globalRoot =
|
|
28703
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28560
28704
|
encoding: "utf-8",
|
|
28561
28705
|
timeout: 5e3,
|
|
28562
28706
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28762,7 +28906,7 @@ var init_listen = __esm({
|
|
|
28762
28906
|
}
|
|
28763
28907
|
if (!this.transcribeCliAvailable) {
|
|
28764
28908
|
try {
|
|
28765
|
-
|
|
28909
|
+
execSync24("which transcribe-cli", { stdio: "pipe" });
|
|
28766
28910
|
this.transcribeCliAvailable = true;
|
|
28767
28911
|
} catch {
|
|
28768
28912
|
this.transcribeCliAvailable = false;
|
|
@@ -28779,7 +28923,7 @@ var init_listen = __esm({
|
|
|
28779
28923
|
} catch {
|
|
28780
28924
|
}
|
|
28781
28925
|
try {
|
|
28782
|
-
const globalRoot =
|
|
28926
|
+
const globalRoot = execSync24("npm root -g", {
|
|
28783
28927
|
encoding: "utf-8",
|
|
28784
28928
|
timeout: 5e3,
|
|
28785
28929
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -28829,7 +28973,7 @@ var init_listen = __esm({
|
|
|
28829
28973
|
}
|
|
28830
28974
|
if (!tc) {
|
|
28831
28975
|
try {
|
|
28832
|
-
|
|
28976
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
28833
28977
|
this.transcribeCliAvailable = null;
|
|
28834
28978
|
tc = await this.loadTranscribeCli();
|
|
28835
28979
|
} catch {
|
|
@@ -29012,7 +29156,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29012
29156
|
}
|
|
29013
29157
|
if (!tc) {
|
|
29014
29158
|
try {
|
|
29015
|
-
|
|
29159
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29016
29160
|
this.transcribeCliAvailable = null;
|
|
29017
29161
|
tc = await this.loadTranscribeCli();
|
|
29018
29162
|
} catch {
|
|
@@ -29066,7 +29210,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29066
29210
|
}
|
|
29067
29211
|
if (!tc) {
|
|
29068
29212
|
try {
|
|
29069
|
-
|
|
29213
|
+
execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29070
29214
|
this.transcribeCliAvailable = null;
|
|
29071
29215
|
tc = await this.loadTranscribeCli();
|
|
29072
29216
|
} catch {
|
|
@@ -33573,7 +33717,7 @@ var init_render = __esm({
|
|
|
33573
33717
|
|
|
33574
33718
|
// packages/cli/dist/tui/voice-session.js
|
|
33575
33719
|
import { createServer as createServer2 } from "node:http";
|
|
33576
|
-
import { spawn as spawn16, execSync as
|
|
33720
|
+
import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
|
|
33577
33721
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
33578
33722
|
function generateFrontendHTML() {
|
|
33579
33723
|
return `<!DOCTYPE html>
|
|
@@ -34305,7 +34449,7 @@ import { spawn as spawn17, exec } from "node:child_process";
|
|
|
34305
34449
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
34306
34450
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
34307
34451
|
import { URL as URL2 } from "node:url";
|
|
34308
|
-
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
34452
|
+
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
34309
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";
|
|
34310
34454
|
import { join as join47 } from "node:path";
|
|
34311
34455
|
function cleanForwardHeaders(raw, targetHost) {
|
|
@@ -34397,9 +34541,9 @@ function parseRateLimitHeaders(headers) {
|
|
|
34397
34541
|
}
|
|
34398
34542
|
async function collectSystemMetricsAsync() {
|
|
34399
34543
|
const [l1, l5, l15] = loadavg();
|
|
34400
|
-
const cores =
|
|
34401
|
-
const totalMem =
|
|
34402
|
-
const freeMem =
|
|
34544
|
+
const cores = cpus2().length;
|
|
34545
|
+
const totalMem = totalmem2();
|
|
34546
|
+
const freeMem = freemem2();
|
|
34403
34547
|
const usedMem = totalMem - freeMem;
|
|
34404
34548
|
const gpu = {
|
|
34405
34549
|
available: false,
|
|
@@ -36942,7 +37086,7 @@ ${activitySummary}
|
|
|
36942
37086
|
});
|
|
36943
37087
|
|
|
36944
37088
|
// packages/cli/dist/tui/model-picker.js
|
|
36945
|
-
import { totalmem as
|
|
37089
|
+
import { totalmem as totalmem3 } from "node:os";
|
|
36946
37090
|
function isImageGenModel(name, family) {
|
|
36947
37091
|
return IMAGE_GEN_PATTERNS.some((p) => p.test(name) || family && p.test(family));
|
|
36948
37092
|
}
|
|
@@ -36991,15 +37135,15 @@ async function fetchOllamaModels(baseUrl) {
|
|
|
36991
37135
|
}
|
|
36992
37136
|
if (show.model_info) {
|
|
36993
37137
|
const info = show.model_info;
|
|
36994
|
-
const
|
|
37138
|
+
const arch2 = info["general.architecture"];
|
|
36995
37139
|
const paramCount = info["general.parameter_count"];
|
|
36996
37140
|
const fileSizeGB = result[i].sizeBytes > 0 ? result[i].sizeBytes / 1024 ** 3 : paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
36997
|
-
if (
|
|
36998
|
-
const archMax = info[`${
|
|
36999
|
-
const nLayers = info[`${
|
|
37000
|
-
const nKVHeads = info[`${
|
|
37001
|
-
const keyDim = info[`${
|
|
37002
|
-
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;
|
|
37003
37147
|
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
37004
37148
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
37005
37149
|
result[i].contextLength = estimateRealisticContext(kvBytesPerToken, archMax, fileSizeGB);
|
|
@@ -37302,15 +37446,15 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
37302
37446
|
}
|
|
37303
37447
|
if (data.model_info) {
|
|
37304
37448
|
const info = data.model_info;
|
|
37305
|
-
const
|
|
37449
|
+
const arch2 = info["general.architecture"];
|
|
37306
37450
|
const paramCount = info["general.parameter_count"];
|
|
37307
37451
|
const modelSizeGB2 = paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
37308
|
-
if (
|
|
37309
|
-
const archMax = info[`${
|
|
37310
|
-
const nLayers = info[`${
|
|
37311
|
-
const nKVHeads = info[`${
|
|
37312
|
-
const keyDim = info[`${
|
|
37313
|
-
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;
|
|
37314
37458
|
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
37315
37459
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
37316
37460
|
return estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2);
|
|
@@ -37327,7 +37471,7 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
37327
37471
|
}
|
|
37328
37472
|
}
|
|
37329
37473
|
function estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2) {
|
|
37330
|
-
const totalMemGB =
|
|
37474
|
+
const totalMemGB = totalmem3() / 1024 ** 3;
|
|
37331
37475
|
const usableBytes = totalMemGB * 0.7 * 1024 ** 3;
|
|
37332
37476
|
const maxTokens = Math.floor(usableBytes / kvBytesPerToken);
|
|
37333
37477
|
let numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
|
|
@@ -38203,18 +38347,18 @@ var init_oa_directory = __esm({
|
|
|
38203
38347
|
|
|
38204
38348
|
// packages/cli/dist/tui/setup.js
|
|
38205
38349
|
import * as readline from "node:readline";
|
|
38206
|
-
import { execSync as
|
|
38350
|
+
import { execSync as execSync26, spawn as spawn18, exec as exec2 } from "node:child_process";
|
|
38207
38351
|
import { promisify as promisify6 } from "node:util";
|
|
38208
38352
|
import { existsSync as existsSync36, writeFileSync as writeFileSync15, readFileSync as readFileSync27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync14 } from "node:fs";
|
|
38209
38353
|
import { join as join52 } from "node:path";
|
|
38210
|
-
import { homedir as homedir12, platform } from "node:os";
|
|
38354
|
+
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
38211
38355
|
function detectSystemSpecs() {
|
|
38212
38356
|
let totalRamGB = 0;
|
|
38213
38357
|
let availableRamGB = 0;
|
|
38214
38358
|
let gpuVramGB = 0;
|
|
38215
38359
|
let gpuName = "";
|
|
38216
38360
|
try {
|
|
38217
|
-
const memInfo =
|
|
38361
|
+
const memInfo = execSync26("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
38218
38362
|
encoding: "utf8",
|
|
38219
38363
|
timeout: 5e3
|
|
38220
38364
|
});
|
|
@@ -38234,7 +38378,7 @@ function detectSystemSpecs() {
|
|
|
38234
38378
|
} catch {
|
|
38235
38379
|
}
|
|
38236
38380
|
try {
|
|
38237
|
-
const nvidiaSmi =
|
|
38381
|
+
const nvidiaSmi = execSync26("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
38238
38382
|
const lines = nvidiaSmi.trim().split("\n");
|
|
38239
38383
|
if (lines.length > 0) {
|
|
38240
38384
|
for (const line of lines) {
|
|
@@ -38394,7 +38538,7 @@ function askSecret(rl, question) {
|
|
|
38394
38538
|
function ensureCurl() {
|
|
38395
38539
|
if (hasCmd("curl"))
|
|
38396
38540
|
return true;
|
|
38397
|
-
const plat =
|
|
38541
|
+
const plat = platform2();
|
|
38398
38542
|
if (plat === "win32") {
|
|
38399
38543
|
process.stdout.write(` ${c2.yellow("\u26A0")} curl not found on Windows \u2014 install it manually.
|
|
38400
38544
|
`);
|
|
@@ -38413,7 +38557,7 @@ function ensureCurl() {
|
|
|
38413
38557
|
for (const s of strategies) {
|
|
38414
38558
|
if (hasCmd(s.check)) {
|
|
38415
38559
|
try {
|
|
38416
|
-
|
|
38560
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38417
38561
|
if (hasCmd("curl")) {
|
|
38418
38562
|
process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
|
|
38419
38563
|
`);
|
|
@@ -38427,7 +38571,7 @@ function ensureCurl() {
|
|
|
38427
38571
|
}
|
|
38428
38572
|
if (plat === "darwin") {
|
|
38429
38573
|
try {
|
|
38430
|
-
|
|
38574
|
+
execSync26("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
38431
38575
|
if (hasCmd("curl"))
|
|
38432
38576
|
return true;
|
|
38433
38577
|
} catch {
|
|
@@ -38438,7 +38582,7 @@ function ensureCurl() {
|
|
|
38438
38582
|
return false;
|
|
38439
38583
|
}
|
|
38440
38584
|
async function autoInstallOllama(rl) {
|
|
38441
|
-
const plat =
|
|
38585
|
+
const plat = platform2();
|
|
38442
38586
|
if (plat !== "win32" && !ensureCurl()) {
|
|
38443
38587
|
return false;
|
|
38444
38588
|
}
|
|
@@ -38462,7 +38606,7 @@ function installOllamaLinux() {
|
|
|
38462
38606
|
|
|
38463
38607
|
`);
|
|
38464
38608
|
try {
|
|
38465
|
-
|
|
38609
|
+
execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
38466
38610
|
stdio: "inherit",
|
|
38467
38611
|
timeout: 3e5
|
|
38468
38612
|
});
|
|
@@ -38490,7 +38634,7 @@ async function installOllamaMac(_rl) {
|
|
|
38490
38634
|
|
|
38491
38635
|
`);
|
|
38492
38636
|
try {
|
|
38493
|
-
|
|
38637
|
+
execSync26('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
38494
38638
|
if (!hasCmd("brew")) {
|
|
38495
38639
|
try {
|
|
38496
38640
|
const brewPrefix = existsSync36("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
@@ -38523,7 +38667,7 @@ async function installOllamaMac(_rl) {
|
|
|
38523
38667
|
|
|
38524
38668
|
`);
|
|
38525
38669
|
try {
|
|
38526
|
-
|
|
38670
|
+
execSync26("brew install ollama", {
|
|
38527
38671
|
stdio: "inherit",
|
|
38528
38672
|
timeout: 3e5
|
|
38529
38673
|
});
|
|
@@ -38550,7 +38694,7 @@ function installOllamaWindows() {
|
|
|
38550
38694
|
|
|
38551
38695
|
`);
|
|
38552
38696
|
try {
|
|
38553
|
-
|
|
38697
|
+
execSync26('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
38554
38698
|
stdio: "inherit",
|
|
38555
38699
|
timeout: 3e5
|
|
38556
38700
|
});
|
|
@@ -38631,7 +38775,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
38631
38775
|
}
|
|
38632
38776
|
function pullModelWithAutoUpdate(tag) {
|
|
38633
38777
|
try {
|
|
38634
|
-
|
|
38778
|
+
execSync26(`ollama pull ${tag}`, {
|
|
38635
38779
|
stdio: "inherit",
|
|
38636
38780
|
timeout: 36e5
|
|
38637
38781
|
// 1 hour max
|
|
@@ -38651,7 +38795,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
38651
38795
|
|
|
38652
38796
|
`);
|
|
38653
38797
|
try {
|
|
38654
|
-
|
|
38798
|
+
execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
38655
38799
|
stdio: "inherit",
|
|
38656
38800
|
timeout: 3e5
|
|
38657
38801
|
// 5 min max for install
|
|
@@ -38662,7 +38806,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
38662
38806
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
38663
38807
|
|
|
38664
38808
|
`);
|
|
38665
|
-
|
|
38809
|
+
execSync26(`ollama pull ${tag}`, {
|
|
38666
38810
|
stdio: "inherit",
|
|
38667
38811
|
timeout: 36e5
|
|
38668
38812
|
});
|
|
@@ -38746,7 +38890,7 @@ function renderScoreBar(score, width = 20) {
|
|
|
38746
38890
|
function ensurePython3() {
|
|
38747
38891
|
process.stdout.write(` ${c2.cyan("\u25CF")} Installing Python3...
|
|
38748
38892
|
`);
|
|
38749
|
-
const plat =
|
|
38893
|
+
const plat = platform2();
|
|
38750
38894
|
if (plat === "win32") {
|
|
38751
38895
|
process.stdout.write(` ${c2.dim("Download Python from https://python.org/downloads/")}
|
|
38752
38896
|
|
|
@@ -38764,7 +38908,7 @@ function ensurePython3() {
|
|
|
38764
38908
|
if (plat === "darwin") {
|
|
38765
38909
|
if (hasCmd("brew")) {
|
|
38766
38910
|
try {
|
|
38767
|
-
|
|
38911
|
+
execSync26("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
38768
38912
|
if (hasCmd("python3")) {
|
|
38769
38913
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
|
|
38770
38914
|
`);
|
|
@@ -38777,7 +38921,7 @@ function ensurePython3() {
|
|
|
38777
38921
|
for (const s of strategies) {
|
|
38778
38922
|
if (hasCmd(s.check)) {
|
|
38779
38923
|
try {
|
|
38780
|
-
|
|
38924
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38781
38925
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
38782
38926
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
|
|
38783
38927
|
`);
|
|
@@ -38793,11 +38937,11 @@ function ensurePython3() {
|
|
|
38793
38937
|
}
|
|
38794
38938
|
function checkPythonVenv() {
|
|
38795
38939
|
try {
|
|
38796
|
-
|
|
38940
|
+
execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
38797
38941
|
return true;
|
|
38798
38942
|
} catch {
|
|
38799
38943
|
try {
|
|
38800
|
-
|
|
38944
|
+
execSync26("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
38801
38945
|
return true;
|
|
38802
38946
|
} catch {
|
|
38803
38947
|
return false;
|
|
@@ -38816,7 +38960,7 @@ function ensurePythonVenv() {
|
|
|
38816
38960
|
for (const s of strategies) {
|
|
38817
38961
|
if (hasCmd(s.check)) {
|
|
38818
38962
|
try {
|
|
38819
|
-
|
|
38963
|
+
execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38820
38964
|
if (checkPythonVenv()) {
|
|
38821
38965
|
process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
|
|
38822
38966
|
`);
|
|
@@ -39252,7 +39396,7 @@ async function doSetup(config, rl) {
|
|
|
39252
39396
|
const modelfilePath = join52(modelDir2, `Modelfile.${customName}`);
|
|
39253
39397
|
writeFileSync15(modelfilePath, modelfileContent + "\n", "utf8");
|
|
39254
39398
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
39255
|
-
|
|
39399
|
+
execSync26(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
39256
39400
|
stdio: "pipe",
|
|
39257
39401
|
timeout: 12e4
|
|
39258
39402
|
});
|
|
@@ -39303,7 +39447,7 @@ function isFirstRun() {
|
|
|
39303
39447
|
function hasCmd(cmd) {
|
|
39304
39448
|
try {
|
|
39305
39449
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
39306
|
-
|
|
39450
|
+
execSync26(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
39307
39451
|
return true;
|
|
39308
39452
|
} catch {
|
|
39309
39453
|
return false;
|
|
@@ -39336,7 +39480,7 @@ function getVenvDir() {
|
|
|
39336
39480
|
}
|
|
39337
39481
|
function hasVenvModule() {
|
|
39338
39482
|
try {
|
|
39339
|
-
|
|
39483
|
+
execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39340
39484
|
return true;
|
|
39341
39485
|
} catch {
|
|
39342
39486
|
return false;
|
|
@@ -39358,8 +39502,8 @@ function ensureVenv(log) {
|
|
|
39358
39502
|
}
|
|
39359
39503
|
try {
|
|
39360
39504
|
mkdirSync14(join52(homedir12(), ".open-agents"), { recursive: true });
|
|
39361
|
-
|
|
39362
|
-
|
|
39505
|
+
execSync26(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
39506
|
+
execSync26(`"${join52(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
39363
39507
|
stdio: "pipe",
|
|
39364
39508
|
timeout: 6e4
|
|
39365
39509
|
});
|
|
@@ -39372,7 +39516,7 @@ function ensureVenv(log) {
|
|
|
39372
39516
|
}
|
|
39373
39517
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
39374
39518
|
try {
|
|
39375
|
-
|
|
39519
|
+
execSync26(`sudo -n ${cmd}`, {
|
|
39376
39520
|
stdio: "pipe",
|
|
39377
39521
|
timeout: timeoutMs,
|
|
39378
39522
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -39385,7 +39529,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
39385
39529
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
39386
39530
|
try {
|
|
39387
39531
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
39388
|
-
|
|
39532
|
+
execSync26(`sudo -S bash -c '${escaped}'`, {
|
|
39389
39533
|
input: password + "\n",
|
|
39390
39534
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39391
39535
|
timeout: timeoutMs,
|
|
@@ -39492,7 +39636,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39492
39636
|
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
39493
39637
|
} else {
|
|
39494
39638
|
try {
|
|
39495
|
-
|
|
39639
|
+
execSync26(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
39496
39640
|
ok = true;
|
|
39497
39641
|
} catch {
|
|
39498
39642
|
ok = false;
|
|
@@ -39529,7 +39673,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39529
39673
|
const venvCmds = {
|
|
39530
39674
|
apt: () => {
|
|
39531
39675
|
try {
|
|
39532
|
-
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();
|
|
39533
39677
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
39534
39678
|
} catch {
|
|
39535
39679
|
return "apt-get install -y python3-venv";
|
|
@@ -39557,12 +39701,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39557
39701
|
const venvPip = join52(venvBin, "pip");
|
|
39558
39702
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
39559
39703
|
try {
|
|
39560
|
-
|
|
39704
|
+
execSync26(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
39561
39705
|
if (existsSync36(venvMoondream)) {
|
|
39562
39706
|
log("moondream-station installed successfully.");
|
|
39563
39707
|
} else {
|
|
39564
39708
|
try {
|
|
39565
|
-
const check =
|
|
39709
|
+
const check = execSync26(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
39566
39710
|
if (check.includes("moondream")) {
|
|
39567
39711
|
log("moondream-station package installed.");
|
|
39568
39712
|
}
|
|
@@ -39579,7 +39723,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39579
39723
|
const venvPip2 = join52(venvBin, "pip");
|
|
39580
39724
|
let ocrStackInstalled = false;
|
|
39581
39725
|
try {
|
|
39582
|
-
|
|
39726
|
+
execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
39583
39727
|
ocrStackInstalled = true;
|
|
39584
39728
|
} catch {
|
|
39585
39729
|
}
|
|
@@ -39587,9 +39731,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
39587
39731
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
39588
39732
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
39589
39733
|
try {
|
|
39590
|
-
|
|
39734
|
+
execSync26(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
39591
39735
|
try {
|
|
39592
|
-
|
|
39736
|
+
execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
39593
39737
|
log("OCR Python stack installed successfully.");
|
|
39594
39738
|
} catch {
|
|
39595
39739
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -39613,17 +39757,17 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39613
39757
|
});
|
|
39614
39758
|
log("Installing cloudflared for live voice sessions...");
|
|
39615
39759
|
_cloudflaredInstallPromise = (async () => {
|
|
39616
|
-
const
|
|
39617
|
-
const os =
|
|
39760
|
+
const arch2 = process.arch;
|
|
39761
|
+
const os = platform2();
|
|
39618
39762
|
if (os !== "win32" && !ensureCurl()) {
|
|
39619
39763
|
log("curl not available \u2014 cannot install cloudflared.");
|
|
39620
39764
|
return false;
|
|
39621
39765
|
}
|
|
39622
39766
|
if (os === "linux") {
|
|
39623
39767
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
39624
|
-
const cfArch = archMap[
|
|
39768
|
+
const cfArch = archMap[arch2] ?? "amd64";
|
|
39625
39769
|
try {
|
|
39626
|
-
|
|
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 });
|
|
39627
39771
|
if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
|
|
39628
39772
|
process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
|
|
39629
39773
|
}
|
|
@@ -39634,7 +39778,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39634
39778
|
} catch {
|
|
39635
39779
|
}
|
|
39636
39780
|
try {
|
|
39637
|
-
|
|
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 });
|
|
39638
39782
|
if (hasCmd("cloudflared")) {
|
|
39639
39783
|
log("cloudflared installed.");
|
|
39640
39784
|
return true;
|
|
@@ -39643,7 +39787,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
39643
39787
|
}
|
|
39644
39788
|
} else if (os === "darwin") {
|
|
39645
39789
|
try {
|
|
39646
|
-
|
|
39790
|
+
execSync26("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
39647
39791
|
if (hasCmd("cloudflared")) {
|
|
39648
39792
|
log("cloudflared installed via Homebrew.");
|
|
39649
39793
|
return true;
|
|
@@ -39692,14 +39836,14 @@ async function queryModelKVInfo(backendUrl, modelName) {
|
|
|
39692
39836
|
if (!data.model_info)
|
|
39693
39837
|
return null;
|
|
39694
39838
|
const info = data.model_info;
|
|
39695
|
-
const
|
|
39696
|
-
if (!
|
|
39839
|
+
const arch2 = info["general.architecture"];
|
|
39840
|
+
if (!arch2)
|
|
39697
39841
|
return null;
|
|
39698
|
-
const nLayers = info[`${
|
|
39699
|
-
const nKVHeads = info[`${
|
|
39700
|
-
const keyDim = info[`${
|
|
39701
|
-
const valDim = info[`${
|
|
39702
|
-
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`];
|
|
39703
39847
|
if (!nLayers || !nKVHeads || !keyDim || !valDim || !archMax)
|
|
39704
39848
|
return null;
|
|
39705
39849
|
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
@@ -39785,7 +39929,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
39785
39929
|
}
|
|
39786
39930
|
async function ensureNeovim() {
|
|
39787
39931
|
try {
|
|
39788
|
-
const nvimPath =
|
|
39932
|
+
const nvimPath = execSync26("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
39789
39933
|
encoding: "utf8",
|
|
39790
39934
|
stdio: "pipe",
|
|
39791
39935
|
timeout: 5e3
|
|
@@ -39794,27 +39938,27 @@ async function ensureNeovim() {
|
|
|
39794
39938
|
return nvimPath;
|
|
39795
39939
|
} catch {
|
|
39796
39940
|
}
|
|
39797
|
-
const
|
|
39798
|
-
const
|
|
39799
|
-
if (
|
|
39941
|
+
const platform6 = process.platform;
|
|
39942
|
+
const arch2 = process.arch;
|
|
39943
|
+
if (platform6 === "linux") {
|
|
39800
39944
|
const binDir = join52(homedir12(), ".local", "bin");
|
|
39801
39945
|
const nvimDest = join52(binDir, "nvim");
|
|
39802
39946
|
try {
|
|
39803
39947
|
mkdirSync14(binDir, { recursive: true });
|
|
39804
39948
|
} catch {
|
|
39805
39949
|
}
|
|
39806
|
-
const appImageName =
|
|
39950
|
+
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
39807
39951
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
39808
39952
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
39809
39953
|
try {
|
|
39810
|
-
|
|
39811
|
-
|
|
39954
|
+
execSync26(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
39955
|
+
execSync26(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
39812
39956
|
} catch (err) {
|
|
39813
39957
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
39814
39958
|
return null;
|
|
39815
39959
|
}
|
|
39816
39960
|
try {
|
|
39817
|
-
const ver =
|
|
39961
|
+
const ver = execSync26(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
39818
39962
|
console.log(` Installed: ${ver}`);
|
|
39819
39963
|
} catch {
|
|
39820
39964
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -39825,12 +39969,12 @@ async function ensureNeovim() {
|
|
|
39825
39969
|
ensurePathInShellRc(binDir);
|
|
39826
39970
|
return nvimDest;
|
|
39827
39971
|
}
|
|
39828
|
-
if (
|
|
39972
|
+
if (platform6 === "darwin") {
|
|
39829
39973
|
if (hasCmd("brew")) {
|
|
39830
39974
|
console.log(" Installing Neovim via Homebrew...");
|
|
39831
39975
|
try {
|
|
39832
|
-
|
|
39833
|
-
const nvimPath =
|
|
39976
|
+
execSync26("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
39977
|
+
const nvimPath = execSync26("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
39834
39978
|
return nvimPath || null;
|
|
39835
39979
|
} catch {
|
|
39836
39980
|
console.log(" brew install neovim failed.");
|
|
@@ -39840,11 +39984,11 @@ async function ensureNeovim() {
|
|
|
39840
39984
|
console.log(" Homebrew not found. Install Neovim: brew install neovim");
|
|
39841
39985
|
return null;
|
|
39842
39986
|
}
|
|
39843
|
-
if (
|
|
39987
|
+
if (platform6 === "win32") {
|
|
39844
39988
|
if (hasCmd("choco")) {
|
|
39845
39989
|
console.log(" Installing Neovim via Chocolatey...");
|
|
39846
39990
|
try {
|
|
39847
|
-
|
|
39991
|
+
execSync26("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
39848
39992
|
return "nvim";
|
|
39849
39993
|
} catch {
|
|
39850
39994
|
console.log(" choco install neovim failed.");
|
|
@@ -39853,7 +39997,7 @@ async function ensureNeovim() {
|
|
|
39853
39997
|
if (hasCmd("winget")) {
|
|
39854
39998
|
console.log(" Installing Neovim via winget...");
|
|
39855
39999
|
try {
|
|
39856
|
-
|
|
40000
|
+
execSync26("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
39857
40001
|
stdio: "inherit",
|
|
39858
40002
|
timeout: 12e4
|
|
39859
40003
|
});
|
|
@@ -40775,7 +40919,7 @@ var init_drop_panel = __esm({
|
|
|
40775
40919
|
import { existsSync as existsSync38, unlinkSync as unlinkSync7 } from "node:fs";
|
|
40776
40920
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
40777
40921
|
import { join as join53 } from "node:path";
|
|
40778
|
-
import { execSync as
|
|
40922
|
+
import { execSync as execSync27 } from "node:child_process";
|
|
40779
40923
|
function isNeovimActive() {
|
|
40780
40924
|
return _state !== null && !_state.cleanedUp;
|
|
40781
40925
|
}
|
|
@@ -40793,7 +40937,7 @@ async function startNeovimMode(opts) {
|
|
|
40793
40937
|
}
|
|
40794
40938
|
let nvimPath;
|
|
40795
40939
|
try {
|
|
40796
|
-
nvimPath =
|
|
40940
|
+
nvimPath = execSync27("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
40797
40941
|
if (!nvimPath)
|
|
40798
40942
|
throw new Error();
|
|
40799
40943
|
} catch {
|
|
@@ -41253,8 +41397,8 @@ __export(voice_exports, {
|
|
|
41253
41397
|
});
|
|
41254
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";
|
|
41255
41399
|
import { join as join54, dirname as dirname18 } from "node:path";
|
|
41256
|
-
import { homedir as homedir13, tmpdir as tmpdir9, platform as
|
|
41257
|
-
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";
|
|
41258
41402
|
import { createRequire } from "node:module";
|
|
41259
41403
|
function sanitizeForTTS(text) {
|
|
41260
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();
|
|
@@ -41295,7 +41439,7 @@ function luxttsVenvDir() {
|
|
|
41295
41439
|
return join54(voiceDir(), "luxtts-venv");
|
|
41296
41440
|
}
|
|
41297
41441
|
function luxttsVenvPy() {
|
|
41298
|
-
return
|
|
41442
|
+
return platform3() === "win32" ? join54(luxttsVenvDir(), "Scripts", "python.exe") : join54(luxttsVenvDir(), "bin", "python3");
|
|
41299
41443
|
}
|
|
41300
41444
|
function luxttsRepoDir() {
|
|
41301
41445
|
return join54(voiceDir(), "LuxTTS");
|
|
@@ -42983,7 +43127,7 @@ var init_voice = __esm({
|
|
|
42983
43127
|
});
|
|
42984
43128
|
}
|
|
42985
43129
|
getPlayCommand(path) {
|
|
42986
|
-
const os =
|
|
43130
|
+
const os = platform3();
|
|
42987
43131
|
if (os === "darwin")
|
|
42988
43132
|
return ["afplay", path];
|
|
42989
43133
|
if (os === "win32") {
|
|
@@ -42995,7 +43139,7 @@ var init_voice = __esm({
|
|
|
42995
43139
|
}
|
|
42996
43140
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
42997
43141
|
try {
|
|
42998
|
-
|
|
43142
|
+
execSync28(`which ${player}`, { stdio: "pipe" });
|
|
42999
43143
|
return [player, path];
|
|
43000
43144
|
} catch {
|
|
43001
43145
|
}
|
|
@@ -43016,7 +43160,7 @@ var init_voice = __esm({
|
|
|
43016
43160
|
// -------------------------------------------------------------------------
|
|
43017
43161
|
/** Check if we're on macOS Apple Silicon */
|
|
43018
43162
|
isMlxCapable() {
|
|
43019
|
-
return
|
|
43163
|
+
return platform3() === "darwin" && process.arch === "arm64";
|
|
43020
43164
|
}
|
|
43021
43165
|
/** Resolve python3 binary path (cached after first call) */
|
|
43022
43166
|
findPython3() {
|
|
@@ -43024,7 +43168,7 @@ var init_voice = __esm({
|
|
|
43024
43168
|
return this.python3Path;
|
|
43025
43169
|
for (const bin of ["python3", "python"]) {
|
|
43026
43170
|
try {
|
|
43027
|
-
const path =
|
|
43171
|
+
const path = execSync28(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
43028
43172
|
if (path) {
|
|
43029
43173
|
this.python3Path = path;
|
|
43030
43174
|
return path;
|
|
@@ -43090,7 +43234,7 @@ var init_voice = __esm({
|
|
|
43090
43234
|
return false;
|
|
43091
43235
|
}
|
|
43092
43236
|
try {
|
|
43093
|
-
|
|
43237
|
+
execSync28(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
43094
43238
|
this.mlxInstalled = true;
|
|
43095
43239
|
return true;
|
|
43096
43240
|
} catch {
|
|
@@ -43151,11 +43295,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43151
43295
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43152
43296
|
].join("; ");
|
|
43153
43297
|
try {
|
|
43154
|
-
|
|
43298
|
+
execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43155
43299
|
} catch (err) {
|
|
43156
43300
|
try {
|
|
43157
43301
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43158
|
-
|
|
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() });
|
|
43159
43303
|
} catch (err2) {
|
|
43160
43304
|
return;
|
|
43161
43305
|
}
|
|
@@ -43219,11 +43363,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43219
43363
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43220
43364
|
].join("; ");
|
|
43221
43365
|
try {
|
|
43222
|
-
|
|
43366
|
+
execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43223
43367
|
} catch {
|
|
43224
43368
|
try {
|
|
43225
43369
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43226
|
-
|
|
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() });
|
|
43227
43371
|
} catch {
|
|
43228
43372
|
return null;
|
|
43229
43373
|
}
|
|
@@ -43317,8 +43461,8 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43317
43461
|
pipArgsStr = "torch torchaudio --index-url https://download.pytorch.org/whl/cu124";
|
|
43318
43462
|
torchDesc = "CUDA (fallback)";
|
|
43319
43463
|
} catch {
|
|
43320
|
-
const
|
|
43321
|
-
if (
|
|
43464
|
+
const arch2 = process.arch;
|
|
43465
|
+
if (arch2 === "arm64" || arch2 === "arm") {
|
|
43322
43466
|
pipArgsStr = "torch torchaudio";
|
|
43323
43467
|
torchDesc = "ARM CPU (generic PyPI)";
|
|
43324
43468
|
} else {
|
|
@@ -43790,7 +43934,7 @@ if __name__ == '__main__':
|
|
|
43790
43934
|
async ensureRuntime() {
|
|
43791
43935
|
if (this.ort)
|
|
43792
43936
|
return;
|
|
43793
|
-
const
|
|
43937
|
+
const arch2 = process.arch;
|
|
43794
43938
|
mkdirSync15(voiceDir(), { recursive: true });
|
|
43795
43939
|
const pkgPath = join54(voiceDir(), "package.json");
|
|
43796
43940
|
const expectedDeps = {
|
|
@@ -43826,7 +43970,7 @@ if __name__ == '__main__':
|
|
|
43826
43970
|
const onnxNodeModules = join54(voiceDir(), "node_modules", "onnxruntime-node");
|
|
43827
43971
|
const onnxInstalled = existsSync39(onnxNodeModules);
|
|
43828
43972
|
if (onnxInstalled && !await probeOnnx()) {
|
|
43829
|
-
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.`);
|
|
43830
43974
|
}
|
|
43831
43975
|
try {
|
|
43832
43976
|
this.ort = voiceRequire("onnxruntime-node");
|
|
@@ -43835,12 +43979,12 @@ if __name__ == '__main__':
|
|
|
43835
43979
|
try {
|
|
43836
43980
|
await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
|
|
43837
43981
|
} catch (err) {
|
|
43838
|
-
const archHint =
|
|
43982
|
+
const archHint = arch2 !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch2}.` : "";
|
|
43839
43983
|
throw new Error(`Failed to install voice dependencies.${archHint} Try manually: cd ${voiceDir()} && npm install
|
|
43840
43984
|
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
43841
43985
|
}
|
|
43842
43986
|
if (!await probeOnnx()) {
|
|
43843
|
-
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.`);
|
|
43844
43988
|
}
|
|
43845
43989
|
try {
|
|
43846
43990
|
this.ort = voiceRequire("onnxruntime-node");
|
|
@@ -43858,7 +44002,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
43858
44002
|
const phonemizerMod = voiceRequire("phonemizer");
|
|
43859
44003
|
this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
|
|
43860
44004
|
} catch (err) {
|
|
43861
|
-
const archHint =
|
|
44005
|
+
const archHint = arch2 !== "x64" ? ` phonemizer WASM may not support ${process.platform}-${arch2}.` : "";
|
|
43862
44006
|
throw new Error(`Failed to install phonemizer.${archHint} Try manually: cd ${voiceDir()} && npm install
|
|
43863
44007
|
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
43864
44008
|
}
|
|
@@ -47311,7 +47455,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47311
47455
|
}
|
|
47312
47456
|
}
|
|
47313
47457
|
async function handleParallel(arg, ctx) {
|
|
47314
|
-
const { execSync:
|
|
47458
|
+
const { execSync: execSync33 } = await import("node:child_process");
|
|
47315
47459
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
47316
47460
|
const isRemote = ctx.config.backendType === "nexus";
|
|
47317
47461
|
if (isRemote) {
|
|
@@ -47335,7 +47479,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47335
47479
|
}
|
|
47336
47480
|
let systemdVal = "";
|
|
47337
47481
|
try {
|
|
47338
|
-
const out =
|
|
47482
|
+
const out = execSync33("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
47339
47483
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
47340
47484
|
if (match)
|
|
47341
47485
|
systemdVal = match[1];
|
|
@@ -47364,7 +47508,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47364
47508
|
}
|
|
47365
47509
|
const isSystemd = (() => {
|
|
47366
47510
|
try {
|
|
47367
|
-
const out =
|
|
47511
|
+
const out = execSync33("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
47368
47512
|
return out === "active" || out === "inactive";
|
|
47369
47513
|
} catch {
|
|
47370
47514
|
return false;
|
|
@@ -47378,10 +47522,10 @@ async function handleParallel(arg, ctx) {
|
|
|
47378
47522
|
const overrideContent = `[Service]
|
|
47379
47523
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
47380
47524
|
`;
|
|
47381
|
-
|
|
47382
|
-
|
|
47383
|
-
|
|
47384
|
-
|
|
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" });
|
|
47385
47529
|
let ready = false;
|
|
47386
47530
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
47387
47531
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -47408,7 +47552,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
47408
47552
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
47409
47553
|
try {
|
|
47410
47554
|
try {
|
|
47411
|
-
|
|
47555
|
+
execSync33("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
47412
47556
|
} catch {
|
|
47413
47557
|
}
|
|
47414
47558
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -47957,15 +48101,15 @@ function fmtUptime(ms) {
|
|
|
47957
48101
|
return `${Math.floor(sec / 3600)}h ${Math.floor(sec % 3600 / 60)}m`;
|
|
47958
48102
|
}
|
|
47959
48103
|
function getLocalSystemMetrics() {
|
|
47960
|
-
const
|
|
48104
|
+
const cpus5 = nodeOs.cpus();
|
|
47961
48105
|
const loads = nodeOs.loadavg();
|
|
47962
48106
|
const totalMem = nodeOs.totalmem();
|
|
47963
48107
|
const freeMem = nodeOs.freemem();
|
|
47964
48108
|
const usedMem = totalMem - freeMem;
|
|
47965
48109
|
const result = {
|
|
47966
|
-
cpuModel:
|
|
47967
|
-
cpuCores:
|
|
47968
|
-
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)),
|
|
47969
48113
|
memTotalGB: Math.round(totalMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
47970
48114
|
memUsedGB: Math.round(usedMem / (1024 * 1024 * 1024) * 10) / 10,
|
|
47971
48115
|
memUtil: Math.round(usedMem / totalMem * 100),
|
|
@@ -48059,12 +48203,12 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
48059
48203
|
const now = Date.now();
|
|
48060
48204
|
const w = cols();
|
|
48061
48205
|
const h = rows();
|
|
48062
|
-
const
|
|
48206
|
+
const uptime2 = s ? fmtUptime(now - (s.startedAt || now)) : "0s";
|
|
48063
48207
|
const lines = [];
|
|
48064
48208
|
const statusDot = !s ? c2.dim("\u25CF") : s.status === "active" ? c2.green("\u25CF") : s.status === "error" ? c2.red("\u25CF") : c2.yellow("\u25CF");
|
|
48065
48209
|
const statusLabel = s?.status || "unknown";
|
|
48066
48210
|
lines.push("");
|
|
48067
|
-
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())}`);
|
|
48068
48212
|
const isTunnel = !!gateway.tunnelUrl;
|
|
48069
48213
|
const isP2P = !!gateway.peerId;
|
|
48070
48214
|
const endpointId = isTunnel ? gateway.tunnelUrl : isP2P ? gateway.peerId : null;
|
|
@@ -48210,18 +48354,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
48210
48354
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
48211
48355
|
let copied = false;
|
|
48212
48356
|
try {
|
|
48213
|
-
const { execSync:
|
|
48214
|
-
const
|
|
48215
|
-
if (
|
|
48216
|
-
|
|
48357
|
+
const { execSync: execSync33 } = __require("node:child_process");
|
|
48358
|
+
const platform6 = process.platform;
|
|
48359
|
+
if (platform6 === "darwin") {
|
|
48360
|
+
execSync33("pbcopy", { input: cmd, timeout: 3e3 });
|
|
48217
48361
|
copied = true;
|
|
48218
|
-
} else if (
|
|
48219
|
-
|
|
48362
|
+
} else if (platform6 === "win32") {
|
|
48363
|
+
execSync33("clip", { input: cmd, timeout: 3e3 });
|
|
48220
48364
|
copied = true;
|
|
48221
48365
|
} else {
|
|
48222
48366
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
48223
48367
|
try {
|
|
48224
|
-
|
|
48368
|
+
execSync33(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
48225
48369
|
copied = true;
|
|
48226
48370
|
break;
|
|
48227
48371
|
} catch {
|
|
@@ -48310,8 +48454,8 @@ var init_commands = __esm({
|
|
|
48310
48454
|
// packages/cli/dist/tui/project-context.js
|
|
48311
48455
|
import { existsSync as existsSync41, readFileSync as readFileSync30, readdirSync as readdirSync12 } from "node:fs";
|
|
48312
48456
|
import { join as join56, basename as basename11 } from "node:path";
|
|
48313
|
-
import { execSync as
|
|
48314
|
-
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";
|
|
48315
48459
|
function getModelTier(modelName) {
|
|
48316
48460
|
const m = modelName.toLowerCase();
|
|
48317
48461
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -48356,19 +48500,19 @@ function loadProjectMap(repoRoot) {
|
|
|
48356
48500
|
}
|
|
48357
48501
|
function getGitInfo(repoRoot) {
|
|
48358
48502
|
try {
|
|
48359
|
-
|
|
48503
|
+
execSync29("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
48360
48504
|
} catch {
|
|
48361
48505
|
return "";
|
|
48362
48506
|
}
|
|
48363
48507
|
const lines = [];
|
|
48364
48508
|
try {
|
|
48365
|
-
const branch =
|
|
48509
|
+
const branch = execSync29("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48366
48510
|
if (branch)
|
|
48367
48511
|
lines.push(`Branch: ${branch}`);
|
|
48368
48512
|
} catch {
|
|
48369
48513
|
}
|
|
48370
48514
|
try {
|
|
48371
|
-
const status =
|
|
48515
|
+
const status = execSync29("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48372
48516
|
if (status) {
|
|
48373
48517
|
const changed = status.split("\n").length;
|
|
48374
48518
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -48378,7 +48522,7 @@ function getGitInfo(repoRoot) {
|
|
|
48378
48522
|
} catch {
|
|
48379
48523
|
}
|
|
48380
48524
|
try {
|
|
48381
|
-
const log =
|
|
48525
|
+
const log = execSync29("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48382
48526
|
if (log)
|
|
48383
48527
|
lines.push(`Recent commits:
|
|
48384
48528
|
${log}`);
|
|
@@ -48453,7 +48597,7 @@ function getEnvironment(repoRoot) {
|
|
|
48453
48597
|
const lines = [
|
|
48454
48598
|
`Working directory: ${repoRoot}`,
|
|
48455
48599
|
`Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
|
|
48456
|
-
`Platform: ${
|
|
48600
|
+
`Platform: ${platform4()} ${release()}`,
|
|
48457
48601
|
`Node: ${process.version}`
|
|
48458
48602
|
];
|
|
48459
48603
|
return lines.join("\n");
|
|
@@ -49536,8 +49680,8 @@ function generateMnemonic(seed) {
|
|
|
49536
49680
|
}
|
|
49537
49681
|
function getNodeMnemonic() {
|
|
49538
49682
|
try {
|
|
49539
|
-
const { hostname:
|
|
49540
|
-
return generateMnemonic(`${
|
|
49683
|
+
const { hostname: hostname3, userInfo: userInfo2 } = __require("node:os");
|
|
49684
|
+
return generateMnemonic(`${hostname3()}:${userInfo2().username}`);
|
|
49541
49685
|
} catch {
|
|
49542
49686
|
return generateMnemonic("unknown-node");
|
|
49543
49687
|
}
|
|
@@ -50930,7 +51074,7 @@ var init_promptLoader3 = __esm({
|
|
|
50930
51074
|
// packages/cli/dist/tui/dream-engine.js
|
|
50931
51075
|
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readFileSync as readFileSync33, existsSync as existsSync44, cpSync, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
|
|
50932
51076
|
import { join as join60, basename as basename13 } from "node:path";
|
|
50933
|
-
import { execSync as
|
|
51077
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
50934
51078
|
function loadAutoresearchMemory(repoRoot) {
|
|
50935
51079
|
const memoryPath = join60(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
50936
51080
|
if (!existsSync44(memoryPath))
|
|
@@ -51294,7 +51438,7 @@ var init_dream_engine = __esm({
|
|
|
51294
51438
|
}
|
|
51295
51439
|
}
|
|
51296
51440
|
try {
|
|
51297
|
-
const output =
|
|
51441
|
+
const output = execSync30(cmd, {
|
|
51298
51442
|
cwd: this.repoRoot,
|
|
51299
51443
|
timeout: 3e4,
|
|
51300
51444
|
encoding: "utf-8",
|
|
@@ -52071,17 +52215,17 @@ ${summaryResult}
|
|
|
52071
52215
|
try {
|
|
52072
52216
|
mkdirSync19(checkpointDir, { recursive: true });
|
|
52073
52217
|
try {
|
|
52074
|
-
const gitStatus =
|
|
52218
|
+
const gitStatus = execSync30("git status --porcelain", {
|
|
52075
52219
|
cwd: this.repoRoot,
|
|
52076
52220
|
encoding: "utf-8",
|
|
52077
52221
|
timeout: 1e4
|
|
52078
52222
|
});
|
|
52079
|
-
const gitDiff =
|
|
52223
|
+
const gitDiff = execSync30("git diff", {
|
|
52080
52224
|
cwd: this.repoRoot,
|
|
52081
52225
|
encoding: "utf-8",
|
|
52082
52226
|
timeout: 1e4
|
|
52083
52227
|
});
|
|
52084
|
-
const gitHash =
|
|
52228
|
+
const gitHash = execSync30("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
52085
52229
|
cwd: this.repoRoot,
|
|
52086
52230
|
encoding: "utf-8",
|
|
52087
52231
|
timeout: 5e3
|
|
@@ -55595,7 +55739,7 @@ var init_braille_spinner = __esm({
|
|
|
55595
55739
|
});
|
|
55596
55740
|
|
|
55597
55741
|
// packages/cli/dist/tui/system-metrics.js
|
|
55598
|
-
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";
|
|
55599
55743
|
import { exec as exec3 } from "node:child_process";
|
|
55600
55744
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
55601
55745
|
function formatRate(bytesPerSec) {
|
|
@@ -55629,7 +55773,7 @@ async function readProcNetDev() {
|
|
|
55629
55773
|
}
|
|
55630
55774
|
async function collectNetworkMetrics() {
|
|
55631
55775
|
const now = Date.now();
|
|
55632
|
-
const plat =
|
|
55776
|
+
const plat = platform5();
|
|
55633
55777
|
if (plat === "linux") {
|
|
55634
55778
|
const snap = await readProcNetDev();
|
|
55635
55779
|
if (!snap)
|
|
@@ -55727,10 +55871,10 @@ function getInstantSnapshot() {
|
|
|
55727
55871
|
}
|
|
55728
55872
|
function collectCpuRam() {
|
|
55729
55873
|
const [l1] = loadavg3();
|
|
55730
|
-
const cores =
|
|
55731
|
-
const cpuModel =
|
|
55732
|
-
const totalMem =
|
|
55733
|
-
const usedMem = totalMem -
|
|
55874
|
+
const cores = cpus4().length;
|
|
55875
|
+
const cpuModel = cpus4()[0]?.model ?? "";
|
|
55876
|
+
const totalMem = totalmem5();
|
|
55877
|
+
const usedMem = totalMem - freemem4();
|
|
55734
55878
|
return {
|
|
55735
55879
|
cpuUtil: Math.min(100, Math.round(l1 / cores * 100)),
|
|
55736
55880
|
cpuCores: cores,
|
|
@@ -55891,7 +56035,7 @@ __export(text_selection_exports, {
|
|
|
55891
56035
|
stripAnsi: () => stripAnsi3,
|
|
55892
56036
|
visibleLength: () => visibleLength
|
|
55893
56037
|
});
|
|
55894
|
-
import { execSync as
|
|
56038
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
55895
56039
|
function stripAnsi3(s) {
|
|
55896
56040
|
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
55897
56041
|
}
|
|
@@ -55900,18 +56044,18 @@ function visibleLength(s) {
|
|
|
55900
56044
|
}
|
|
55901
56045
|
function copyText(text) {
|
|
55902
56046
|
try {
|
|
55903
|
-
const
|
|
55904
|
-
if (
|
|
55905
|
-
|
|
56047
|
+
const platform6 = process.platform;
|
|
56048
|
+
if (platform6 === "darwin") {
|
|
56049
|
+
execSync31("pbcopy", { input: text, timeout: 3e3 });
|
|
55906
56050
|
return true;
|
|
55907
56051
|
}
|
|
55908
|
-
if (
|
|
55909
|
-
|
|
56052
|
+
if (platform6 === "win32") {
|
|
56053
|
+
execSync31("clip", { input: text, timeout: 3e3 });
|
|
55910
56054
|
return true;
|
|
55911
56055
|
}
|
|
55912
56056
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
55913
56057
|
try {
|
|
55914
|
-
|
|
56058
|
+
execSync31(tool, { input: text, timeout: 3e3 });
|
|
55915
56059
|
return true;
|
|
55916
56060
|
} catch {
|
|
55917
56061
|
continue;
|
|
@@ -55920,10 +56064,10 @@ function copyText(text) {
|
|
|
55920
56064
|
if (!_clipboardAutoInstallAttempted) {
|
|
55921
56065
|
_clipboardAutoInstallAttempted = true;
|
|
55922
56066
|
try {
|
|
55923
|
-
|
|
56067
|
+
execSync31("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
55924
56068
|
try {
|
|
55925
|
-
|
|
55926
|
-
|
|
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 });
|
|
55927
56071
|
return true;
|
|
55928
56072
|
} catch {
|
|
55929
56073
|
}
|
|
@@ -58364,7 +58508,7 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
58364
58508
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
58365
58509
|
import { readFileSync as readFileSync37, writeFileSync as writeFileSync21, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync18, mkdirSync as mkdirSync22 } from "node:fs";
|
|
58366
58510
|
import { existsSync as existsSync48 } from "node:fs";
|
|
58367
|
-
import { execSync as
|
|
58511
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
58368
58512
|
import { homedir as homedir16 } from "node:os";
|
|
58369
58513
|
function formatTimeAgo(date) {
|
|
58370
58514
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -58746,6 +58890,11 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
58746
58890
|
const modelTier = getModelTier(config.model);
|
|
58747
58891
|
const projectCtx = buildProjectContext(repoRoot, taskStores?.contextStores);
|
|
58748
58892
|
let dynamicContext = formatContextForPrompt(projectCtx, modelTier);
|
|
58893
|
+
try {
|
|
58894
|
+
const snap = collectSnapshot(repoRoot);
|
|
58895
|
+
dynamicContext += "\n\n" + formatSnapshotForContext(snap);
|
|
58896
|
+
} catch {
|
|
58897
|
+
}
|
|
58749
58898
|
try {
|
|
58750
58899
|
const { MemoryMetabolismTool: MemoryMetabolismTool2 } = __require("@open-agents/execution");
|
|
58751
58900
|
const mm = new MemoryMetabolismTool2(repoRoot);
|
|
@@ -61637,7 +61786,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61637
61786
|
try {
|
|
61638
61787
|
if (process.platform === "win32") {
|
|
61639
61788
|
try {
|
|
61640
|
-
|
|
61789
|
+
execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
61641
61790
|
} catch {
|
|
61642
61791
|
}
|
|
61643
61792
|
} else {
|
|
@@ -61664,7 +61813,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61664
61813
|
if (pid > 0) {
|
|
61665
61814
|
if (process.platform === "win32") {
|
|
61666
61815
|
try {
|
|
61667
|
-
|
|
61816
|
+
execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
61668
61817
|
} catch {
|
|
61669
61818
|
}
|
|
61670
61819
|
} else {
|
|
@@ -61681,7 +61830,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61681
61830
|
} catch {
|
|
61682
61831
|
}
|
|
61683
61832
|
try {
|
|
61684
|
-
|
|
61833
|
+
execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
61685
61834
|
} catch {
|
|
61686
61835
|
}
|
|
61687
61836
|
const oaPath = join64(repoRoot, OA_DIR);
|
|
@@ -61695,14 +61844,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
61695
61844
|
} catch (err) {
|
|
61696
61845
|
if (attempt < 2) {
|
|
61697
61846
|
try {
|
|
61698
|
-
|
|
61847
|
+
execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
61699
61848
|
} catch {
|
|
61700
61849
|
}
|
|
61701
61850
|
} else {
|
|
61702
61851
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
61703
61852
|
if (process.platform === "win32") {
|
|
61704
61853
|
try {
|
|
61705
|
-
|
|
61854
|
+
execSync32(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
61706
61855
|
deleted = true;
|
|
61707
61856
|
} catch {
|
|
61708
61857
|
}
|