open-agents-ai 0.187.136 → 0.187.138
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 +693 -192
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -247838,9 +247838,9 @@ var init_vision = __esm({
|
|
|
247838
247838
|
if (ollamaResult)
|
|
247839
247839
|
return ollamaResult;
|
|
247840
247840
|
try {
|
|
247841
|
-
const { execSync:
|
|
247841
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
247842
247842
|
try {
|
|
247843
|
-
|
|
247843
|
+
execSync48("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
|
|
247844
247844
|
timeout: 12e4,
|
|
247845
247845
|
stdio: "pipe"
|
|
247846
247846
|
});
|
|
@@ -247853,7 +247853,7 @@ var init_vision = __esm({
|
|
|
247853
247853
|
} catch {
|
|
247854
247854
|
}
|
|
247855
247855
|
try {
|
|
247856
|
-
|
|
247856
|
+
execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247857
247857
|
const retryOllama = await this.tryOllamaVision(buffer2, filename, action, prompt, length4, start2);
|
|
247858
247858
|
if (retryOllama)
|
|
247859
247859
|
return retryOllama;
|
|
@@ -247961,8 +247961,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
|
|
|
247961
247961
|
const errText = await res.text().catch(() => "");
|
|
247962
247962
|
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
247963
247963
|
try {
|
|
247964
|
-
const { execSync:
|
|
247965
|
-
|
|
247964
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
247965
|
+
execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
247966
247966
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
247967
247967
|
method: "POST",
|
|
247968
247968
|
headers: { "Content-Type": "application/json" },
|
|
@@ -254210,10 +254210,14 @@ ${cameras.join("\n")}`,
|
|
|
254210
254210
|
}
|
|
254211
254211
|
let ssid = null;
|
|
254212
254212
|
try {
|
|
254213
|
+
try {
|
|
254214
|
+
execSync27("nmcli device wifi rescan 2>/dev/null", { timeout: 5e3, stdio: "pipe" });
|
|
254215
|
+
} catch {
|
|
254216
|
+
}
|
|
254213
254217
|
const wifiList = execSync27("nmcli device wifi list 2>/dev/null", { encoding: "utf8", timeout: 1e4 });
|
|
254214
|
-
const oscMatch = wifiList.match(
|
|
254218
|
+
const oscMatch = wifiList.match(/(QooCam[^\n]*?\.OSC)\s/i);
|
|
254215
254219
|
if (oscMatch)
|
|
254216
|
-
ssid = oscMatch[1];
|
|
254220
|
+
ssid = oscMatch[1].trim();
|
|
254217
254221
|
} catch {
|
|
254218
254222
|
}
|
|
254219
254223
|
let connected = false;
|
|
@@ -254269,7 +254273,7 @@ ${cameras.join("\n")}`,
|
|
|
254269
254273
|
execSync27("nmcli device wifi rescan 2>/dev/null", { timeout: 5e3, stdio: "pipe" });
|
|
254270
254274
|
execSync27("sleep 2", { timeout: 5e3 });
|
|
254271
254275
|
const wifiList = execSync27("nmcli device wifi list 2>/dev/null", { encoding: "utf8", timeout: 1e4 });
|
|
254272
|
-
const oscMatch = wifiList.match(
|
|
254276
|
+
const oscMatch = wifiList.match(/(QooCam[^\n]*?\.OSC)\s/i);
|
|
254273
254277
|
if (oscMatch)
|
|
254274
254278
|
ssid = oscMatch[1];
|
|
254275
254279
|
} catch {
|
|
@@ -254884,6 +254888,497 @@ ${devices.join("\n")}`,
|
|
|
254884
254888
|
}
|
|
254885
254889
|
});
|
|
254886
254890
|
|
|
254891
|
+
// packages/execution/dist/tools/wifi-control.js
|
|
254892
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
254893
|
+
var WifiControlTool;
|
|
254894
|
+
var init_wifi_control = __esm({
|
|
254895
|
+
"packages/execution/dist/tools/wifi-control.js"() {
|
|
254896
|
+
"use strict";
|
|
254897
|
+
WifiControlTool = class {
|
|
254898
|
+
name = "wifi_control";
|
|
254899
|
+
description = "Scan, connect, and manage WiFi networks. Actions: 'scan' to discover nearby networks, 'interfaces' to list WiFi adapters, 'connect' to join a network, 'disconnect' to leave, 'status' for current connection info, 'monitor' to toggle monitor mode on an adapter. Use this to explore the wireless environment, find networks, check signal strength, connect to specific networks, or manage multiple WiFi adapters.";
|
|
254900
|
+
parameters = {
|
|
254901
|
+
type: "object",
|
|
254902
|
+
properties: {
|
|
254903
|
+
action: {
|
|
254904
|
+
type: "string",
|
|
254905
|
+
enum: ["scan", "interfaces", "connect", "disconnect", "status", "monitor"],
|
|
254906
|
+
description: "Action to perform"
|
|
254907
|
+
},
|
|
254908
|
+
ssid: {
|
|
254909
|
+
type: "string",
|
|
254910
|
+
description: "WiFi network name (for 'connect' action)"
|
|
254911
|
+
},
|
|
254912
|
+
password: {
|
|
254913
|
+
type: "string",
|
|
254914
|
+
description: "WiFi password (for 'connect' action)"
|
|
254915
|
+
},
|
|
254916
|
+
interface: {
|
|
254917
|
+
type: "string",
|
|
254918
|
+
description: "WiFi interface name (e.g. wlp69s0, wlan1). Default: auto-detect."
|
|
254919
|
+
},
|
|
254920
|
+
enable: {
|
|
254921
|
+
type: "boolean",
|
|
254922
|
+
description: "true to enable, false to disable (for 'monitor' action)"
|
|
254923
|
+
}
|
|
254924
|
+
},
|
|
254925
|
+
required: ["action"]
|
|
254926
|
+
};
|
|
254927
|
+
async execute(args) {
|
|
254928
|
+
const action = args["action"];
|
|
254929
|
+
const start2 = performance.now();
|
|
254930
|
+
try {
|
|
254931
|
+
switch (action) {
|
|
254932
|
+
case "scan":
|
|
254933
|
+
return this.scanNetworks(args, start2);
|
|
254934
|
+
case "interfaces":
|
|
254935
|
+
return this.listInterfaces(start2);
|
|
254936
|
+
case "connect":
|
|
254937
|
+
return this.connectNetwork(args, start2);
|
|
254938
|
+
case "disconnect":
|
|
254939
|
+
return this.disconnectNetwork(args, start2);
|
|
254940
|
+
case "status":
|
|
254941
|
+
return this.connectionStatus(args, start2);
|
|
254942
|
+
case "monitor":
|
|
254943
|
+
return this.monitorMode(args, start2);
|
|
254944
|
+
default:
|
|
254945
|
+
return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
|
|
254946
|
+
}
|
|
254947
|
+
} catch (err) {
|
|
254948
|
+
return { success: false, output: "", error: `wifi_control error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
254949
|
+
}
|
|
254950
|
+
}
|
|
254951
|
+
// =========================================================================
|
|
254952
|
+
// Scan nearby WiFi networks
|
|
254953
|
+
// =========================================================================
|
|
254954
|
+
scanNetworks(args, start2) {
|
|
254955
|
+
const iface = args["interface"] || this.findWifiInterface();
|
|
254956
|
+
if (!iface) {
|
|
254957
|
+
return { success: false, output: "", error: "No WiFi interface found. Connect a WiFi adapter.", durationMs: performance.now() - start2 };
|
|
254958
|
+
}
|
|
254959
|
+
try {
|
|
254960
|
+
execSync30(`nmcli device wifi rescan ifname ${iface} 2>/dev/null`, { timeout: 1e4, stdio: "pipe" });
|
|
254961
|
+
execSync30("sleep 1", { timeout: 5e3 });
|
|
254962
|
+
} catch {
|
|
254963
|
+
}
|
|
254964
|
+
try {
|
|
254965
|
+
const raw = execSync30(`nmcli -t -f BSSID,SSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,IN-USE device wifi list ifname ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 15e3 });
|
|
254966
|
+
const networks = [];
|
|
254967
|
+
for (const line of raw.trim().split("\n").filter(Boolean)) {
|
|
254968
|
+
const parts = line.split(":");
|
|
254969
|
+
if (parts.length < 9)
|
|
254970
|
+
continue;
|
|
254971
|
+
const bssid = parts.slice(0, 6).join(":");
|
|
254972
|
+
const rest = parts.slice(6);
|
|
254973
|
+
if (rest.length < 9)
|
|
254974
|
+
continue;
|
|
254975
|
+
const ssid = rest[0] || "(hidden)";
|
|
254976
|
+
const channel = parseInt(rest[2] || "0");
|
|
254977
|
+
const frequency = rest[3] || "";
|
|
254978
|
+
const rate = rest[4] || "";
|
|
254979
|
+
const signal = parseInt(rest[5] || "0");
|
|
254980
|
+
const bars = rest[6] || "";
|
|
254981
|
+
const security = rest[7] || "Open";
|
|
254982
|
+
const active = rest[8] === "*";
|
|
254983
|
+
networks.push({ ssid, bssid, channel, frequency, signal, bars, security, rate, active });
|
|
254984
|
+
}
|
|
254985
|
+
if (networks.length === 0) {
|
|
254986
|
+
return { success: true, output: `No WiFi networks found on ${iface}. The adapter may be disabled or out of range.`, durationMs: performance.now() - start2 };
|
|
254987
|
+
}
|
|
254988
|
+
networks.sort((a2, b) => b.signal - a2.signal);
|
|
254989
|
+
const lines = networks.map((n2) => {
|
|
254990
|
+
const marker = n2.active ? " *" : " ";
|
|
254991
|
+
return `${marker}${n2.signal}% ${n2.bars} ${n2.ssid.padEnd(25)} Ch${String(n2.channel).padEnd(3)} ${n2.security.padEnd(12)} ${n2.rate} (${n2.bssid})`;
|
|
254992
|
+
});
|
|
254993
|
+
return {
|
|
254994
|
+
success: true,
|
|
254995
|
+
output: `WiFi networks on ${iface} (${networks.length} found, sorted by signal):
|
|
254996
|
+
${" Sig".padEnd(5)} ${"".padEnd(5)} ${"SSID".padEnd(25)} ${"Ch".padEnd(4)} ${"Security".padEnd(12)} Rate
|
|
254997
|
+
${"-".repeat(90)}
|
|
254998
|
+
` + lines.join("\n") + (networks.some((n2) => n2.active) ? "\n\n * = currently connected" : ""),
|
|
254999
|
+
durationMs: performance.now() - start2
|
|
255000
|
+
};
|
|
255001
|
+
} catch (err) {
|
|
255002
|
+
try {
|
|
255003
|
+
const iwScan = execSync30(`iw dev ${iface} scan 2>/dev/null | grep -E "SSID:|signal:|freq:" | head -60`, { encoding: "utf8", timeout: 15e3 });
|
|
255004
|
+
return { success: true, output: `WiFi scan (iw fallback) on ${iface}:
|
|
255005
|
+
${iwScan}`, durationMs: performance.now() - start2 };
|
|
255006
|
+
} catch {
|
|
255007
|
+
return { success: false, output: "", error: `WiFi scan failed on ${iface}: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255008
|
+
}
|
|
255009
|
+
}
|
|
255010
|
+
}
|
|
255011
|
+
// =========================================================================
|
|
255012
|
+
// List WiFi interfaces
|
|
255013
|
+
// =========================================================================
|
|
255014
|
+
listInterfaces(start2) {
|
|
255015
|
+
const interfaces = [];
|
|
255016
|
+
try {
|
|
255017
|
+
const ifaces = execSync30("ls /sys/class/net/", { encoding: "utf8", timeout: 5e3 }).trim().split("\n");
|
|
255018
|
+
for (const iface of ifaces) {
|
|
255019
|
+
try {
|
|
255020
|
+
execSync30(`test -d /sys/class/net/${iface}/wireless`, { timeout: 2e3, stdio: "pipe" });
|
|
255021
|
+
let info = ` ${iface}:`;
|
|
255022
|
+
try {
|
|
255023
|
+
const driver = execSync30(`readlink /sys/class/net/${iface}/device/driver 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim().split("/").pop();
|
|
255024
|
+
info += ` driver=${driver}`;
|
|
255025
|
+
} catch {
|
|
255026
|
+
}
|
|
255027
|
+
try {
|
|
255028
|
+
const mac = execSync30(`cat /sys/class/net/${iface}/address 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
255029
|
+
info += ` mac=${mac}`;
|
|
255030
|
+
} catch {
|
|
255031
|
+
}
|
|
255032
|
+
try {
|
|
255033
|
+
const state = execSync30(`cat /sys/class/net/${iface}/operstate 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
255034
|
+
info += ` state=${state}`;
|
|
255035
|
+
} catch {
|
|
255036
|
+
}
|
|
255037
|
+
try {
|
|
255038
|
+
const uevent = execSync30(`cat /sys/class/net/${iface}/device/uevent 2>/dev/null`, { encoding: "utf8", timeout: 2e3 });
|
|
255039
|
+
const prodMatch = uevent.match(/PRODUCT=([^\n]+)/);
|
|
255040
|
+
if (prodMatch)
|
|
255041
|
+
info += ` usb=${prodMatch[1]}`;
|
|
255042
|
+
} catch {
|
|
255043
|
+
}
|
|
255044
|
+
try {
|
|
255045
|
+
const conn = execSync30(`nmcli -t -f NAME connection show --active 2>/dev/null | head -1`, { encoding: "utf8", timeout: 3e3 }).trim();
|
|
255046
|
+
const devConn = execSync30(`nmcli -t -f DEVICE connection show --active 2>/dev/null | head -1`, { encoding: "utf8", timeout: 3e3 }).trim();
|
|
255047
|
+
if (devConn === iface && conn)
|
|
255048
|
+
info += ` connected="${conn}"`;
|
|
255049
|
+
} catch {
|
|
255050
|
+
}
|
|
255051
|
+
interfaces.push(info);
|
|
255052
|
+
} catch {
|
|
255053
|
+
}
|
|
255054
|
+
}
|
|
255055
|
+
} catch {
|
|
255056
|
+
}
|
|
255057
|
+
try {
|
|
255058
|
+
const lsusb = execSync30("lsusb 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
255059
|
+
const usbWifi = lsusb.split("\n").filter((l2) => /wireless|wifi|802\.11|rtl88|mt76|ath9k|ac600|archer/i.test(l2) && !l2.includes("Bluetooth"));
|
|
255060
|
+
for (const dev of usbWifi) {
|
|
255061
|
+
const already = interfaces.some((i2) => {
|
|
255062
|
+
const match = dev.match(/ID\s+([0-9a-f:]+)/i);
|
|
255063
|
+
return match && i2.includes(match[1].replace(":", "/"));
|
|
255064
|
+
});
|
|
255065
|
+
if (!already) {
|
|
255066
|
+
interfaces.push(` [no-interface] ${dev.trim()} (driver may not be loaded)`);
|
|
255067
|
+
}
|
|
255068
|
+
}
|
|
255069
|
+
} catch {
|
|
255070
|
+
}
|
|
255071
|
+
if (interfaces.length === 0) {
|
|
255072
|
+
return { success: true, output: "No WiFi interfaces found. Connect a WiFi adapter.", durationMs: performance.now() - start2 };
|
|
255073
|
+
}
|
|
255074
|
+
return {
|
|
255075
|
+
success: true,
|
|
255076
|
+
output: `WiFi interfaces:
|
|
255077
|
+
${interfaces.join("\n")}`,
|
|
255078
|
+
durationMs: performance.now() - start2
|
|
255079
|
+
};
|
|
255080
|
+
}
|
|
255081
|
+
// =========================================================================
|
|
255082
|
+
// Connect to a network
|
|
255083
|
+
// =========================================================================
|
|
255084
|
+
connectNetwork(args, start2) {
|
|
255085
|
+
const ssid = args["ssid"];
|
|
255086
|
+
if (!ssid) {
|
|
255087
|
+
return { success: false, output: "", error: "Missing 'ssid'. Specify the WiFi network name to connect to.", durationMs: performance.now() - start2 };
|
|
255088
|
+
}
|
|
255089
|
+
const password = args["password"];
|
|
255090
|
+
const iface = args["interface"] || this.findWifiInterface();
|
|
255091
|
+
if (!iface) {
|
|
255092
|
+
return { success: false, output: "", error: "No WiFi interface available.", durationMs: performance.now() - start2 };
|
|
255093
|
+
}
|
|
255094
|
+
const cmd = password ? `nmcli device wifi connect "${ssid}" password "${password}" ifname ${iface}` : `nmcli device wifi connect "${ssid}" ifname ${iface}`;
|
|
255095
|
+
try {
|
|
255096
|
+
execSync30(cmd, { encoding: "utf8", timeout: 3e4, stdio: "pipe" });
|
|
255097
|
+
} catch (err) {
|
|
255098
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
255099
|
+
if (msg.includes("No network with SSID")) {
|
|
255100
|
+
return { success: false, output: "", error: `Network "${ssid}" not found. Run wifi_control action='scan' to see available networks.`, durationMs: performance.now() - start2 };
|
|
255101
|
+
}
|
|
255102
|
+
if (msg.includes("Secrets were required")) {
|
|
255103
|
+
return { success: false, output: "", error: `Password required for "${ssid}". Provide the password parameter.`, durationMs: performance.now() - start2 };
|
|
255104
|
+
}
|
|
255105
|
+
return { success: false, output: "", error: `Failed to connect to "${ssid}": ${msg.slice(0, 300)}`, durationMs: performance.now() - start2 };
|
|
255106
|
+
}
|
|
255107
|
+
try {
|
|
255108
|
+
execSync30("sleep 2", { timeout: 5e3 });
|
|
255109
|
+
const ip = execSync30(`ip addr show ${iface} | grep "inet " | awk '{print $2}'`, { encoding: "utf8", timeout: 5e3 }).trim();
|
|
255110
|
+
return { success: true, output: `Connected to "${ssid}" on ${iface}.
|
|
255111
|
+
IP address: ${ip}`, durationMs: performance.now() - start2 };
|
|
255112
|
+
} catch {
|
|
255113
|
+
return { success: true, output: `Connected to "${ssid}" on ${iface}. (IP assignment pending)`, durationMs: performance.now() - start2 };
|
|
255114
|
+
}
|
|
255115
|
+
}
|
|
255116
|
+
// =========================================================================
|
|
255117
|
+
// Disconnect
|
|
255118
|
+
// =========================================================================
|
|
255119
|
+
disconnectNetwork(args, start2) {
|
|
255120
|
+
const iface = args["interface"] || this.findWifiInterface();
|
|
255121
|
+
if (!iface) {
|
|
255122
|
+
return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
|
|
255123
|
+
}
|
|
255124
|
+
try {
|
|
255125
|
+
execSync30(`nmcli device disconnect ${iface}`, { timeout: 1e4, stdio: "pipe" });
|
|
255126
|
+
return { success: true, output: `Disconnected ${iface} from WiFi.`, durationMs: performance.now() - start2 };
|
|
255127
|
+
} catch (err) {
|
|
255128
|
+
return { success: false, output: "", error: `Disconnect failed: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255129
|
+
}
|
|
255130
|
+
}
|
|
255131
|
+
// =========================================================================
|
|
255132
|
+
// Connection status
|
|
255133
|
+
// =========================================================================
|
|
255134
|
+
connectionStatus(args, start2) {
|
|
255135
|
+
const iface = args["interface"] || this.findWifiInterface();
|
|
255136
|
+
if (!iface) {
|
|
255137
|
+
return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
|
|
255138
|
+
}
|
|
255139
|
+
const info = [`WiFi status for ${iface}:`];
|
|
255140
|
+
try {
|
|
255141
|
+
const state = execSync30(`nmcli -t -f GENERAL.STATE device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
|
|
255142
|
+
const stateMatch = state.match(/GENERAL\.STATE:(.+)/);
|
|
255143
|
+
info.push(` State: ${stateMatch ? stateMatch[1].trim() : "unknown"}`);
|
|
255144
|
+
} catch {
|
|
255145
|
+
}
|
|
255146
|
+
try {
|
|
255147
|
+
const conn = execSync30(`nmcli -t -f GENERAL.CONNECTION device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
|
|
255148
|
+
const connMatch = conn.match(/GENERAL\.CONNECTION:(.+)/);
|
|
255149
|
+
info.push(` Network: ${connMatch ? connMatch[1].trim() || "(not connected)" : "(not connected)"}`);
|
|
255150
|
+
} catch {
|
|
255151
|
+
}
|
|
255152
|
+
try {
|
|
255153
|
+
const ip = execSync30(`ip addr show ${iface} 2>/dev/null | grep "inet " | awk '{print $2}'`, { encoding: "utf8", timeout: 5e3 }).trim();
|
|
255154
|
+
info.push(` IP: ${ip || "(no IP)"}`);
|
|
255155
|
+
} catch {
|
|
255156
|
+
}
|
|
255157
|
+
try {
|
|
255158
|
+
const iwconfig = execSync30(`iwconfig ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
|
|
255159
|
+
const signalMatch = iwconfig.match(/Signal level[=:](-?\d+)\s*dBm/);
|
|
255160
|
+
const linkMatch = iwconfig.match(/Link Quality[=:](\d+\/\d+)/);
|
|
255161
|
+
const bitRateMatch = iwconfig.match(/Bit Rate[=:]([^\s]+)/);
|
|
255162
|
+
const freqMatch = iwconfig.match(/Frequency[=:]([^\s]+\s*GHz)/);
|
|
255163
|
+
if (signalMatch)
|
|
255164
|
+
info.push(` Signal: ${signalMatch[1]} dBm`);
|
|
255165
|
+
if (linkMatch)
|
|
255166
|
+
info.push(` Link Quality: ${linkMatch[1]}`);
|
|
255167
|
+
if (bitRateMatch)
|
|
255168
|
+
info.push(` Bit Rate: ${bitRateMatch[1]}`);
|
|
255169
|
+
if (freqMatch)
|
|
255170
|
+
info.push(` Frequency: ${freqMatch[1]}`);
|
|
255171
|
+
} catch {
|
|
255172
|
+
}
|
|
255173
|
+
try {
|
|
255174
|
+
const gw = execSync30(`ip route show dev ${iface} 2>/dev/null | grep default | awk '{print $3}'`, { encoding: "utf8", timeout: 5e3 }).trim();
|
|
255175
|
+
if (gw)
|
|
255176
|
+
info.push(` Gateway: ${gw}`);
|
|
255177
|
+
} catch {
|
|
255178
|
+
}
|
|
255179
|
+
try {
|
|
255180
|
+
const dns2 = execSync30(`nmcli -t -f IP4.DNS device show ${iface} 2>/dev/null`, { encoding: "utf8", timeout: 5e3 });
|
|
255181
|
+
const dnsServers = dns2.match(/IP4\.DNS\[?\d*\]?:(.+)/g);
|
|
255182
|
+
if (dnsServers)
|
|
255183
|
+
info.push(` DNS: ${dnsServers.map((d2) => d2.split(":")[1]).join(", ")}`);
|
|
255184
|
+
} catch {
|
|
255185
|
+
}
|
|
255186
|
+
return { success: true, output: info.join("\n"), durationMs: performance.now() - start2 };
|
|
255187
|
+
}
|
|
255188
|
+
// =========================================================================
|
|
255189
|
+
// Monitor mode
|
|
255190
|
+
// =========================================================================
|
|
255191
|
+
monitorMode(args, start2) {
|
|
255192
|
+
const iface = args["interface"] || this.findWifiInterface();
|
|
255193
|
+
if (!iface) {
|
|
255194
|
+
return { success: false, output: "", error: "No WiFi interface found.", durationMs: performance.now() - start2 };
|
|
255195
|
+
}
|
|
255196
|
+
const enable = args["enable"] !== false;
|
|
255197
|
+
if (enable) {
|
|
255198
|
+
try {
|
|
255199
|
+
execSync30(`ip link set ${iface} down && iw dev ${iface} set type monitor && ip link set ${iface} up`, { timeout: 1e4, stdio: "pipe" });
|
|
255200
|
+
return { success: true, output: `Monitor mode ENABLED on ${iface}. Use 'monitor enable=false' to restore managed mode.`, durationMs: performance.now() - start2 };
|
|
255201
|
+
} catch (err) {
|
|
255202
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
255203
|
+
if (msg.includes("Operation not permitted")) {
|
|
255204
|
+
return { success: false, output: "", error: `Monitor mode requires root. Run with sudo or use shell: sudo ip link set ${iface} down && sudo iw dev ${iface} set type monitor && sudo ip link set ${iface} up`, durationMs: performance.now() - start2 };
|
|
255205
|
+
}
|
|
255206
|
+
return { success: false, output: "", error: `Failed to enable monitor mode: ${msg.slice(0, 300)}`, durationMs: performance.now() - start2 };
|
|
255207
|
+
}
|
|
255208
|
+
} else {
|
|
255209
|
+
try {
|
|
255210
|
+
execSync30(`ip link set ${iface} down && iw dev ${iface} set type managed && ip link set ${iface} up`, { timeout: 1e4, stdio: "pipe" });
|
|
255211
|
+
return { success: true, output: `Monitor mode DISABLED on ${iface}. Restored to managed mode.`, durationMs: performance.now() - start2 };
|
|
255212
|
+
} catch (err) {
|
|
255213
|
+
return { success: false, output: "", error: `Failed to disable monitor mode: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255214
|
+
}
|
|
255215
|
+
}
|
|
255216
|
+
}
|
|
255217
|
+
// =========================================================================
|
|
255218
|
+
// Helpers
|
|
255219
|
+
// =========================================================================
|
|
255220
|
+
findWifiInterface() {
|
|
255221
|
+
try {
|
|
255222
|
+
const ifaces = execSync30("ls /sys/class/net/", { encoding: "utf8", timeout: 3e3 }).trim().split("\n");
|
|
255223
|
+
for (const iface of ifaces) {
|
|
255224
|
+
try {
|
|
255225
|
+
execSync30(`test -d /sys/class/net/${iface}/wireless`, { timeout: 2e3, stdio: "pipe" });
|
|
255226
|
+
return iface;
|
|
255227
|
+
} catch {
|
|
255228
|
+
}
|
|
255229
|
+
}
|
|
255230
|
+
} catch {
|
|
255231
|
+
}
|
|
255232
|
+
return null;
|
|
255233
|
+
}
|
|
255234
|
+
};
|
|
255235
|
+
}
|
|
255236
|
+
});
|
|
255237
|
+
|
|
255238
|
+
// packages/execution/dist/tools/bluetooth-scan.js
|
|
255239
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
255240
|
+
var BluetoothScanTool;
|
|
255241
|
+
var init_bluetooth_scan = __esm({
|
|
255242
|
+
"packages/execution/dist/tools/bluetooth-scan.js"() {
|
|
255243
|
+
"use strict";
|
|
255244
|
+
BluetoothScanTool = class {
|
|
255245
|
+
name = "bluetooth_scan";
|
|
255246
|
+
description = "Discover nearby Bluetooth devices. Actions: 'scan' to find Classic and BLE devices, 'interfaces' to list Bluetooth adapters, 'info' to get device details. Use this to discover Bluetooth peripherals, check for nearby devices, or identify what Bluetooth hardware is connected to this system.";
|
|
255247
|
+
parameters = {
|
|
255248
|
+
type: "object",
|
|
255249
|
+
properties: {
|
|
255250
|
+
action: {
|
|
255251
|
+
type: "string",
|
|
255252
|
+
enum: ["scan", "interfaces", "info"],
|
|
255253
|
+
description: "Action: scan for devices, list adapters, or get device info"
|
|
255254
|
+
},
|
|
255255
|
+
device: {
|
|
255256
|
+
type: "string",
|
|
255257
|
+
description: "HCI device (e.g. hci0). Default: first available."
|
|
255258
|
+
},
|
|
255259
|
+
address: {
|
|
255260
|
+
type: "string",
|
|
255261
|
+
description: "Bluetooth MAC address for 'info' action"
|
|
255262
|
+
},
|
|
255263
|
+
timeout: {
|
|
255264
|
+
type: "number",
|
|
255265
|
+
description: "Scan timeout in seconds (default: 8)"
|
|
255266
|
+
}
|
|
255267
|
+
},
|
|
255268
|
+
required: ["action"]
|
|
255269
|
+
};
|
|
255270
|
+
async execute(args) {
|
|
255271
|
+
const action = args["action"];
|
|
255272
|
+
const start2 = performance.now();
|
|
255273
|
+
try {
|
|
255274
|
+
switch (action) {
|
|
255275
|
+
case "scan":
|
|
255276
|
+
return this.scanDevices(args, start2);
|
|
255277
|
+
case "interfaces":
|
|
255278
|
+
return this.listInterfaces(start2);
|
|
255279
|
+
case "info":
|
|
255280
|
+
return this.deviceInfo(args, start2);
|
|
255281
|
+
default:
|
|
255282
|
+
return { success: false, output: "", error: `Unknown action: ${action}`, durationMs: performance.now() - start2 };
|
|
255283
|
+
}
|
|
255284
|
+
} catch (err) {
|
|
255285
|
+
return { success: false, output: "", error: `bluetooth_scan error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
255286
|
+
}
|
|
255287
|
+
}
|
|
255288
|
+
scanDevices(args, start2) {
|
|
255289
|
+
const hci = args["device"] || "hci0";
|
|
255290
|
+
const timeout2 = args["timeout"] || 8;
|
|
255291
|
+
const devices = [];
|
|
255292
|
+
try {
|
|
255293
|
+
const classic = execSync31(`hcitool -i ${hci} scan --length=${timeout2} 2>/dev/null`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
|
|
255294
|
+
for (const line of classic.split("\n")) {
|
|
255295
|
+
const match = line.trim().match(/^([0-9A-F:]{17})\s+(.+)$/i);
|
|
255296
|
+
if (match)
|
|
255297
|
+
devices.push({ mac: match[1], name: match[2].trim(), type: "classic" });
|
|
255298
|
+
}
|
|
255299
|
+
} catch {
|
|
255300
|
+
}
|
|
255301
|
+
try {
|
|
255302
|
+
const ble = execSync31(`timeout ${Math.min(timeout2, 5)} hcitool -i ${hci} lescan --duplicates 2>/dev/null || true`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
|
|
255303
|
+
const seen = /* @__PURE__ */ new Set();
|
|
255304
|
+
for (const line of ble.split("\n")) {
|
|
255305
|
+
const match = line.trim().match(/^([0-9A-F:]{17})\s+(.*)$/i);
|
|
255306
|
+
if (match && !seen.has(match[1])) {
|
|
255307
|
+
seen.add(match[1]);
|
|
255308
|
+
devices.push({ mac: match[1], name: match[2].trim() || "(unnamed)", type: "ble" });
|
|
255309
|
+
}
|
|
255310
|
+
}
|
|
255311
|
+
} catch {
|
|
255312
|
+
}
|
|
255313
|
+
if (devices.length === 0) {
|
|
255314
|
+
try {
|
|
255315
|
+
const btctl = execSync31(`echo -e "scan on\\n" | timeout ${timeout2} bluetoothctl 2>/dev/null | grep "Device "`, { encoding: "utf8", timeout: (timeout2 + 5) * 1e3 });
|
|
255316
|
+
for (const line of btctl.split("\n")) {
|
|
255317
|
+
const match = line.match(/Device\s+([0-9A-F:]{17})\s+(.+)/i);
|
|
255318
|
+
if (match)
|
|
255319
|
+
devices.push({ mac: match[1], name: match[2].trim(), type: "unknown" });
|
|
255320
|
+
}
|
|
255321
|
+
} catch {
|
|
255322
|
+
}
|
|
255323
|
+
}
|
|
255324
|
+
if (devices.length === 0) {
|
|
255325
|
+
return { success: true, output: `No Bluetooth devices found within ${timeout2}s scan on ${hci}.
|
|
255326
|
+
Tip: Make sure target devices are in discoverable/pairing mode.`, durationMs: performance.now() - start2 };
|
|
255327
|
+
}
|
|
255328
|
+
const lines = devices.map((d2) => ` ${d2.mac} ${d2.name.padEnd(30)} [${d2.type}]`);
|
|
255329
|
+
return {
|
|
255330
|
+
success: true,
|
|
255331
|
+
output: `Found ${devices.length} Bluetooth device(s) on ${hci}:
|
|
255332
|
+
${lines.join("\n")}`,
|
|
255333
|
+
durationMs: performance.now() - start2
|
|
255334
|
+
};
|
|
255335
|
+
}
|
|
255336
|
+
listInterfaces(start2) {
|
|
255337
|
+
const adapters = [];
|
|
255338
|
+
try {
|
|
255339
|
+
const hciconfig = execSync31("hciconfig -a 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
255340
|
+
const blocks = hciconfig.split(/^(hci\d+)/m);
|
|
255341
|
+
for (let i2 = 1; i2 < blocks.length; i2 += 2) {
|
|
255342
|
+
const name10 = blocks[i2];
|
|
255343
|
+
const info = blocks[i2 + 1] || "";
|
|
255344
|
+
const bdAddr = info.match(/BD Address:\s*([0-9A-F:]{17})/i)?.[1] || "unknown";
|
|
255345
|
+
const state = info.includes("UP RUNNING") ? "up" : info.includes("DOWN") ? "down" : "unknown";
|
|
255346
|
+
const type = info.match(/Type:\s*(\w+)/)?.[1] || "";
|
|
255347
|
+
adapters.push(` ${name10}: ${bdAddr} state=${state} ${type}`);
|
|
255348
|
+
}
|
|
255349
|
+
} catch {
|
|
255350
|
+
try {
|
|
255351
|
+
const devs = execSync31("ls /sys/class/bluetooth/ 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim().split("\n").filter(Boolean);
|
|
255352
|
+
for (const dev of devs) {
|
|
255353
|
+
const addr = execSync31(`cat /sys/class/bluetooth/${dev}/address 2>/dev/null`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
255354
|
+
adapters.push(` ${dev}: ${addr}`);
|
|
255355
|
+
}
|
|
255356
|
+
} catch {
|
|
255357
|
+
}
|
|
255358
|
+
}
|
|
255359
|
+
if (adapters.length === 0) {
|
|
255360
|
+
return { success: true, output: "No Bluetooth adapters found.", durationMs: performance.now() - start2 };
|
|
255361
|
+
}
|
|
255362
|
+
return { success: true, output: `Bluetooth adapters:
|
|
255363
|
+
${adapters.join("\n")}`, durationMs: performance.now() - start2 };
|
|
255364
|
+
}
|
|
255365
|
+
deviceInfo(args, start2) {
|
|
255366
|
+
const address = args["address"];
|
|
255367
|
+
if (!address) {
|
|
255368
|
+
return { success: false, output: "", error: "Missing 'address'. Provide a Bluetooth MAC address.", durationMs: performance.now() - start2 };
|
|
255369
|
+
}
|
|
255370
|
+
try {
|
|
255371
|
+
const info = execSync31(`hcitool info ${address} 2>/dev/null`, { encoding: "utf8", timeout: 1e4 });
|
|
255372
|
+
return { success: true, output: `Bluetooth device ${address}:
|
|
255373
|
+
${info}`, durationMs: performance.now() - start2 };
|
|
255374
|
+
} catch {
|
|
255375
|
+
return { success: true, output: `Could not query ${address}. Device may be out of range or not in discoverable mode.`, durationMs: performance.now() - start2 };
|
|
255376
|
+
}
|
|
255377
|
+
}
|
|
255378
|
+
};
|
|
255379
|
+
}
|
|
255380
|
+
});
|
|
255381
|
+
|
|
254887
255382
|
// packages/execution/dist/tools/full-sub-agent.js
|
|
254888
255383
|
import { spawn as spawn13, ChildProcess } from "node:child_process";
|
|
254889
255384
|
import { randomBytes as randomBytes13 } from "node:crypto";
|
|
@@ -255328,7 +255823,7 @@ var init_agent_tool = __esm({
|
|
|
255328
255823
|
});
|
|
255329
255824
|
|
|
255330
255825
|
// packages/execution/dist/tools/worktree.js
|
|
255331
|
-
import { execSync as
|
|
255826
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
255332
255827
|
import { existsSync as existsSync31, mkdirSync as mkdirSync12, rmSync } from "node:fs";
|
|
255333
255828
|
import { join as join46, resolve as resolve30 } from "node:path";
|
|
255334
255829
|
function validateSlug(slug) {
|
|
@@ -255347,7 +255842,7 @@ function flattenSlug(slug) {
|
|
|
255347
255842
|
}
|
|
255348
255843
|
function isGitRepo(cwd4) {
|
|
255349
255844
|
try {
|
|
255350
|
-
|
|
255845
|
+
execSync32("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
|
|
255351
255846
|
return true;
|
|
255352
255847
|
} catch {
|
|
255353
255848
|
return false;
|
|
@@ -255355,14 +255850,14 @@ function isGitRepo(cwd4) {
|
|
|
255355
255850
|
}
|
|
255356
255851
|
function getCurrentBranch(cwd4) {
|
|
255357
255852
|
try {
|
|
255358
|
-
return
|
|
255853
|
+
return execSync32("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
255359
255854
|
} catch {
|
|
255360
255855
|
return void 0;
|
|
255361
255856
|
}
|
|
255362
255857
|
}
|
|
255363
255858
|
function getCurrentCommit(cwd4) {
|
|
255364
255859
|
try {
|
|
255365
|
-
return
|
|
255860
|
+
return execSync32("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
255366
255861
|
} catch {
|
|
255367
255862
|
return void 0;
|
|
255368
255863
|
}
|
|
@@ -255393,13 +255888,13 @@ function createWorktree(repoRoot, slug) {
|
|
|
255393
255888
|
}
|
|
255394
255889
|
mkdirSync12(worktreeBase, { recursive: true });
|
|
255395
255890
|
try {
|
|
255396
|
-
|
|
255891
|
+
execSync32(`git worktree add "${worktreePath}" -b "${branchName}"`, {
|
|
255397
255892
|
cwd: repoRoot,
|
|
255398
255893
|
stdio: "pipe"
|
|
255399
255894
|
});
|
|
255400
255895
|
} catch (err) {
|
|
255401
255896
|
try {
|
|
255402
|
-
|
|
255897
|
+
execSync32(`git worktree add "${worktreePath}" "${branchName}"`, {
|
|
255403
255898
|
cwd: repoRoot,
|
|
255404
255899
|
stdio: "pipe"
|
|
255405
255900
|
});
|
|
@@ -255421,7 +255916,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
255421
255916
|
}
|
|
255422
255917
|
function worktreeHasChanges(worktreePath) {
|
|
255423
255918
|
try {
|
|
255424
|
-
const status =
|
|
255919
|
+
const status = execSync32("git status --porcelain", {
|
|
255425
255920
|
cwd: worktreePath,
|
|
255426
255921
|
stdio: "pipe"
|
|
255427
255922
|
}).toString().trim();
|
|
@@ -255442,20 +255937,20 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
255442
255937
|
return "Worktree has uncommitted changes. Use force=true to discard, or commit/stash first.";
|
|
255443
255938
|
}
|
|
255444
255939
|
try {
|
|
255445
|
-
|
|
255940
|
+
execSync32(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
|
|
255446
255941
|
cwd: repoRoot,
|
|
255447
255942
|
stdio: "pipe"
|
|
255448
255943
|
});
|
|
255449
255944
|
} catch (err) {
|
|
255450
255945
|
try {
|
|
255451
255946
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
255452
|
-
|
|
255947
|
+
execSync32("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
|
|
255453
255948
|
} catch {
|
|
255454
255949
|
return `Failed to remove worktree: ${err}`;
|
|
255455
255950
|
}
|
|
255456
255951
|
}
|
|
255457
255952
|
try {
|
|
255458
|
-
|
|
255953
|
+
execSync32(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
|
|
255459
255954
|
} catch {
|
|
255460
255955
|
}
|
|
255461
255956
|
_sessions.delete(slug);
|
|
@@ -256732,7 +257227,7 @@ var init_notebook_edit = __esm({
|
|
|
256732
257227
|
});
|
|
256733
257228
|
|
|
256734
257229
|
// packages/execution/dist/tools/environment-snapshot.js
|
|
256735
|
-
import { execSync as
|
|
257230
|
+
import { execSync as execSync33 } from "node:child_process";
|
|
256736
257231
|
import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
|
|
256737
257232
|
import { statfsSync } from "node:fs";
|
|
256738
257233
|
function collectSnapshot(workingDir) {
|
|
@@ -256750,7 +257245,7 @@ function collectSnapshot(workingDir) {
|
|
|
256750
257245
|
}
|
|
256751
257246
|
let gpu = void 0;
|
|
256752
257247
|
try {
|
|
256753
|
-
const nvOut =
|
|
257248
|
+
const nvOut = execSync33("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((s2) => s2.trim());
|
|
256754
257249
|
if (nvOut.length >= 3) {
|
|
256755
257250
|
gpu = {
|
|
256756
257251
|
name: nvOut[0],
|
|
@@ -256765,12 +257260,12 @@ function collectSnapshot(workingDir) {
|
|
|
256765
257260
|
let battery = void 0;
|
|
256766
257261
|
try {
|
|
256767
257262
|
if (platform() === "linux") {
|
|
256768
|
-
const cap =
|
|
256769
|
-
const status =
|
|
257263
|
+
const cap = execSync33("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
257264
|
+
const status = execSync33("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
256770
257265
|
if (cap)
|
|
256771
257266
|
battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
|
|
256772
257267
|
} else if (platform() === "darwin") {
|
|
256773
|
-
const pmOut =
|
|
257268
|
+
const pmOut = execSync33("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
|
|
256774
257269
|
const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
|
|
256775
257270
|
if (match)
|
|
256776
257271
|
battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
|
|
@@ -256791,8 +257286,8 @@ function collectSnapshot(workingDir) {
|
|
|
256791
257286
|
}
|
|
256792
257287
|
let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
|
|
256793
257288
|
try {
|
|
256794
|
-
const psLines =
|
|
256795
|
-
const total = parseInt(
|
|
257289
|
+
const psLines = execSync33("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");
|
|
257290
|
+
const total = parseInt(execSync33("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
|
|
256796
257291
|
let nodeCount = 0;
|
|
256797
257292
|
let oaSpawned = 0;
|
|
256798
257293
|
const topCpu = [];
|
|
@@ -256873,7 +257368,7 @@ var init_environment_snapshot = __esm({
|
|
|
256873
257368
|
});
|
|
256874
257369
|
|
|
256875
257370
|
// packages/execution/dist/tools/video-understand.js
|
|
256876
|
-
import { execSync as
|
|
257371
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
256877
257372
|
import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync26, readdirSync as readdirSync8, unlinkSync as unlinkSync7 } from "node:fs";
|
|
256878
257373
|
import { join as join49, basename as basename11 } from "node:path";
|
|
256879
257374
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -256882,11 +257377,11 @@ function isYouTubeUrl2(url) {
|
|
|
256882
257377
|
}
|
|
256883
257378
|
function ensureYtDlp2() {
|
|
256884
257379
|
try {
|
|
256885
|
-
|
|
257380
|
+
execSync34("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
256886
257381
|
return true;
|
|
256887
257382
|
} catch {
|
|
256888
257383
|
try {
|
|
256889
|
-
|
|
257384
|
+
execSync34("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
256890
257385
|
return true;
|
|
256891
257386
|
} catch {
|
|
256892
257387
|
return false;
|
|
@@ -256895,7 +257390,7 @@ function ensureYtDlp2() {
|
|
|
256895
257390
|
}
|
|
256896
257391
|
function ensureFfmpeg() {
|
|
256897
257392
|
try {
|
|
256898
|
-
|
|
257393
|
+
execSync34("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
256899
257394
|
return true;
|
|
256900
257395
|
} catch {
|
|
256901
257396
|
return false;
|
|
@@ -256975,32 +257470,32 @@ var init_video_understand = __esm({
|
|
|
256975
257470
|
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start2 };
|
|
256976
257471
|
}
|
|
256977
257472
|
try {
|
|
256978
|
-
|
|
257473
|
+
execSync34(`yt-dlp -f "worst[ext=mp4]" -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256979
257474
|
} catch {
|
|
256980
|
-
|
|
257475
|
+
execSync34(`yt-dlp -f worst -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256981
257476
|
}
|
|
256982
|
-
|
|
257477
|
+
execSync34(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join49(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256983
257478
|
try {
|
|
256984
|
-
title =
|
|
257479
|
+
title = execSync34(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
256985
257480
|
} catch {
|
|
256986
257481
|
}
|
|
256987
257482
|
} else {
|
|
256988
|
-
|
|
256989
|
-
|
|
257483
|
+
execSync34(`curl -sL -o "${join49(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
257484
|
+
execSync34(`ffmpeg -i "${join49(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join49(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
256990
257485
|
}
|
|
256991
257486
|
videoPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("video")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("video"))) : join49(tmpDir, "video.mp4");
|
|
256992
257487
|
audioPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("audio")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("audio"))) : join49(tmpDir, "audio.mp3");
|
|
256993
257488
|
} else {
|
|
256994
257489
|
videoPath = localPath;
|
|
256995
257490
|
audioPath = join49(tmpDir, "audio.mp3");
|
|
256996
|
-
|
|
257491
|
+
execSync34(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
256997
257492
|
}
|
|
256998
257493
|
let segments = [];
|
|
256999
257494
|
let language = "en";
|
|
257000
257495
|
let duration = 0;
|
|
257001
257496
|
try {
|
|
257002
257497
|
const jsonOut = join49(tmpDir, "transcript.json");
|
|
257003
|
-
|
|
257498
|
+
execSync34(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
257004
257499
|
const jsonFile = readdirSync8(tmpDir).find((f2) => f2.endsWith(".json") && f2 !== "result.json");
|
|
257005
257500
|
if (jsonFile) {
|
|
257006
257501
|
const data = JSON.parse(readFileSync26(join49(tmpDir, jsonFile), "utf-8"));
|
|
@@ -257023,7 +257518,7 @@ var init_video_understand = __esm({
|
|
|
257023
257518
|
const fps = 25;
|
|
257024
257519
|
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
257025
257520
|
try {
|
|
257026
|
-
|
|
257521
|
+
execSync34(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join49(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
|
|
257027
257522
|
} catch {
|
|
257028
257523
|
}
|
|
257029
257524
|
const frameFiles = readdirSync8(framesDir).filter((f2) => f2.endsWith(".jpg")).sort();
|
|
@@ -257156,7 +257651,7 @@ Topic: ${segments.slice(0, 5).map((s2) => s2.text).join(" ").slice(0, 300)}`,
|
|
|
257156
257651
|
}
|
|
257157
257652
|
}
|
|
257158
257653
|
try {
|
|
257159
|
-
|
|
257654
|
+
execSync34(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
257160
257655
|
} catch {
|
|
257161
257656
|
}
|
|
257162
257657
|
return {
|
|
@@ -258050,6 +258545,7 @@ __export(dist_exports, {
|
|
|
258050
258545
|
BackgroundRunTool: () => BackgroundRunTool,
|
|
258051
258546
|
BackgroundTaskManager: () => BackgroundTaskManager,
|
|
258052
258547
|
BatchEditTool: () => BatchEditTool,
|
|
258548
|
+
BluetoothScanTool: () => BluetoothScanTool,
|
|
258053
258549
|
BrowserActionTool: () => BrowserActionTool,
|
|
258054
258550
|
CameraCaptureTool: () => CameraCaptureTool,
|
|
258055
258551
|
CodeSandboxTool: () => CodeSandboxTool,
|
|
@@ -258125,6 +258621,7 @@ __export(dist_exports, {
|
|
|
258125
258621
|
WebCrawlTool: () => WebCrawlTool,
|
|
258126
258622
|
WebFetchTool: () => WebFetchTool,
|
|
258127
258623
|
WebSearchTool: () => WebSearchTool,
|
|
258624
|
+
WifiControlTool: () => WifiControlTool,
|
|
258128
258625
|
WorkingNotesTool: () => WorkingNotesTool,
|
|
258129
258626
|
YouTubeDownloadTool: () => YouTubeDownloadTool,
|
|
258130
258627
|
addProjectConstraint: () => addProjectConstraint,
|
|
@@ -258286,6 +258783,8 @@ var init_dist4 = __esm({
|
|
|
258286
258783
|
init_camera_capture();
|
|
258287
258784
|
init_audio_capture();
|
|
258288
258785
|
init_audio_playback();
|
|
258786
|
+
init_wifi_control();
|
|
258787
|
+
init_bluetooth_scan();
|
|
258289
258788
|
init_system_auth();
|
|
258290
258789
|
init_full_sub_agent();
|
|
258291
258790
|
init_agent_tool();
|
|
@@ -261190,12 +261689,12 @@ var init_tool_batching = __esm({
|
|
|
261190
261689
|
});
|
|
261191
261690
|
|
|
261192
261691
|
// packages/orchestrator/dist/hooks.js
|
|
261193
|
-
import { execSync as
|
|
261692
|
+
import { execSync as execSync35 } from "node:child_process";
|
|
261194
261693
|
function executeHook(hook, env2 = {}) {
|
|
261195
261694
|
const start2 = performance.now();
|
|
261196
261695
|
const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
|
|
261197
261696
|
try {
|
|
261198
|
-
const output =
|
|
261697
|
+
const output = execSync35(hook.command, {
|
|
261199
261698
|
timeout: timeout2,
|
|
261200
261699
|
env: { ...process.env, ...env2 },
|
|
261201
261700
|
encoding: "utf8",
|
|
@@ -265419,7 +265918,7 @@ ${result}`
|
|
|
265419
265918
|
const buffer2 = Buffer.from(rawBase64, "base64");
|
|
265420
265919
|
let resizedBase64 = null;
|
|
265421
265920
|
try {
|
|
265422
|
-
const { execSync:
|
|
265921
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
265423
265922
|
const { writeFileSync: writeFileSync38, readFileSync: readFileSync56, unlinkSync: unlinkSync17 } = await import("node:fs");
|
|
265424
265923
|
const { join: join91 } = await import("node:path");
|
|
265425
265924
|
const { tmpdir: tmpdir14 } = await import("node:os");
|
|
@@ -265429,7 +265928,7 @@ ${result}`
|
|
|
265429
265928
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
265430
265929
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
265431
265930
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
265432
|
-
|
|
265931
|
+
execSync48(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
265433
265932
|
const resizedBuf = readFileSync56(tmpOut);
|
|
265434
265933
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
265435
265934
|
try {
|
|
@@ -265483,8 +265982,8 @@ ${result}`
|
|
|
265483
265982
|
if (!res.ok && model === "moondream" && res.status === 404) {
|
|
265484
265983
|
this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
265485
265984
|
try {
|
|
265486
|
-
const { execSync:
|
|
265487
|
-
|
|
265985
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
265986
|
+
execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
265488
265987
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
265489
265988
|
method: "POST",
|
|
265490
265989
|
headers: { "Content-Type": "application/json" },
|
|
@@ -267848,7 +268347,7 @@ __export(listen_exports, {
|
|
|
267848
268347
|
isVideoPath: () => isVideoPath,
|
|
267849
268348
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
267850
268349
|
});
|
|
267851
|
-
import { spawn as spawn17, execSync as
|
|
268350
|
+
import { spawn as spawn17, execSync as execSync36 } from "node:child_process";
|
|
267852
268351
|
import { existsSync as existsSync41, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readdirSync as readdirSync9 } from "node:fs";
|
|
267853
268352
|
import { join as join57, dirname as dirname16 } from "node:path";
|
|
267854
268353
|
import { homedir as homedir15 } from "node:os";
|
|
@@ -267870,7 +268369,7 @@ function findMicCaptureCommand() {
|
|
|
267870
268369
|
const platform6 = process.platform;
|
|
267871
268370
|
if (platform6 === "linux") {
|
|
267872
268371
|
try {
|
|
267873
|
-
|
|
268372
|
+
execSync36("which arecord", { stdio: "pipe" });
|
|
267874
268373
|
return {
|
|
267875
268374
|
cmd: "arecord",
|
|
267876
268375
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -267880,7 +268379,7 @@ function findMicCaptureCommand() {
|
|
|
267880
268379
|
}
|
|
267881
268380
|
if (platform6 === "darwin") {
|
|
267882
268381
|
try {
|
|
267883
|
-
|
|
268382
|
+
execSync36("which sox", { stdio: "pipe" });
|
|
267884
268383
|
return {
|
|
267885
268384
|
cmd: "sox",
|
|
267886
268385
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -267889,7 +268388,7 @@ function findMicCaptureCommand() {
|
|
|
267889
268388
|
}
|
|
267890
268389
|
}
|
|
267891
268390
|
try {
|
|
267892
|
-
|
|
268391
|
+
execSync36("which ffmpeg", { stdio: "pipe" });
|
|
267893
268392
|
if (platform6 === "linux") {
|
|
267894
268393
|
return {
|
|
267895
268394
|
cmd: "ffmpeg",
|
|
@@ -267947,7 +268446,7 @@ function findLiveWhisperScript() {
|
|
|
267947
268446
|
if (existsSync41(p2)) return p2;
|
|
267948
268447
|
}
|
|
267949
268448
|
try {
|
|
267950
|
-
const globalRoot =
|
|
268449
|
+
const globalRoot = execSync36("npm root -g", {
|
|
267951
268450
|
encoding: "utf-8",
|
|
267952
268451
|
timeout: 5e3,
|
|
267953
268452
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -267977,7 +268476,7 @@ function ensureTranscribeCliBackground() {
|
|
|
267977
268476
|
if (_bgInstallPromise) return;
|
|
267978
268477
|
_bgInstallPromise = (async () => {
|
|
267979
268478
|
try {
|
|
267980
|
-
const globalRoot =
|
|
268479
|
+
const globalRoot = execSync36("npm root -g", {
|
|
267981
268480
|
encoding: "utf-8",
|
|
267982
268481
|
timeout: 5e3,
|
|
267983
268482
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268179,7 +268678,7 @@ var init_listen = __esm({
|
|
|
268179
268678
|
}
|
|
268180
268679
|
if (!this.transcribeCliAvailable) {
|
|
268181
268680
|
try {
|
|
268182
|
-
|
|
268681
|
+
execSync36("which transcribe-cli", { stdio: "pipe" });
|
|
268183
268682
|
this.transcribeCliAvailable = true;
|
|
268184
268683
|
} catch {
|
|
268185
268684
|
this.transcribeCliAvailable = false;
|
|
@@ -268196,7 +268695,7 @@ var init_listen = __esm({
|
|
|
268196
268695
|
} catch {
|
|
268197
268696
|
}
|
|
268198
268697
|
try {
|
|
268199
|
-
const globalRoot =
|
|
268698
|
+
const globalRoot = execSync36("npm root -g", {
|
|
268200
268699
|
encoding: "utf-8",
|
|
268201
268700
|
timeout: 5e3,
|
|
268202
268701
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268245,7 +268744,7 @@ var init_listen = __esm({
|
|
|
268245
268744
|
}
|
|
268246
268745
|
if (!tc) {
|
|
268247
268746
|
try {
|
|
268248
|
-
|
|
268747
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268249
268748
|
this.transcribeCliAvailable = null;
|
|
268250
268749
|
tc = await this.loadTranscribeCli();
|
|
268251
268750
|
} catch {
|
|
@@ -268423,7 +268922,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
268423
268922
|
}
|
|
268424
268923
|
if (!tc) {
|
|
268425
268924
|
try {
|
|
268426
|
-
|
|
268925
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268427
268926
|
this.transcribeCliAvailable = null;
|
|
268428
268927
|
tc = await this.loadTranscribeCli();
|
|
268429
268928
|
} catch {
|
|
@@ -268476,7 +268975,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
268476
268975
|
}
|
|
268477
268976
|
if (!tc) {
|
|
268478
268977
|
try {
|
|
268479
|
-
|
|
268978
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268480
268979
|
this.transcribeCliAvailable = null;
|
|
268481
268980
|
tc = await this.loadTranscribeCli();
|
|
268482
268981
|
} catch {
|
|
@@ -273398,7 +273897,7 @@ var init_render = __esm({
|
|
|
273398
273897
|
|
|
273399
273898
|
// packages/cli/src/tui/voice-session.ts
|
|
273400
273899
|
import { createServer as createServer3 } from "node:http";
|
|
273401
|
-
import { spawn as spawn18, execSync as
|
|
273900
|
+
import { spawn as spawn18, execSync as execSync37 } from "node:child_process";
|
|
273402
273901
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
273403
273902
|
function generateFrontendHTML() {
|
|
273404
273903
|
return `<!DOCTYPE html>
|
|
@@ -279267,7 +279766,7 @@ __export(text_selection_exports, {
|
|
|
279267
279766
|
stripAnsi: () => stripAnsi,
|
|
279268
279767
|
visibleLength: () => visibleLength
|
|
279269
279768
|
});
|
|
279270
|
-
import { execSync as
|
|
279769
|
+
import { execSync as execSync38 } from "node:child_process";
|
|
279271
279770
|
function stripAnsi(s2) {
|
|
279272
279771
|
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
279273
279772
|
}
|
|
@@ -279278,16 +279777,16 @@ function copyText(text) {
|
|
|
279278
279777
|
try {
|
|
279279
279778
|
const platform6 = process.platform;
|
|
279280
279779
|
if (platform6 === "darwin") {
|
|
279281
|
-
|
|
279780
|
+
execSync38("pbcopy", { input: text, timeout: 3e3 });
|
|
279282
279781
|
return true;
|
|
279283
279782
|
}
|
|
279284
279783
|
if (platform6 === "win32") {
|
|
279285
|
-
|
|
279784
|
+
execSync38("clip", { input: text, timeout: 3e3 });
|
|
279286
279785
|
return true;
|
|
279287
279786
|
}
|
|
279288
279787
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
279289
279788
|
try {
|
|
279290
|
-
|
|
279789
|
+
execSync38(tool, { input: text, timeout: 3e3 });
|
|
279291
279790
|
return true;
|
|
279292
279791
|
} catch {
|
|
279293
279792
|
continue;
|
|
@@ -279296,10 +279795,10 @@ function copyText(text) {
|
|
|
279296
279795
|
if (!_clipboardAutoInstallAttempted) {
|
|
279297
279796
|
_clipboardAutoInstallAttempted = true;
|
|
279298
279797
|
try {
|
|
279299
|
-
|
|
279798
|
+
execSync38("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
279300
279799
|
try {
|
|
279301
|
-
|
|
279302
|
-
|
|
279800
|
+
execSync38("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
279801
|
+
execSync38("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
279303
279802
|
return true;
|
|
279304
279803
|
} catch {
|
|
279305
279804
|
}
|
|
@@ -283177,7 +283676,7 @@ __export(personaplex_exports, {
|
|
|
283177
283676
|
import { existsSync as existsSync46, writeFileSync as writeFileSync21, readFileSync as readFileSync36, mkdirSync as mkdirSync20, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync16 } from "node:fs";
|
|
283178
283677
|
import { join as join63, dirname as dirname20 } from "node:path";
|
|
283179
283678
|
import { homedir as homedir17 } from "node:os";
|
|
283180
|
-
import { execSync as
|
|
283679
|
+
import { execSync as execSync39, spawn as spawn20 } from "node:child_process";
|
|
283181
283680
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
283182
283681
|
function execAsync(cmd, opts = {}) {
|
|
283183
283682
|
return new Promise((resolve39, reject) => {
|
|
@@ -283210,7 +283709,7 @@ function detectJetson() {
|
|
|
283210
283709
|
try {
|
|
283211
283710
|
const model = readFileSync36("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
|
|
283212
283711
|
if (/jetson|orin|tegra/i.test(model)) {
|
|
283213
|
-
const memInfo =
|
|
283712
|
+
const memInfo = execSync39("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
283214
283713
|
const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
|
|
283215
283714
|
return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
|
|
283216
283715
|
}
|
|
@@ -283244,7 +283743,7 @@ function detectPersonaPlexCapability() {
|
|
|
283244
283743
|
};
|
|
283245
283744
|
}
|
|
283246
283745
|
try {
|
|
283247
|
-
const nvsmi =
|
|
283746
|
+
const nvsmi = execSync39("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
283248
283747
|
encoding: "utf8",
|
|
283249
283748
|
timeout: 5e3,
|
|
283250
283749
|
stdio: "pipe"
|
|
@@ -283256,7 +283755,7 @@ function detectPersonaPlexCapability() {
|
|
|
283256
283755
|
return { ...fail2(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
|
|
283257
283756
|
}
|
|
283258
283757
|
try {
|
|
283259
|
-
|
|
283758
|
+
execSync39('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
283260
283759
|
timeout: 1e4,
|
|
283261
283760
|
stdio: "pipe"
|
|
283262
283761
|
});
|
|
@@ -283329,7 +283828,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283329
283828
|
mkdirSync20(PERSONAPLEX_DIR, { recursive: true });
|
|
283330
283829
|
let arch2 = "";
|
|
283331
283830
|
try {
|
|
283332
|
-
arch2 =
|
|
283831
|
+
arch2 = execSync39("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
283333
283832
|
} catch {
|
|
283334
283833
|
}
|
|
283335
283834
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
@@ -283350,16 +283849,16 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283350
283849
|
log22("Checking system dependencies (libopus)...");
|
|
283351
283850
|
try {
|
|
283352
283851
|
if (process.platform === "linux") {
|
|
283353
|
-
|
|
283852
|
+
execSync39("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
|
|
283354
283853
|
} else if (process.platform === "darwin") {
|
|
283355
|
-
|
|
283854
|
+
execSync39("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
|
|
283356
283855
|
}
|
|
283357
283856
|
} catch {
|
|
283358
283857
|
}
|
|
283359
283858
|
if (isAarch64) {
|
|
283360
283859
|
log22("ARM64: Checking Rust toolchain for sphn build...");
|
|
283361
283860
|
try {
|
|
283362
|
-
|
|
283861
|
+
execSync39("rustc --version", { timeout: 5e3, stdio: "pipe" });
|
|
283363
283862
|
} catch {
|
|
283364
283863
|
log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
|
|
283365
283864
|
try {
|
|
@@ -283432,7 +283931,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283432
283931
|
}
|
|
283433
283932
|
const serverPy = join63(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
283434
283933
|
try {
|
|
283435
|
-
const sitePackages =
|
|
283934
|
+
const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283436
283935
|
encoding: "utf8",
|
|
283437
283936
|
timeout: 5e3,
|
|
283438
283937
|
stdio: "pipe"
|
|
@@ -283449,7 +283948,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283449
283948
|
} catch {
|
|
283450
283949
|
}
|
|
283451
283950
|
try {
|
|
283452
|
-
const sitePackages =
|
|
283951
|
+
const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283453
283952
|
encoding: "utf8",
|
|
283454
283953
|
timeout: 5e3,
|
|
283455
283954
|
stdio: "pipe"
|
|
@@ -283553,7 +284052,7 @@ $2if filename.endswith(".safetensors"):`
|
|
|
283553
284052
|
} catch {
|
|
283554
284053
|
}
|
|
283555
284054
|
try {
|
|
283556
|
-
const sitePackages2 =
|
|
284055
|
+
const sitePackages2 = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283557
284056
|
encoding: "utf8",
|
|
283558
284057
|
timeout: 5e3,
|
|
283559
284058
|
stdio: "pipe"
|
|
@@ -283688,14 +284187,14 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
283688
284187
|
if (tier === "nf4-distilled") {
|
|
283689
284188
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
283690
284189
|
try {
|
|
283691
|
-
const weightPath =
|
|
284190
|
+
const weightPath = execSync39(
|
|
283692
284191
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
283693
284192
|
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
283694
284193
|
).trim();
|
|
283695
284194
|
if (existsSync46(weightPath)) {
|
|
283696
284195
|
if (!existsSync46(cachedBf16)) {
|
|
283697
284196
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
283698
|
-
|
|
284197
|
+
execSync39(
|
|
283699
284198
|
`"${venvPython2}" -c "
|
|
283700
284199
|
import torch; from safetensors.torch import save_file
|
|
283701
284200
|
state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
|
|
@@ -283727,13 +284226,13 @@ print('Converted')
|
|
|
283727
284226
|
}
|
|
283728
284227
|
}
|
|
283729
284228
|
try {
|
|
283730
|
-
const weightPath =
|
|
284229
|
+
const weightPath = execSync39(
|
|
283731
284230
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
283732
284231
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283733
284232
|
).trim();
|
|
283734
284233
|
if (existsSync46(dequantScript) && existsSync46(weightPath)) {
|
|
283735
284234
|
try {
|
|
283736
|
-
|
|
284235
|
+
execSync39(
|
|
283737
284236
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
283738
284237
|
{ timeout: 3e5, stdio: "pipe" }
|
|
283739
284238
|
);
|
|
@@ -283746,7 +284245,7 @@ print('Converted')
|
|
|
283746
284245
|
}
|
|
283747
284246
|
}
|
|
283748
284247
|
try {
|
|
283749
|
-
const mimiPath =
|
|
284248
|
+
const mimiPath = execSync39(
|
|
283750
284249
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
283751
284250
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283752
284251
|
).trim();
|
|
@@ -283754,7 +284253,7 @@ print('Converted')
|
|
|
283754
284253
|
} catch {
|
|
283755
284254
|
}
|
|
283756
284255
|
try {
|
|
283757
|
-
const tokPath =
|
|
284256
|
+
const tokPath = execSync39(
|
|
283758
284257
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
283759
284258
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283760
284259
|
).trim();
|
|
@@ -283778,7 +284277,7 @@ print('Converted')
|
|
|
283778
284277
|
}
|
|
283779
284278
|
if (!ollamaModel) ollamaModel = "qwen3.5:4b";
|
|
283780
284279
|
try {
|
|
283781
|
-
const ollamaCheck =
|
|
284280
|
+
const ollamaCheck = execSync39("curl -s http://localhost:11434/api/tags", {
|
|
283782
284281
|
timeout: 3e3,
|
|
283783
284282
|
stdio: "pipe",
|
|
283784
284283
|
encoding: "utf8"
|
|
@@ -283852,7 +284351,7 @@ print('Converted')
|
|
|
283852
284351
|
return null;
|
|
283853
284352
|
}
|
|
283854
284353
|
try {
|
|
283855
|
-
|
|
284354
|
+
execSync39(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
|
|
283856
284355
|
timeout: 3e3,
|
|
283857
284356
|
stdio: "pipe",
|
|
283858
284357
|
encoding: "utf8"
|
|
@@ -283875,7 +284374,7 @@ function stopPersonaPlex() {
|
|
|
283875
284374
|
if (isNaN(pid) || pid <= 0) return;
|
|
283876
284375
|
try {
|
|
283877
284376
|
if (process.platform === "win32") {
|
|
283878
|
-
|
|
284377
|
+
execSync39(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
283879
284378
|
} else {
|
|
283880
284379
|
process.kill(pid, "SIGTERM");
|
|
283881
284380
|
}
|
|
@@ -284179,7 +284678,7 @@ __export(setup_exports, {
|
|
|
284179
284678
|
updateOllama: () => updateOllama
|
|
284180
284679
|
});
|
|
284181
284680
|
import * as readline from "node:readline";
|
|
284182
|
-
import { execSync as
|
|
284681
|
+
import { execSync as execSync40, spawn as spawn21, exec as exec4 } from "node:child_process";
|
|
284183
284682
|
import { promisify as promisify7 } from "node:util";
|
|
284184
284683
|
import { existsSync as existsSync47, writeFileSync as writeFileSync22, readFileSync as readFileSync37, appendFileSync as appendFileSync2, mkdirSync as mkdirSync21 } from "node:fs";
|
|
284185
284684
|
import { join as join64 } from "node:path";
|
|
@@ -284217,7 +284716,7 @@ function detectSystemSpecs() {
|
|
|
284217
284716
|
let gpuVramGB = 0;
|
|
284218
284717
|
let gpuName = "";
|
|
284219
284718
|
try {
|
|
284220
|
-
const memInfo =
|
|
284719
|
+
const memInfo = execSync40("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
284221
284720
|
encoding: "utf8",
|
|
284222
284721
|
timeout: 5e3
|
|
284223
284722
|
});
|
|
@@ -284237,7 +284736,7 @@ function detectSystemSpecs() {
|
|
|
284237
284736
|
} catch {
|
|
284238
284737
|
}
|
|
284239
284738
|
try {
|
|
284240
|
-
const nvidiaSmi =
|
|
284739
|
+
const nvidiaSmi = execSync40(
|
|
284241
284740
|
"nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null",
|
|
284242
284741
|
{ encoding: "utf8", timeout: 5e3 }
|
|
284243
284742
|
);
|
|
@@ -284411,7 +284910,7 @@ function ensureCurl() {
|
|
|
284411
284910
|
for (const s2 of strategies) {
|
|
284412
284911
|
if (hasCmd(s2.check)) {
|
|
284413
284912
|
try {
|
|
284414
|
-
|
|
284913
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284415
284914
|
if (hasCmd("curl")) {
|
|
284416
284915
|
process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
|
|
284417
284916
|
`);
|
|
@@ -284425,7 +284924,7 @@ function ensureCurl() {
|
|
|
284425
284924
|
}
|
|
284426
284925
|
if (plat === "darwin") {
|
|
284427
284926
|
try {
|
|
284428
|
-
|
|
284927
|
+
execSync40("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
284429
284928
|
if (hasCmd("curl")) return true;
|
|
284430
284929
|
} catch {
|
|
284431
284930
|
}
|
|
@@ -284459,7 +284958,7 @@ function installOllamaLinux() {
|
|
|
284459
284958
|
|
|
284460
284959
|
`);
|
|
284461
284960
|
try {
|
|
284462
|
-
|
|
284961
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284463
284962
|
stdio: "inherit",
|
|
284464
284963
|
timeout: 3e5
|
|
284465
284964
|
});
|
|
@@ -284487,7 +284986,7 @@ async function installOllamaMac(_rl) {
|
|
|
284487
284986
|
|
|
284488
284987
|
`);
|
|
284489
284988
|
try {
|
|
284490
|
-
|
|
284989
|
+
execSync40(
|
|
284491
284990
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
284492
284991
|
{ stdio: "inherit", timeout: 6e5 }
|
|
284493
284992
|
);
|
|
@@ -284523,7 +285022,7 @@ async function installOllamaMac(_rl) {
|
|
|
284523
285022
|
|
|
284524
285023
|
`);
|
|
284525
285024
|
try {
|
|
284526
|
-
|
|
285025
|
+
execSync40("brew install ollama", {
|
|
284527
285026
|
stdio: "inherit",
|
|
284528
285027
|
timeout: 3e5
|
|
284529
285028
|
});
|
|
@@ -284550,7 +285049,7 @@ function installOllamaWindows() {
|
|
|
284550
285049
|
|
|
284551
285050
|
`);
|
|
284552
285051
|
try {
|
|
284553
|
-
|
|
285052
|
+
execSync40('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
284554
285053
|
stdio: "inherit",
|
|
284555
285054
|
timeout: 3e5
|
|
284556
285055
|
});
|
|
@@ -284630,7 +285129,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
284630
285129
|
}
|
|
284631
285130
|
function getOllamaVersion() {
|
|
284632
285131
|
try {
|
|
284633
|
-
const out =
|
|
285132
|
+
const out = execSync40("ollama --version", { encoding: "utf8", timeout: 5e3 });
|
|
284634
285133
|
const match = out.match(/(\d+\.\d+\.\d+)/);
|
|
284635
285134
|
return match ? match[1] : null;
|
|
284636
285135
|
} catch {
|
|
@@ -284676,7 +285175,7 @@ function updateOllama() {
|
|
|
284676
285175
|
return false;
|
|
284677
285176
|
}
|
|
284678
285177
|
try {
|
|
284679
|
-
|
|
285178
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284680
285179
|
stdio: "inherit",
|
|
284681
285180
|
timeout: 3e5
|
|
284682
285181
|
});
|
|
@@ -284687,7 +285186,7 @@ function updateOllama() {
|
|
|
284687
285186
|
}
|
|
284688
285187
|
function pullModelWithAutoUpdate(tag) {
|
|
284689
285188
|
try {
|
|
284690
|
-
|
|
285189
|
+
execSync40(`ollama pull ${tag}`, {
|
|
284691
285190
|
stdio: "inherit",
|
|
284692
285191
|
timeout: 36e5
|
|
284693
285192
|
// 1 hour max
|
|
@@ -284707,7 +285206,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
284707
285206
|
|
|
284708
285207
|
`);
|
|
284709
285208
|
try {
|
|
284710
|
-
|
|
285209
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284711
285210
|
stdio: "inherit",
|
|
284712
285211
|
timeout: 3e5
|
|
284713
285212
|
// 5 min max for install
|
|
@@ -284718,7 +285217,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
284718
285217
|
process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
|
|
284719
285218
|
|
|
284720
285219
|
`);
|
|
284721
|
-
|
|
285220
|
+
execSync40(`ollama pull ${tag}`, {
|
|
284722
285221
|
stdio: "inherit",
|
|
284723
285222
|
timeout: 36e5
|
|
284724
285223
|
});
|
|
@@ -284807,7 +285306,7 @@ function ensurePython3() {
|
|
|
284807
285306
|
if (plat === "darwin") {
|
|
284808
285307
|
if (hasCmd("brew")) {
|
|
284809
285308
|
try {
|
|
284810
|
-
|
|
285309
|
+
execSync40("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
284811
285310
|
if (hasCmd("python3")) {
|
|
284812
285311
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
|
|
284813
285312
|
`);
|
|
@@ -284820,7 +285319,7 @@ function ensurePython3() {
|
|
|
284820
285319
|
for (const s2 of strategies) {
|
|
284821
285320
|
if (hasCmd(s2.check)) {
|
|
284822
285321
|
try {
|
|
284823
|
-
|
|
285322
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284824
285323
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
284825
285324
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
|
|
284826
285325
|
`);
|
|
@@ -284836,11 +285335,11 @@ function ensurePython3() {
|
|
|
284836
285335
|
}
|
|
284837
285336
|
function checkPythonVenv() {
|
|
284838
285337
|
try {
|
|
284839
|
-
|
|
285338
|
+
execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
284840
285339
|
return true;
|
|
284841
285340
|
} catch {
|
|
284842
285341
|
try {
|
|
284843
|
-
|
|
285342
|
+
execSync40("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
284844
285343
|
return true;
|
|
284845
285344
|
} catch {
|
|
284846
285345
|
return false;
|
|
@@ -284859,7 +285358,7 @@ function ensurePythonVenv() {
|
|
|
284859
285358
|
for (const s2 of strategies) {
|
|
284860
285359
|
if (hasCmd(s2.check)) {
|
|
284861
285360
|
try {
|
|
284862
|
-
|
|
285361
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284863
285362
|
if (checkPythonVenv()) {
|
|
284864
285363
|
process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
|
|
284865
285364
|
`);
|
|
@@ -285287,7 +285786,7 @@ async function doSetup(config, rl) {
|
|
|
285287
285786
|
const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
|
|
285288
285787
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
285289
285788
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
285290
|
-
|
|
285789
|
+
execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
285291
285790
|
stdio: "pipe",
|
|
285292
285791
|
timeout: 12e4
|
|
285293
285792
|
});
|
|
@@ -285338,7 +285837,7 @@ function isFirstRun() {
|
|
|
285338
285837
|
function hasCmd(cmd) {
|
|
285339
285838
|
try {
|
|
285340
285839
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
285341
|
-
|
|
285840
|
+
execSync40(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
285342
285841
|
return true;
|
|
285343
285842
|
} catch {
|
|
285344
285843
|
return false;
|
|
@@ -285350,7 +285849,7 @@ function detectPkgManager() {
|
|
|
285350
285849
|
if (hasCmd("choco")) return "choco";
|
|
285351
285850
|
if (hasCmd("winget")) return "winget";
|
|
285352
285851
|
try {
|
|
285353
|
-
|
|
285852
|
+
execSync40(
|
|
285354
285853
|
`powershell -NoProfile -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"`,
|
|
285355
285854
|
{ stdio: "pipe", timeout: 12e4 }
|
|
285356
285855
|
);
|
|
@@ -285362,7 +285861,7 @@ function detectPkgManager() {
|
|
|
285362
285861
|
if (plat === "darwin") {
|
|
285363
285862
|
if (hasCmd("brew")) return "brew";
|
|
285364
285863
|
try {
|
|
285365
|
-
|
|
285864
|
+
execSync40(
|
|
285366
285865
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
285367
285866
|
{ stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } }
|
|
285368
285867
|
);
|
|
@@ -285382,7 +285881,7 @@ function getVenvDir() {
|
|
|
285382
285881
|
}
|
|
285383
285882
|
function hasVenvModule() {
|
|
285384
285883
|
try {
|
|
285385
|
-
|
|
285884
|
+
execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285386
285885
|
return true;
|
|
285387
285886
|
} catch {
|
|
285388
285887
|
return false;
|
|
@@ -285406,8 +285905,8 @@ function ensureVenv(log22) {
|
|
|
285406
285905
|
try {
|
|
285407
285906
|
mkdirSync21(join64(homedir18(), ".open-agents"), { recursive: true });
|
|
285408
285907
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
285409
|
-
|
|
285410
|
-
|
|
285908
|
+
execSync40(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
285909
|
+
execSync40(`"${pipPath}" install --upgrade pip`, {
|
|
285411
285910
|
stdio: "pipe",
|
|
285412
285911
|
timeout: 6e4
|
|
285413
285912
|
});
|
|
@@ -285420,7 +285919,7 @@ function ensureVenv(log22) {
|
|
|
285420
285919
|
}
|
|
285421
285920
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
285422
285921
|
try {
|
|
285423
|
-
|
|
285922
|
+
execSync40(`sudo -n ${cmd}`, {
|
|
285424
285923
|
stdio: "pipe",
|
|
285425
285924
|
timeout: timeoutMs,
|
|
285426
285925
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -285433,7 +285932,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
285433
285932
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
285434
285933
|
try {
|
|
285435
285934
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
285436
|
-
|
|
285935
|
+
execSync40(`sudo -S bash -c '${escaped}'`, {
|
|
285437
285936
|
input: password + "\n",
|
|
285438
285937
|
stdio: ["pipe", "pipe", "pipe"],
|
|
285439
285938
|
timeout: timeoutMs,
|
|
@@ -285527,7 +286026,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285527
286026
|
let winNeedsElevation = false;
|
|
285528
286027
|
if (process.platform === "win32") {
|
|
285529
286028
|
try {
|
|
285530
|
-
|
|
286029
|
+
execSync40("net session", { stdio: "pipe", timeout: 3e3 });
|
|
285531
286030
|
} catch {
|
|
285532
286031
|
winNeedsElevation = true;
|
|
285533
286032
|
log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
|
|
@@ -285574,12 +286073,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285574
286073
|
if (needsSudo) {
|
|
285575
286074
|
await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
|
|
285576
286075
|
} else if (winNeedsElevation) {
|
|
285577
|
-
|
|
286076
|
+
execSync40(
|
|
285578
286077
|
`powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`,
|
|
285579
286078
|
{ stdio: "pipe", timeout: 18e4 }
|
|
285580
286079
|
);
|
|
285581
286080
|
} else {
|
|
285582
|
-
|
|
286081
|
+
execSync40(installCmd, { stdio: "pipe", timeout: 18e4 });
|
|
285583
286082
|
}
|
|
285584
286083
|
} catch (e2) {
|
|
285585
286084
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -285592,7 +286091,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285592
286091
|
if (!hasCmd(d2.binary) && pipPkg) {
|
|
285593
286092
|
try {
|
|
285594
286093
|
const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
|
|
285595
|
-
|
|
286094
|
+
execSync40(pipCmd, { stdio: "pipe", timeout: 12e4 });
|
|
285596
286095
|
lastError = "";
|
|
285597
286096
|
} catch (e2) {
|
|
285598
286097
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -285604,7 +286103,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285604
286103
|
}
|
|
285605
286104
|
if (process.platform === "win32" && !hasCmd(d2.binary)) {
|
|
285606
286105
|
try {
|
|
285607
|
-
const freshPath =
|
|
286106
|
+
const freshPath = execSync40(
|
|
285608
286107
|
`powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`,
|
|
285609
286108
|
{ encoding: "utf8", timeout: 5e3, stdio: "pipe" }
|
|
285610
286109
|
).trim();
|
|
@@ -285650,7 +286149,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285650
286149
|
const venvCmds = {
|
|
285651
286150
|
apt: () => {
|
|
285652
286151
|
try {
|
|
285653
|
-
const pyVer =
|
|
286152
|
+
const pyVer = execSync40(
|
|
285654
286153
|
`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
285655
286154
|
{ encoding: "utf8", stdio: "pipe", timeout: 5e3 }
|
|
285656
286155
|
).trim();
|
|
@@ -285682,12 +286181,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285682
286181
|
const venvPip2 = join64(venvBin, "pip");
|
|
285683
286182
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
285684
286183
|
try {
|
|
285685
|
-
|
|
286184
|
+
execSync40(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
285686
286185
|
if (existsSync47(venvMoondream)) {
|
|
285687
286186
|
log22("moondream-station installed successfully.");
|
|
285688
286187
|
} else {
|
|
285689
286188
|
try {
|
|
285690
|
-
const check =
|
|
286189
|
+
const check = execSync40(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
285691
286190
|
if (check.includes("moondream")) {
|
|
285692
286191
|
log22("moondream-station package installed.");
|
|
285693
286192
|
}
|
|
@@ -285704,7 +286203,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285704
286203
|
const venvPip2 = join64(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
285705
286204
|
let ocrStackInstalled = false;
|
|
285706
286205
|
try {
|
|
285707
|
-
|
|
286206
|
+
execSync40(
|
|
285708
286207
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
285709
286208
|
{ stdio: "pipe", timeout: 1e4 }
|
|
285710
286209
|
);
|
|
@@ -285715,12 +286214,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285715
286214
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
285716
286215
|
log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
285717
286216
|
try {
|
|
285718
|
-
|
|
286217
|
+
execSync40(
|
|
285719
286218
|
`"${venvPip2}" install ${ocrPackages}`,
|
|
285720
286219
|
{ stdio: "pipe", timeout: 3e5 }
|
|
285721
286220
|
);
|
|
285722
286221
|
try {
|
|
285723
|
-
|
|
286222
|
+
execSync40(
|
|
285724
286223
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
285725
286224
|
{ stdio: "pipe", timeout: 1e4 }
|
|
285726
286225
|
);
|
|
@@ -285756,7 +286255,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285756
286255
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
285757
286256
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
285758
286257
|
try {
|
|
285759
|
-
|
|
286258
|
+
execSync40(
|
|
285760
286259
|
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir18()}/.local/bin" && mv /tmp/cloudflared "${homedir18()}/.local/bin/cloudflared"`,
|
|
285761
286260
|
{ stdio: "pipe", timeout: 6e4 }
|
|
285762
286261
|
);
|
|
@@ -285770,7 +286269,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285770
286269
|
} catch {
|
|
285771
286270
|
}
|
|
285772
286271
|
try {
|
|
285773
|
-
|
|
286272
|
+
execSync40(
|
|
285774
286273
|
`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`,
|
|
285775
286274
|
{ stdio: "pipe", timeout: 6e4 }
|
|
285776
286275
|
);
|
|
@@ -285782,7 +286281,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285782
286281
|
}
|
|
285783
286282
|
} else if (os8 === "darwin") {
|
|
285784
286283
|
try {
|
|
285785
|
-
|
|
286284
|
+
execSync40("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
285786
286285
|
if (hasCmd("cloudflared")) {
|
|
285787
286286
|
log22("cloudflared installed via Homebrew.");
|
|
285788
286287
|
return true;
|
|
@@ -285862,7 +286361,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
285862
286361
|
mkdirSync21(modelDir2, { recursive: true });
|
|
285863
286362
|
const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
|
|
285864
286363
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
285865
|
-
|
|
286364
|
+
execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
285866
286365
|
stdio: "pipe",
|
|
285867
286366
|
timeout: 12e4
|
|
285868
286367
|
});
|
|
@@ -285948,7 +286447,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
285948
286447
|
}
|
|
285949
286448
|
async function ensureNeovim() {
|
|
285950
286449
|
try {
|
|
285951
|
-
const nvimPath =
|
|
286450
|
+
const nvimPath = execSync40("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
285952
286451
|
encoding: "utf8",
|
|
285953
286452
|
stdio: "pipe",
|
|
285954
286453
|
timeout: 5e3
|
|
@@ -285969,14 +286468,14 @@ async function ensureNeovim() {
|
|
|
285969
286468
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
285970
286469
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
285971
286470
|
try {
|
|
285972
|
-
|
|
285973
|
-
|
|
286471
|
+
execSync40(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
286472
|
+
execSync40(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
285974
286473
|
} catch (err) {
|
|
285975
286474
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
285976
286475
|
return null;
|
|
285977
286476
|
}
|
|
285978
286477
|
try {
|
|
285979
|
-
const ver =
|
|
286478
|
+
const ver = execSync40(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
285980
286479
|
console.log(` Installed: ${ver}`);
|
|
285981
286480
|
} catch {
|
|
285982
286481
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -285991,8 +286490,8 @@ async function ensureNeovim() {
|
|
|
285991
286490
|
if (hasCmd("brew")) {
|
|
285992
286491
|
console.log(" Installing Neovim via Homebrew...");
|
|
285993
286492
|
try {
|
|
285994
|
-
|
|
285995
|
-
const nvimPath =
|
|
286493
|
+
execSync40("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
286494
|
+
const nvimPath = execSync40("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
285996
286495
|
return nvimPath || null;
|
|
285997
286496
|
} catch {
|
|
285998
286497
|
console.log(" brew install neovim failed.");
|
|
@@ -286006,7 +286505,7 @@ async function ensureNeovim() {
|
|
|
286006
286505
|
if (hasCmd("choco")) {
|
|
286007
286506
|
console.log(" Installing Neovim via Chocolatey...");
|
|
286008
286507
|
try {
|
|
286009
|
-
|
|
286508
|
+
execSync40("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
286010
286509
|
return "nvim";
|
|
286011
286510
|
} catch {
|
|
286012
286511
|
console.log(" choco install neovim failed.");
|
|
@@ -286015,7 +286514,7 @@ async function ensureNeovim() {
|
|
|
286015
286514
|
if (hasCmd("winget")) {
|
|
286016
286515
|
console.log(" Installing Neovim via winget...");
|
|
286017
286516
|
try {
|
|
286018
|
-
|
|
286517
|
+
execSync40("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
286019
286518
|
stdio: "inherit",
|
|
286020
286519
|
timeout: 12e4
|
|
286021
286520
|
});
|
|
@@ -286266,7 +286765,7 @@ var init_drop_panel = __esm({
|
|
|
286266
286765
|
import { existsSync as existsSync49, unlinkSync as unlinkSync11 } from "node:fs";
|
|
286267
286766
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
286268
286767
|
import { join as join65 } from "node:path";
|
|
286269
|
-
import { execSync as
|
|
286768
|
+
import { execSync as execSync41 } from "node:child_process";
|
|
286270
286769
|
function isNeovimActive() {
|
|
286271
286770
|
return _state !== null && !_state.cleanedUp;
|
|
286272
286771
|
}
|
|
@@ -286283,7 +286782,7 @@ async function startNeovimMode(opts) {
|
|
|
286283
286782
|
}
|
|
286284
286783
|
let nvimPath;
|
|
286285
286784
|
try {
|
|
286286
|
-
nvimPath =
|
|
286785
|
+
nvimPath = execSync41("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
286287
286786
|
if (!nvimPath) throw new Error();
|
|
286288
286787
|
} catch {
|
|
286289
286788
|
const installed = await ensureNeovim();
|
|
@@ -286818,8 +287317,8 @@ async function startDaemon() {
|
|
|
286818
287317
|
let oaScript = process.argv[1];
|
|
286819
287318
|
if (!oaScript) {
|
|
286820
287319
|
try {
|
|
286821
|
-
const { execSync:
|
|
286822
|
-
const whichOa =
|
|
287320
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
287321
|
+
const whichOa = execSync48("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
|
|
286823
287322
|
if (whichOa) oaScript = whichOa;
|
|
286824
287323
|
} catch {
|
|
286825
287324
|
}
|
|
@@ -288226,7 +288725,7 @@ __export(voice_exports, {
|
|
|
288226
288725
|
import { existsSync as existsSync52, mkdirSync as mkdirSync24, writeFileSync as writeFileSync25, readFileSync as readFileSync40, unlinkSync as unlinkSync13, readdirSync as readdirSync13, statSync as statSync17 } from "node:fs";
|
|
288227
288726
|
import { join as join68, dirname as dirname22 } from "node:path";
|
|
288228
288727
|
import { homedir as homedir20, tmpdir as tmpdir12, platform as platform4 } from "node:os";
|
|
288229
|
-
import { execSync as
|
|
288728
|
+
import { execSync as execSync42, spawn as nodeSpawn } from "node:child_process";
|
|
288230
288729
|
import { createRequire as createRequire2 } from "node:module";
|
|
288231
288730
|
function sanitizeForTTS(text) {
|
|
288232
288731
|
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();
|
|
@@ -289914,7 +290413,7 @@ var init_voice = __esm({
|
|
|
289914
290413
|
}
|
|
289915
290414
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
289916
290415
|
try {
|
|
289917
|
-
|
|
290416
|
+
execSync42(`which ${player}`, { stdio: "pipe" });
|
|
289918
290417
|
return [player, path5];
|
|
289919
290418
|
} catch {
|
|
289920
290419
|
}
|
|
@@ -289942,7 +290441,7 @@ var init_voice = __esm({
|
|
|
289942
290441
|
if (this.python3Path) return this.python3Path;
|
|
289943
290442
|
for (const bin of ["python3", "python"]) {
|
|
289944
290443
|
try {
|
|
289945
|
-
const path5 =
|
|
290444
|
+
const path5 = execSync42(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
289946
290445
|
if (path5) {
|
|
289947
290446
|
this.python3Path = path5;
|
|
289948
290447
|
return path5;
|
|
@@ -290004,7 +290503,7 @@ var init_voice = __esm({
|
|
|
290004
290503
|
return false;
|
|
290005
290504
|
}
|
|
290006
290505
|
try {
|
|
290007
|
-
|
|
290506
|
+
execSync42(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
290008
290507
|
this.mlxInstalled = true;
|
|
290009
290508
|
return true;
|
|
290010
290509
|
} catch {
|
|
@@ -290067,14 +290566,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
290067
290566
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
290068
290567
|
].join("; ");
|
|
290069
290568
|
try {
|
|
290070
|
-
|
|
290569
|
+
execSync42(
|
|
290071
290570
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
290072
290571
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290073
290572
|
);
|
|
290074
290573
|
} catch (err) {
|
|
290075
290574
|
try {
|
|
290076
290575
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
290077
|
-
|
|
290576
|
+
execSync42(
|
|
290078
290577
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
290079
290578
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290080
290579
|
);
|
|
@@ -290141,14 +290640,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
290141
290640
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
290142
290641
|
].join("; ");
|
|
290143
290642
|
try {
|
|
290144
|
-
|
|
290643
|
+
execSync42(
|
|
290145
290644
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
290146
290645
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290147
290646
|
);
|
|
290148
290647
|
} catch {
|
|
290149
290648
|
try {
|
|
290150
290649
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
290151
|
-
|
|
290650
|
+
execSync42(
|
|
290152
290651
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
290153
290652
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290154
290653
|
);
|
|
@@ -295663,7 +296162,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
295663
296162
|
}
|
|
295664
296163
|
}
|
|
295665
296164
|
async function handleParallel(arg, ctx3) {
|
|
295666
|
-
const { execSync:
|
|
296165
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
295667
296166
|
const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
|
|
295668
296167
|
const isRemote = ctx3.config.backendType === "nexus";
|
|
295669
296168
|
if (isRemote) {
|
|
@@ -295687,7 +296186,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
295687
296186
|
}
|
|
295688
296187
|
let systemdVal = "";
|
|
295689
296188
|
try {
|
|
295690
|
-
const out =
|
|
296189
|
+
const out = execSync48("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
295691
296190
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
295692
296191
|
if (match) systemdVal = match[1];
|
|
295693
296192
|
} catch {
|
|
@@ -295715,7 +296214,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
295715
296214
|
}
|
|
295716
296215
|
const isSystemd = (() => {
|
|
295717
296216
|
try {
|
|
295718
|
-
const out =
|
|
296217
|
+
const out = execSync48("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
295719
296218
|
return out === "active" || out === "inactive";
|
|
295720
296219
|
} catch {
|
|
295721
296220
|
return false;
|
|
@@ -295729,10 +296228,10 @@ async function handleParallel(arg, ctx3) {
|
|
|
295729
296228
|
const overrideContent = `[Service]
|
|
295730
296229
|
Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
295731
296230
|
`;
|
|
295732
|
-
|
|
295733
|
-
|
|
295734
|
-
|
|
295735
|
-
|
|
296231
|
+
execSync48(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
296232
|
+
execSync48(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
296233
|
+
execSync48("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
296234
|
+
execSync48("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
295736
296235
|
let ready = false;
|
|
295737
296236
|
for (let i2 = 0; i2 < 30 && !ready; i2++) {
|
|
295738
296237
|
await new Promise((r2) => setTimeout(r2, 500));
|
|
@@ -295758,7 +296257,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
295758
296257
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
|
|
295759
296258
|
try {
|
|
295760
296259
|
try {
|
|
295761
|
-
|
|
296260
|
+
execSync48("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
295762
296261
|
} catch {
|
|
295763
296262
|
}
|
|
295764
296263
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
@@ -296810,18 +297309,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
296810
297309
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
296811
297310
|
let copied = false;
|
|
296812
297311
|
try {
|
|
296813
|
-
const { execSync:
|
|
297312
|
+
const { execSync: execSync48 } = __require("node:child_process");
|
|
296814
297313
|
const platform6 = process.platform;
|
|
296815
297314
|
if (platform6 === "darwin") {
|
|
296816
|
-
|
|
297315
|
+
execSync48("pbcopy", { input: cmd, timeout: 3e3 });
|
|
296817
297316
|
copied = true;
|
|
296818
297317
|
} else if (platform6 === "win32") {
|
|
296819
|
-
|
|
297318
|
+
execSync48("clip", { input: cmd, timeout: 3e3 });
|
|
296820
297319
|
copied = true;
|
|
296821
297320
|
} else {
|
|
296822
297321
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
296823
297322
|
try {
|
|
296824
|
-
|
|
297323
|
+
execSync48(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
296825
297324
|
copied = true;
|
|
296826
297325
|
break;
|
|
296827
297326
|
} catch {
|
|
@@ -296916,7 +297415,7 @@ var init_commands = __esm({
|
|
|
296916
297415
|
// packages/cli/src/tui/project-context.ts
|
|
296917
297416
|
import { existsSync as existsSync54, readFileSync as readFileSync42, readdirSync as readdirSync15 } from "node:fs";
|
|
296918
297417
|
import { join as join70, basename as basename13 } from "node:path";
|
|
296919
|
-
import { execSync as
|
|
297418
|
+
import { execSync as execSync43 } from "node:child_process";
|
|
296920
297419
|
import { homedir as homedir22, platform as platform5, release } from "node:os";
|
|
296921
297420
|
function getModelTier(modelName) {
|
|
296922
297421
|
const m2 = modelName.toLowerCase();
|
|
@@ -296958,18 +297457,18 @@ function loadProjectMap(repoRoot) {
|
|
|
296958
297457
|
}
|
|
296959
297458
|
function getGitInfo(repoRoot) {
|
|
296960
297459
|
try {
|
|
296961
|
-
|
|
297460
|
+
execSync43("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
296962
297461
|
} catch {
|
|
296963
297462
|
return "";
|
|
296964
297463
|
}
|
|
296965
297464
|
const lines = [];
|
|
296966
297465
|
try {
|
|
296967
|
-
const branch =
|
|
297466
|
+
const branch = execSync43("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296968
297467
|
if (branch) lines.push(`Branch: ${branch}`);
|
|
296969
297468
|
} catch {
|
|
296970
297469
|
}
|
|
296971
297470
|
try {
|
|
296972
|
-
const status =
|
|
297471
|
+
const status = execSync43("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296973
297472
|
if (status) {
|
|
296974
297473
|
const changed = status.split("\n").length;
|
|
296975
297474
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -296979,7 +297478,7 @@ function getGitInfo(repoRoot) {
|
|
|
296979
297478
|
} catch {
|
|
296980
297479
|
}
|
|
296981
297480
|
try {
|
|
296982
|
-
const log22 =
|
|
297481
|
+
const log22 = execSync43("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296983
297482
|
if (log22) lines.push(`Recent commits:
|
|
296984
297483
|
${log22}`);
|
|
296985
297484
|
} catch {
|
|
@@ -299643,7 +300142,7 @@ var init_promptLoader3 = __esm({
|
|
|
299643
300142
|
// packages/cli/src/tui/dream-engine.ts
|
|
299644
300143
|
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync29, readFileSync as readFileSync46, existsSync as existsSync58, readdirSync as readdirSync17 } from "node:fs";
|
|
299645
300144
|
import { join as join75, basename as basename15 } from "node:path";
|
|
299646
|
-
import { execSync as
|
|
300145
|
+
import { execSync as execSync44 } from "node:child_process";
|
|
299647
300146
|
function setDreamWriteContent(fn) {
|
|
299648
300147
|
_dreamWriteContent = fn;
|
|
299649
300148
|
}
|
|
@@ -300017,7 +300516,7 @@ var init_dream_engine = __esm({
|
|
|
300017
300516
|
}
|
|
300018
300517
|
}
|
|
300019
300518
|
try {
|
|
300020
|
-
const output =
|
|
300519
|
+
const output = execSync44(cmd, {
|
|
300021
300520
|
cwd: this.repoRoot,
|
|
300022
300521
|
timeout: 3e4,
|
|
300023
300522
|
encoding: "utf-8",
|
|
@@ -300876,17 +301375,17 @@ ${summaryResult}
|
|
|
300876
301375
|
try {
|
|
300877
301376
|
mkdirSync29(checkpointDir, { recursive: true });
|
|
300878
301377
|
try {
|
|
300879
|
-
const gitStatus =
|
|
301378
|
+
const gitStatus = execSync44("git status --porcelain", {
|
|
300880
301379
|
cwd: this.repoRoot,
|
|
300881
301380
|
encoding: "utf-8",
|
|
300882
301381
|
timeout: 1e4
|
|
300883
301382
|
});
|
|
300884
|
-
const gitDiff =
|
|
301383
|
+
const gitDiff = execSync44("git diff", {
|
|
300885
301384
|
cwd: this.repoRoot,
|
|
300886
301385
|
encoding: "utf-8",
|
|
300887
301386
|
timeout: 1e4
|
|
300888
301387
|
});
|
|
300889
|
-
const gitHash =
|
|
301388
|
+
const gitHash = execSync44("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
300890
301389
|
cwd: this.repoRoot,
|
|
300891
301390
|
encoding: "utf-8",
|
|
300892
301391
|
timeout: 5e3
|
|
@@ -306479,7 +306978,7 @@ var init_profiles = __esm({
|
|
|
306479
306978
|
});
|
|
306480
306979
|
|
|
306481
306980
|
// packages/cli/src/docker.ts
|
|
306482
|
-
import { execSync as
|
|
306981
|
+
import { execSync as execSync45, spawn as spawn23 } from "node:child_process";
|
|
306483
306982
|
import { existsSync as existsSync66, mkdirSync as mkdirSync35, writeFileSync as writeFileSync33 } from "node:fs";
|
|
306484
306983
|
import { join as join83, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
306485
306984
|
import { homedir as homedir24 } from "node:os";
|
|
@@ -306500,7 +306999,7 @@ function getDockerDir() {
|
|
|
306500
306999
|
}
|
|
306501
307000
|
function isDockerAvailable() {
|
|
306502
307001
|
try {
|
|
306503
|
-
|
|
307002
|
+
execSync45("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
306504
307003
|
return true;
|
|
306505
307004
|
} catch {
|
|
306506
307005
|
return false;
|
|
@@ -306508,7 +307007,7 @@ function isDockerAvailable() {
|
|
|
306508
307007
|
}
|
|
306509
307008
|
function isDockerInstalled() {
|
|
306510
307009
|
try {
|
|
306511
|
-
|
|
307010
|
+
execSync45("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
306512
307011
|
return true;
|
|
306513
307012
|
} catch {
|
|
306514
307013
|
return false;
|
|
@@ -306533,31 +307032,31 @@ async function ensureDocker() {
|
|
|
306533
307032
|
}
|
|
306534
307033
|
try {
|
|
306535
307034
|
console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
|
|
306536
|
-
|
|
307035
|
+
execSync45("curl -fsSL https://get.docker.com | sh", {
|
|
306537
307036
|
stdio: "inherit",
|
|
306538
307037
|
timeout: 3e5
|
|
306539
307038
|
});
|
|
306540
307039
|
const user = process.env["USER"] || process.env["LOGNAME"];
|
|
306541
307040
|
if (user) {
|
|
306542
307041
|
try {
|
|
306543
|
-
|
|
307042
|
+
execSync45(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
|
|
306544
307043
|
} catch {
|
|
306545
307044
|
}
|
|
306546
307045
|
}
|
|
306547
307046
|
try {
|
|
306548
|
-
|
|
307047
|
+
execSync45("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
|
|
306549
307048
|
} catch {
|
|
306550
307049
|
}
|
|
306551
307050
|
try {
|
|
306552
|
-
|
|
306553
|
-
const runtimes =
|
|
307051
|
+
execSync45("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
|
|
307052
|
+
const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
|
|
306554
307053
|
stdio: "pipe",
|
|
306555
307054
|
timeout: 5e3
|
|
306556
307055
|
}).toString();
|
|
306557
307056
|
if (!runtimes.includes("nvidia")) {
|
|
306558
307057
|
console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
|
|
306559
307058
|
try {
|
|
306560
|
-
|
|
307059
|
+
execSync45(`
|
|
306561
307060
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
306562
307061
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
306563
307062
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -306587,7 +307086,7 @@ async function ensureDocker() {
|
|
|
306587
307086
|
}
|
|
306588
307087
|
async function ensureNvidiaToolkit() {
|
|
306589
307088
|
try {
|
|
306590
|
-
|
|
307089
|
+
execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
|
|
306591
307090
|
} catch {
|
|
306592
307091
|
return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
|
|
306593
307092
|
}
|
|
@@ -306598,7 +307097,7 @@ async function ensureNvidiaToolkit() {
|
|
|
306598
307097
|
return { ok: false, message: "Auto-install only supported on Linux. Install manually: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html" };
|
|
306599
307098
|
}
|
|
306600
307099
|
try {
|
|
306601
|
-
|
|
307100
|
+
execSync45(`
|
|
306602
307101
|
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 2>/dev/null
|
|
306603
307102
|
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 2>&1
|
|
306604
307103
|
sudo apt-get update -qq 2>/dev/null && sudo apt-get install -y -qq nvidia-container-toolkit 2>/dev/null || ( sudo dnf install -y nvidia-container-toolkit 2>/dev/null || sudo yum install -y nvidia-container-toolkit 2>/dev/null || true )
|
|
@@ -306612,7 +307111,7 @@ async function ensureNvidiaToolkit() {
|
|
|
306612
307111
|
}
|
|
306613
307112
|
function isOaImageBuilt() {
|
|
306614
307113
|
try {
|
|
306615
|
-
const out =
|
|
307114
|
+
const out = execSync45(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
|
|
306616
307115
|
stdio: "pipe",
|
|
306617
307116
|
timeout: 5e3
|
|
306618
307117
|
}).toString().trim();
|
|
@@ -306636,7 +307135,7 @@ async function ensureOaImage(force = false) {
|
|
|
306636
307135
|
}
|
|
306637
307136
|
try {
|
|
306638
307137
|
console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
|
|
306639
|
-
|
|
307138
|
+
execSync45(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
|
|
306640
307139
|
stdio: "inherit",
|
|
306641
307140
|
timeout: 6e5
|
|
306642
307141
|
// 10 min
|
|
@@ -306710,11 +307209,11 @@ exec "$@"
|
|
|
306710
307209
|
}
|
|
306711
307210
|
function hasNvidiaGpu() {
|
|
306712
307211
|
try {
|
|
306713
|
-
|
|
307212
|
+
execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", {
|
|
306714
307213
|
stdio: "pipe",
|
|
306715
307214
|
timeout: 5e3
|
|
306716
307215
|
});
|
|
306717
|
-
const runtimes =
|
|
307216
|
+
const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
|
|
306718
307217
|
stdio: "pipe",
|
|
306719
307218
|
timeout: 5e3
|
|
306720
307219
|
}).toString();
|
|
@@ -306784,7 +307283,7 @@ import * as https3 from "node:https";
|
|
|
306784
307283
|
import { createRequire as createRequire4 } from "node:module";
|
|
306785
307284
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
306786
307285
|
import { dirname as dirname25, join as join84, resolve as resolve34 } from "node:path";
|
|
306787
|
-
import { spawn as spawn24, execSync as
|
|
307286
|
+
import { spawn as spawn24, execSync as execSync46 } from "node:child_process";
|
|
306788
307287
|
import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync34, readFileSync as readFileSync53, readdirSync as readdirSync23, existsSync as existsSync67 } from "node:fs";
|
|
306789
307288
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
306790
307289
|
function getVersion3() {
|
|
@@ -307792,7 +308291,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
307792
308291
|
const containerName = `oa-${id}`;
|
|
307793
308292
|
if (job.sandbox === "container") {
|
|
307794
308293
|
try {
|
|
307795
|
-
|
|
308294
|
+
execSync46(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
|
|
307796
308295
|
} catch {
|
|
307797
308296
|
}
|
|
307798
308297
|
}
|
|
@@ -308702,7 +309201,7 @@ import { createRequire as createRequire5 } from "node:module";
|
|
|
308702
309201
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
308703
309202
|
import { readFileSync as readFileSync54, writeFileSync as writeFileSync35, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync37 } from "node:fs";
|
|
308704
309203
|
import { existsSync as existsSync68 } from "node:fs";
|
|
308705
|
-
import { execSync as
|
|
309204
|
+
import { execSync as execSync47 } from "node:child_process";
|
|
308706
309205
|
import { homedir as homedir25 } from "node:os";
|
|
308707
309206
|
function formatTimeAgo(date) {
|
|
308708
309207
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -308869,6 +309368,8 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
308869
309368
|
new CameraCaptureTool(),
|
|
308870
309369
|
new AudioCaptureTool(),
|
|
308871
309370
|
new AudioPlaybackTool(),
|
|
309371
|
+
new WifiControlTool(),
|
|
309372
|
+
new BluetoothScanTool(),
|
|
308872
309373
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
308873
309374
|
(() => {
|
|
308874
309375
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -313027,7 +313528,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313027
313528
|
try {
|
|
313028
313529
|
if (process.platform === "win32") {
|
|
313029
313530
|
try {
|
|
313030
|
-
|
|
313531
|
+
execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
313031
313532
|
} catch {
|
|
313032
313533
|
}
|
|
313033
313534
|
} else {
|
|
@@ -313054,7 +313555,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313054
313555
|
if (pid > 0) {
|
|
313055
313556
|
if (process.platform === "win32") {
|
|
313056
313557
|
try {
|
|
313057
|
-
|
|
313558
|
+
execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
313058
313559
|
} catch {
|
|
313059
313560
|
}
|
|
313060
313561
|
} else {
|
|
@@ -313071,7 +313572,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313071
313572
|
} catch {
|
|
313072
313573
|
}
|
|
313073
313574
|
try {
|
|
313074
|
-
|
|
313575
|
+
execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
313075
313576
|
} catch {
|
|
313076
313577
|
}
|
|
313077
313578
|
const oaPath = join85(repoRoot, OA_DIR);
|
|
@@ -313085,14 +313586,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313085
313586
|
} catch (err) {
|
|
313086
313587
|
if (attempt < 2) {
|
|
313087
313588
|
try {
|
|
313088
|
-
|
|
313589
|
+
execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
313089
313590
|
} catch {
|
|
313090
313591
|
}
|
|
313091
313592
|
} else {
|
|
313092
313593
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
313093
313594
|
if (process.platform === "win32") {
|
|
313094
313595
|
try {
|
|
313095
|
-
|
|
313596
|
+
execSync47(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
313096
313597
|
deleted = true;
|
|
313097
313598
|
} catch {
|
|
313098
313599
|
}
|