open-agents-ai 0.187.137 → 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 +686 -189
- 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" },
|
|
@@ -254888,6 +254888,497 @@ ${devices.join("\n")}`,
|
|
|
254888
254888
|
}
|
|
254889
254889
|
});
|
|
254890
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
|
+
|
|
254891
255382
|
// packages/execution/dist/tools/full-sub-agent.js
|
|
254892
255383
|
import { spawn as spawn13, ChildProcess } from "node:child_process";
|
|
254893
255384
|
import { randomBytes as randomBytes13 } from "node:crypto";
|
|
@@ -255332,7 +255823,7 @@ var init_agent_tool = __esm({
|
|
|
255332
255823
|
});
|
|
255333
255824
|
|
|
255334
255825
|
// packages/execution/dist/tools/worktree.js
|
|
255335
|
-
import { execSync as
|
|
255826
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
255336
255827
|
import { existsSync as existsSync31, mkdirSync as mkdirSync12, rmSync } from "node:fs";
|
|
255337
255828
|
import { join as join46, resolve as resolve30 } from "node:path";
|
|
255338
255829
|
function validateSlug(slug) {
|
|
@@ -255351,7 +255842,7 @@ function flattenSlug(slug) {
|
|
|
255351
255842
|
}
|
|
255352
255843
|
function isGitRepo(cwd4) {
|
|
255353
255844
|
try {
|
|
255354
|
-
|
|
255845
|
+
execSync32("git rev-parse --is-inside-work-tree", { cwd: cwd4, stdio: "pipe" });
|
|
255355
255846
|
return true;
|
|
255356
255847
|
} catch {
|
|
255357
255848
|
return false;
|
|
@@ -255359,14 +255850,14 @@ function isGitRepo(cwd4) {
|
|
|
255359
255850
|
}
|
|
255360
255851
|
function getCurrentBranch(cwd4) {
|
|
255361
255852
|
try {
|
|
255362
|
-
return
|
|
255853
|
+
return execSync32("git rev-parse --abbrev-ref HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
255363
255854
|
} catch {
|
|
255364
255855
|
return void 0;
|
|
255365
255856
|
}
|
|
255366
255857
|
}
|
|
255367
255858
|
function getCurrentCommit(cwd4) {
|
|
255368
255859
|
try {
|
|
255369
|
-
return
|
|
255860
|
+
return execSync32("git rev-parse --short HEAD", { cwd: cwd4, stdio: "pipe" }).toString().trim();
|
|
255370
255861
|
} catch {
|
|
255371
255862
|
return void 0;
|
|
255372
255863
|
}
|
|
@@ -255397,13 +255888,13 @@ function createWorktree(repoRoot, slug) {
|
|
|
255397
255888
|
}
|
|
255398
255889
|
mkdirSync12(worktreeBase, { recursive: true });
|
|
255399
255890
|
try {
|
|
255400
|
-
|
|
255891
|
+
execSync32(`git worktree add "${worktreePath}" -b "${branchName}"`, {
|
|
255401
255892
|
cwd: repoRoot,
|
|
255402
255893
|
stdio: "pipe"
|
|
255403
255894
|
});
|
|
255404
255895
|
} catch (err) {
|
|
255405
255896
|
try {
|
|
255406
|
-
|
|
255897
|
+
execSync32(`git worktree add "${worktreePath}" "${branchName}"`, {
|
|
255407
255898
|
cwd: repoRoot,
|
|
255408
255899
|
stdio: "pipe"
|
|
255409
255900
|
});
|
|
@@ -255425,7 +255916,7 @@ function createWorktree(repoRoot, slug) {
|
|
|
255425
255916
|
}
|
|
255426
255917
|
function worktreeHasChanges(worktreePath) {
|
|
255427
255918
|
try {
|
|
255428
|
-
const status =
|
|
255919
|
+
const status = execSync32("git status --porcelain", {
|
|
255429
255920
|
cwd: worktreePath,
|
|
255430
255921
|
stdio: "pipe"
|
|
255431
255922
|
}).toString().trim();
|
|
@@ -255446,20 +255937,20 @@ function removeWorktree(repoRoot, slug, force = false) {
|
|
|
255446
255937
|
return "Worktree has uncommitted changes. Use force=true to discard, or commit/stash first.";
|
|
255447
255938
|
}
|
|
255448
255939
|
try {
|
|
255449
|
-
|
|
255940
|
+
execSync32(`git worktree remove "${worktreePath}" ${force ? "--force" : ""}`, {
|
|
255450
255941
|
cwd: repoRoot,
|
|
255451
255942
|
stdio: "pipe"
|
|
255452
255943
|
});
|
|
255453
255944
|
} catch (err) {
|
|
255454
255945
|
try {
|
|
255455
255946
|
rmSync(worktreePath, { recursive: true, force: true });
|
|
255456
|
-
|
|
255947
|
+
execSync32("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
|
|
255457
255948
|
} catch {
|
|
255458
255949
|
return `Failed to remove worktree: ${err}`;
|
|
255459
255950
|
}
|
|
255460
255951
|
}
|
|
255461
255952
|
try {
|
|
255462
|
-
|
|
255953
|
+
execSync32(`git branch -D "${branchName}"`, { cwd: repoRoot, stdio: "pipe" });
|
|
255463
255954
|
} catch {
|
|
255464
255955
|
}
|
|
255465
255956
|
_sessions.delete(slug);
|
|
@@ -256736,7 +257227,7 @@ var init_notebook_edit = __esm({
|
|
|
256736
257227
|
});
|
|
256737
257228
|
|
|
256738
257229
|
// packages/execution/dist/tools/environment-snapshot.js
|
|
256739
|
-
import { execSync as
|
|
257230
|
+
import { execSync as execSync33 } from "node:child_process";
|
|
256740
257231
|
import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
|
|
256741
257232
|
import { statfsSync } from "node:fs";
|
|
256742
257233
|
function collectSnapshot(workingDir) {
|
|
@@ -256754,7 +257245,7 @@ function collectSnapshot(workingDir) {
|
|
|
256754
257245
|
}
|
|
256755
257246
|
let gpu = void 0;
|
|
256756
257247
|
try {
|
|
256757
|
-
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());
|
|
256758
257249
|
if (nvOut.length >= 3) {
|
|
256759
257250
|
gpu = {
|
|
256760
257251
|
name: nvOut[0],
|
|
@@ -256769,12 +257260,12 @@ function collectSnapshot(workingDir) {
|
|
|
256769
257260
|
let battery = void 0;
|
|
256770
257261
|
try {
|
|
256771
257262
|
if (platform() === "linux") {
|
|
256772
|
-
const cap =
|
|
256773
|
-
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();
|
|
256774
257265
|
if (cap)
|
|
256775
257266
|
battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
|
|
256776
257267
|
} else if (platform() === "darwin") {
|
|
256777
|
-
const pmOut =
|
|
257268
|
+
const pmOut = execSync33("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
|
|
256778
257269
|
const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
|
|
256779
257270
|
if (match)
|
|
256780
257271
|
battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
|
|
@@ -256795,8 +257286,8 @@ function collectSnapshot(workingDir) {
|
|
|
256795
257286
|
}
|
|
256796
257287
|
let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
|
|
256797
257288
|
try {
|
|
256798
|
-
const psLines =
|
|
256799
|
-
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);
|
|
256800
257291
|
let nodeCount = 0;
|
|
256801
257292
|
let oaSpawned = 0;
|
|
256802
257293
|
const topCpu = [];
|
|
@@ -256877,7 +257368,7 @@ var init_environment_snapshot = __esm({
|
|
|
256877
257368
|
});
|
|
256878
257369
|
|
|
256879
257370
|
// packages/execution/dist/tools/video-understand.js
|
|
256880
|
-
import { execSync as
|
|
257371
|
+
import { execSync as execSync34 } from "node:child_process";
|
|
256881
257372
|
import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync26, readdirSync as readdirSync8, unlinkSync as unlinkSync7 } from "node:fs";
|
|
256882
257373
|
import { join as join49, basename as basename11 } from "node:path";
|
|
256883
257374
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -256886,11 +257377,11 @@ function isYouTubeUrl2(url) {
|
|
|
256886
257377
|
}
|
|
256887
257378
|
function ensureYtDlp2() {
|
|
256888
257379
|
try {
|
|
256889
|
-
|
|
257380
|
+
execSync34("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
256890
257381
|
return true;
|
|
256891
257382
|
} catch {
|
|
256892
257383
|
try {
|
|
256893
|
-
|
|
257384
|
+
execSync34("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
256894
257385
|
return true;
|
|
256895
257386
|
} catch {
|
|
256896
257387
|
return false;
|
|
@@ -256899,7 +257390,7 @@ function ensureYtDlp2() {
|
|
|
256899
257390
|
}
|
|
256900
257391
|
function ensureFfmpeg() {
|
|
256901
257392
|
try {
|
|
256902
|
-
|
|
257393
|
+
execSync34("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
256903
257394
|
return true;
|
|
256904
257395
|
} catch {
|
|
256905
257396
|
return false;
|
|
@@ -256979,32 +257470,32 @@ var init_video_understand = __esm({
|
|
|
256979
257470
|
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start2 };
|
|
256980
257471
|
}
|
|
256981
257472
|
try {
|
|
256982
|
-
|
|
257473
|
+
execSync34(`yt-dlp -f "worst[ext=mp4]" -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256983
257474
|
} catch {
|
|
256984
|
-
|
|
257475
|
+
execSync34(`yt-dlp -f worst -o "${join49(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256985
257476
|
}
|
|
256986
|
-
|
|
257477
|
+
execSync34(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join49(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
256987
257478
|
try {
|
|
256988
|
-
title =
|
|
257479
|
+
title = execSync34(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
256989
257480
|
} catch {
|
|
256990
257481
|
}
|
|
256991
257482
|
} else {
|
|
256992
|
-
|
|
256993
|
-
|
|
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" });
|
|
256994
257485
|
}
|
|
256995
257486
|
videoPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("video")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("video"))) : join49(tmpDir, "video.mp4");
|
|
256996
257487
|
audioPath = readdirSync8(tmpDir).find((f2) => f2.startsWith("audio")) ? join49(tmpDir, readdirSync8(tmpDir).find((f2) => f2.startsWith("audio"))) : join49(tmpDir, "audio.mp3");
|
|
256997
257488
|
} else {
|
|
256998
257489
|
videoPath = localPath;
|
|
256999
257490
|
audioPath = join49(tmpDir, "audio.mp3");
|
|
257000
|
-
|
|
257491
|
+
execSync34(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
257001
257492
|
}
|
|
257002
257493
|
let segments = [];
|
|
257003
257494
|
let language = "en";
|
|
257004
257495
|
let duration = 0;
|
|
257005
257496
|
try {
|
|
257006
257497
|
const jsonOut = join49(tmpDir, "transcript.json");
|
|
257007
|
-
|
|
257498
|
+
execSync34(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
257008
257499
|
const jsonFile = readdirSync8(tmpDir).find((f2) => f2.endsWith(".json") && f2 !== "result.json");
|
|
257009
257500
|
if (jsonFile) {
|
|
257010
257501
|
const data = JSON.parse(readFileSync26(join49(tmpDir, jsonFile), "utf-8"));
|
|
@@ -257027,7 +257518,7 @@ var init_video_understand = __esm({
|
|
|
257027
257518
|
const fps = 25;
|
|
257028
257519
|
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
257029
257520
|
try {
|
|
257030
|
-
|
|
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" });
|
|
257031
257522
|
} catch {
|
|
257032
257523
|
}
|
|
257033
257524
|
const frameFiles = readdirSync8(framesDir).filter((f2) => f2.endsWith(".jpg")).sort();
|
|
@@ -257160,7 +257651,7 @@ Topic: ${segments.slice(0, 5).map((s2) => s2.text).join(" ").slice(0, 300)}`,
|
|
|
257160
257651
|
}
|
|
257161
257652
|
}
|
|
257162
257653
|
try {
|
|
257163
|
-
|
|
257654
|
+
execSync34(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
257164
257655
|
} catch {
|
|
257165
257656
|
}
|
|
257166
257657
|
return {
|
|
@@ -258054,6 +258545,7 @@ __export(dist_exports, {
|
|
|
258054
258545
|
BackgroundRunTool: () => BackgroundRunTool,
|
|
258055
258546
|
BackgroundTaskManager: () => BackgroundTaskManager,
|
|
258056
258547
|
BatchEditTool: () => BatchEditTool,
|
|
258548
|
+
BluetoothScanTool: () => BluetoothScanTool,
|
|
258057
258549
|
BrowserActionTool: () => BrowserActionTool,
|
|
258058
258550
|
CameraCaptureTool: () => CameraCaptureTool,
|
|
258059
258551
|
CodeSandboxTool: () => CodeSandboxTool,
|
|
@@ -258129,6 +258621,7 @@ __export(dist_exports, {
|
|
|
258129
258621
|
WebCrawlTool: () => WebCrawlTool,
|
|
258130
258622
|
WebFetchTool: () => WebFetchTool,
|
|
258131
258623
|
WebSearchTool: () => WebSearchTool,
|
|
258624
|
+
WifiControlTool: () => WifiControlTool,
|
|
258132
258625
|
WorkingNotesTool: () => WorkingNotesTool,
|
|
258133
258626
|
YouTubeDownloadTool: () => YouTubeDownloadTool,
|
|
258134
258627
|
addProjectConstraint: () => addProjectConstraint,
|
|
@@ -258290,6 +258783,8 @@ var init_dist4 = __esm({
|
|
|
258290
258783
|
init_camera_capture();
|
|
258291
258784
|
init_audio_capture();
|
|
258292
258785
|
init_audio_playback();
|
|
258786
|
+
init_wifi_control();
|
|
258787
|
+
init_bluetooth_scan();
|
|
258293
258788
|
init_system_auth();
|
|
258294
258789
|
init_full_sub_agent();
|
|
258295
258790
|
init_agent_tool();
|
|
@@ -261194,12 +261689,12 @@ var init_tool_batching = __esm({
|
|
|
261194
261689
|
});
|
|
261195
261690
|
|
|
261196
261691
|
// packages/orchestrator/dist/hooks.js
|
|
261197
|
-
import { execSync as
|
|
261692
|
+
import { execSync as execSync35 } from "node:child_process";
|
|
261198
261693
|
function executeHook(hook, env2 = {}) {
|
|
261199
261694
|
const start2 = performance.now();
|
|
261200
261695
|
const timeout2 = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT;
|
|
261201
261696
|
try {
|
|
261202
|
-
const output =
|
|
261697
|
+
const output = execSync35(hook.command, {
|
|
261203
261698
|
timeout: timeout2,
|
|
261204
261699
|
env: { ...process.env, ...env2 },
|
|
261205
261700
|
encoding: "utf8",
|
|
@@ -265423,7 +265918,7 @@ ${result}`
|
|
|
265423
265918
|
const buffer2 = Buffer.from(rawBase64, "base64");
|
|
265424
265919
|
let resizedBase64 = null;
|
|
265425
265920
|
try {
|
|
265426
|
-
const { execSync:
|
|
265921
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
265427
265922
|
const { writeFileSync: writeFileSync38, readFileSync: readFileSync56, unlinkSync: unlinkSync17 } = await import("node:fs");
|
|
265428
265923
|
const { join: join91 } = await import("node:path");
|
|
265429
265924
|
const { tmpdir: tmpdir14 } = await import("node:os");
|
|
@@ -265433,7 +265928,7 @@ ${result}`
|
|
|
265433
265928
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
265434
265929
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
265435
265930
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
265436
|
-
|
|
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" });
|
|
265437
265932
|
const resizedBuf = readFileSync56(tmpOut);
|
|
265438
265933
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
265439
265934
|
try {
|
|
@@ -265487,8 +265982,8 @@ ${result}`
|
|
|
265487
265982
|
if (!res.ok && model === "moondream" && res.status === 404) {
|
|
265488
265983
|
this.emit({ type: "status", content: `Pulling moondream vision model...`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
265489
265984
|
try {
|
|
265490
|
-
const { execSync:
|
|
265491
|
-
|
|
265985
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
265986
|
+
execSync48("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
265492
265987
|
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
265493
265988
|
method: "POST",
|
|
265494
265989
|
headers: { "Content-Type": "application/json" },
|
|
@@ -267852,7 +268347,7 @@ __export(listen_exports, {
|
|
|
267852
268347
|
isVideoPath: () => isVideoPath,
|
|
267853
268348
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
267854
268349
|
});
|
|
267855
|
-
import { spawn as spawn17, execSync as
|
|
268350
|
+
import { spawn as spawn17, execSync as execSync36 } from "node:child_process";
|
|
267856
268351
|
import { existsSync as existsSync41, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readdirSync as readdirSync9 } from "node:fs";
|
|
267857
268352
|
import { join as join57, dirname as dirname16 } from "node:path";
|
|
267858
268353
|
import { homedir as homedir15 } from "node:os";
|
|
@@ -267874,7 +268369,7 @@ function findMicCaptureCommand() {
|
|
|
267874
268369
|
const platform6 = process.platform;
|
|
267875
268370
|
if (platform6 === "linux") {
|
|
267876
268371
|
try {
|
|
267877
|
-
|
|
268372
|
+
execSync36("which arecord", { stdio: "pipe" });
|
|
267878
268373
|
return {
|
|
267879
268374
|
cmd: "arecord",
|
|
267880
268375
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -267884,7 +268379,7 @@ function findMicCaptureCommand() {
|
|
|
267884
268379
|
}
|
|
267885
268380
|
if (platform6 === "darwin") {
|
|
267886
268381
|
try {
|
|
267887
|
-
|
|
268382
|
+
execSync36("which sox", { stdio: "pipe" });
|
|
267888
268383
|
return {
|
|
267889
268384
|
cmd: "sox",
|
|
267890
268385
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -267893,7 +268388,7 @@ function findMicCaptureCommand() {
|
|
|
267893
268388
|
}
|
|
267894
268389
|
}
|
|
267895
268390
|
try {
|
|
267896
|
-
|
|
268391
|
+
execSync36("which ffmpeg", { stdio: "pipe" });
|
|
267897
268392
|
if (platform6 === "linux") {
|
|
267898
268393
|
return {
|
|
267899
268394
|
cmd: "ffmpeg",
|
|
@@ -267951,7 +268446,7 @@ function findLiveWhisperScript() {
|
|
|
267951
268446
|
if (existsSync41(p2)) return p2;
|
|
267952
268447
|
}
|
|
267953
268448
|
try {
|
|
267954
|
-
const globalRoot =
|
|
268449
|
+
const globalRoot = execSync36("npm root -g", {
|
|
267955
268450
|
encoding: "utf-8",
|
|
267956
268451
|
timeout: 5e3,
|
|
267957
268452
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -267981,7 +268476,7 @@ function ensureTranscribeCliBackground() {
|
|
|
267981
268476
|
if (_bgInstallPromise) return;
|
|
267982
268477
|
_bgInstallPromise = (async () => {
|
|
267983
268478
|
try {
|
|
267984
|
-
const globalRoot =
|
|
268479
|
+
const globalRoot = execSync36("npm root -g", {
|
|
267985
268480
|
encoding: "utf-8",
|
|
267986
268481
|
timeout: 5e3,
|
|
267987
268482
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268183,7 +268678,7 @@ var init_listen = __esm({
|
|
|
268183
268678
|
}
|
|
268184
268679
|
if (!this.transcribeCliAvailable) {
|
|
268185
268680
|
try {
|
|
268186
|
-
|
|
268681
|
+
execSync36("which transcribe-cli", { stdio: "pipe" });
|
|
268187
268682
|
this.transcribeCliAvailable = true;
|
|
268188
268683
|
} catch {
|
|
268189
268684
|
this.transcribeCliAvailable = false;
|
|
@@ -268200,7 +268695,7 @@ var init_listen = __esm({
|
|
|
268200
268695
|
} catch {
|
|
268201
268696
|
}
|
|
268202
268697
|
try {
|
|
268203
|
-
const globalRoot =
|
|
268698
|
+
const globalRoot = execSync36("npm root -g", {
|
|
268204
268699
|
encoding: "utf-8",
|
|
268205
268700
|
timeout: 5e3,
|
|
268206
268701
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -268249,7 +268744,7 @@ var init_listen = __esm({
|
|
|
268249
268744
|
}
|
|
268250
268745
|
if (!tc) {
|
|
268251
268746
|
try {
|
|
268252
|
-
|
|
268747
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268253
268748
|
this.transcribeCliAvailable = null;
|
|
268254
268749
|
tc = await this.loadTranscribeCli();
|
|
268255
268750
|
} catch {
|
|
@@ -268427,7 +268922,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
268427
268922
|
}
|
|
268428
268923
|
if (!tc) {
|
|
268429
268924
|
try {
|
|
268430
|
-
|
|
268925
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268431
268926
|
this.transcribeCliAvailable = null;
|
|
268432
268927
|
tc = await this.loadTranscribeCli();
|
|
268433
268928
|
} catch {
|
|
@@ -268480,7 +268975,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
268480
268975
|
}
|
|
268481
268976
|
if (!tc) {
|
|
268482
268977
|
try {
|
|
268483
|
-
|
|
268978
|
+
execSync36("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
268484
268979
|
this.transcribeCliAvailable = null;
|
|
268485
268980
|
tc = await this.loadTranscribeCli();
|
|
268486
268981
|
} catch {
|
|
@@ -273402,7 +273897,7 @@ var init_render = __esm({
|
|
|
273402
273897
|
|
|
273403
273898
|
// packages/cli/src/tui/voice-session.ts
|
|
273404
273899
|
import { createServer as createServer3 } from "node:http";
|
|
273405
|
-
import { spawn as spawn18, execSync as
|
|
273900
|
+
import { spawn as spawn18, execSync as execSync37 } from "node:child_process";
|
|
273406
273901
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
273407
273902
|
function generateFrontendHTML() {
|
|
273408
273903
|
return `<!DOCTYPE html>
|
|
@@ -279271,7 +279766,7 @@ __export(text_selection_exports, {
|
|
|
279271
279766
|
stripAnsi: () => stripAnsi,
|
|
279272
279767
|
visibleLength: () => visibleLength
|
|
279273
279768
|
});
|
|
279274
|
-
import { execSync as
|
|
279769
|
+
import { execSync as execSync38 } from "node:child_process";
|
|
279275
279770
|
function stripAnsi(s2) {
|
|
279276
279771
|
return s2.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
279277
279772
|
}
|
|
@@ -279282,16 +279777,16 @@ function copyText(text) {
|
|
|
279282
279777
|
try {
|
|
279283
279778
|
const platform6 = process.platform;
|
|
279284
279779
|
if (platform6 === "darwin") {
|
|
279285
|
-
|
|
279780
|
+
execSync38("pbcopy", { input: text, timeout: 3e3 });
|
|
279286
279781
|
return true;
|
|
279287
279782
|
}
|
|
279288
279783
|
if (platform6 === "win32") {
|
|
279289
|
-
|
|
279784
|
+
execSync38("clip", { input: text, timeout: 3e3 });
|
|
279290
279785
|
return true;
|
|
279291
279786
|
}
|
|
279292
279787
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
279293
279788
|
try {
|
|
279294
|
-
|
|
279789
|
+
execSync38(tool, { input: text, timeout: 3e3 });
|
|
279295
279790
|
return true;
|
|
279296
279791
|
} catch {
|
|
279297
279792
|
continue;
|
|
@@ -279300,10 +279795,10 @@ function copyText(text) {
|
|
|
279300
279795
|
if (!_clipboardAutoInstallAttempted) {
|
|
279301
279796
|
_clipboardAutoInstallAttempted = true;
|
|
279302
279797
|
try {
|
|
279303
|
-
|
|
279798
|
+
execSync38("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
279304
279799
|
try {
|
|
279305
|
-
|
|
279306
|
-
|
|
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 });
|
|
279307
279802
|
return true;
|
|
279308
279803
|
} catch {
|
|
279309
279804
|
}
|
|
@@ -283181,7 +283676,7 @@ __export(personaplex_exports, {
|
|
|
283181
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";
|
|
283182
283677
|
import { join as join63, dirname as dirname20 } from "node:path";
|
|
283183
283678
|
import { homedir as homedir17 } from "node:os";
|
|
283184
|
-
import { execSync as
|
|
283679
|
+
import { execSync as execSync39, spawn as spawn20 } from "node:child_process";
|
|
283185
283680
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
283186
283681
|
function execAsync(cmd, opts = {}) {
|
|
283187
283682
|
return new Promise((resolve39, reject) => {
|
|
@@ -283214,7 +283709,7 @@ function detectJetson() {
|
|
|
283214
283709
|
try {
|
|
283215
283710
|
const model = readFileSync36("/proc/device-tree/model", "utf8").replace(/\0/g, "").trim();
|
|
283216
283711
|
if (/jetson|orin|tegra/i.test(model)) {
|
|
283217
|
-
const memInfo =
|
|
283712
|
+
const memInfo = execSync39("grep MemTotal /proc/meminfo", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
283218
283713
|
const memKB = parseInt(memInfo.match(/(\d+)/)?.[1] ?? "0", 10);
|
|
283219
283714
|
return { isJetson: true, model, totalMemGB: memKB / 1024 / 1024 };
|
|
283220
283715
|
}
|
|
@@ -283248,7 +283743,7 @@ function detectPersonaPlexCapability() {
|
|
|
283248
283743
|
};
|
|
283249
283744
|
}
|
|
283250
283745
|
try {
|
|
283251
|
-
const nvsmi =
|
|
283746
|
+
const nvsmi = execSync39("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
|
|
283252
283747
|
encoding: "utf8",
|
|
283253
283748
|
timeout: 5e3,
|
|
283254
283749
|
stdio: "pipe"
|
|
@@ -283260,7 +283755,7 @@ function detectPersonaPlexCapability() {
|
|
|
283260
283755
|
return { ...fail2(`GPU has ${vramGB.toFixed(1)}GB VRAM (need \u22658GB)`), gpuName: gpuName ?? "", vramGB };
|
|
283261
283756
|
}
|
|
283262
283757
|
try {
|
|
283263
|
-
|
|
283758
|
+
execSync39('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
283264
283759
|
timeout: 1e4,
|
|
283265
283760
|
stdio: "pipe"
|
|
283266
283761
|
});
|
|
@@ -283333,7 +283828,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283333
283828
|
mkdirSync20(PERSONAPLEX_DIR, { recursive: true });
|
|
283334
283829
|
let arch2 = "";
|
|
283335
283830
|
try {
|
|
283336
|
-
arch2 =
|
|
283831
|
+
arch2 = execSync39("uname -m", { encoding: "utf8", timeout: 3e3, stdio: "pipe" }).trim();
|
|
283337
283832
|
} catch {
|
|
283338
283833
|
}
|
|
283339
283834
|
const isAarch64 = arch2 === "aarch64" || arch2 === "arm64";
|
|
@@ -283354,16 +283849,16 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283354
283849
|
log22("Checking system dependencies (libopus)...");
|
|
283355
283850
|
try {
|
|
283356
283851
|
if (process.platform === "linux") {
|
|
283357
|
-
|
|
283852
|
+
execSync39("dpkg -l libopus-dev 2>/dev/null || sudo apt-get install -y libopus-dev", { timeout: 3e4, stdio: "pipe" });
|
|
283358
283853
|
} else if (process.platform === "darwin") {
|
|
283359
|
-
|
|
283854
|
+
execSync39("brew list opus 2>/dev/null || brew install opus", { timeout: 6e4, stdio: "pipe" });
|
|
283360
283855
|
}
|
|
283361
283856
|
} catch {
|
|
283362
283857
|
}
|
|
283363
283858
|
if (isAarch64) {
|
|
283364
283859
|
log22("ARM64: Checking Rust toolchain for sphn build...");
|
|
283365
283860
|
try {
|
|
283366
|
-
|
|
283861
|
+
execSync39("rustc --version", { timeout: 5e3, stdio: "pipe" });
|
|
283367
283862
|
} catch {
|
|
283368
283863
|
log22("ARM64: Installing Rust toolchain (needed for sphn audio codec)...");
|
|
283369
283864
|
try {
|
|
@@ -283436,7 +283931,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283436
283931
|
}
|
|
283437
283932
|
const serverPy = join63(venvDir, "lib", `python3.${process.versions.node ? "12" : "10"}`, "site-packages", "moshi", "server.py");
|
|
283438
283933
|
try {
|
|
283439
|
-
const sitePackages =
|
|
283934
|
+
const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283440
283935
|
encoding: "utf8",
|
|
283441
283936
|
timeout: 5e3,
|
|
283442
283937
|
stdio: "pipe"
|
|
@@ -283453,7 +283948,7 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
283453
283948
|
} catch {
|
|
283454
283949
|
}
|
|
283455
283950
|
try {
|
|
283456
|
-
const sitePackages =
|
|
283951
|
+
const sitePackages = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283457
283952
|
encoding: "utf8",
|
|
283458
283953
|
timeout: 5e3,
|
|
283459
283954
|
stdio: "pipe"
|
|
@@ -283557,7 +284052,7 @@ $2if filename.endswith(".safetensors"):`
|
|
|
283557
284052
|
} catch {
|
|
283558
284053
|
}
|
|
283559
284054
|
try {
|
|
283560
|
-
const sitePackages2 =
|
|
284055
|
+
const sitePackages2 = execSync39(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
283561
284056
|
encoding: "utf8",
|
|
283562
284057
|
timeout: 5e3,
|
|
283563
284058
|
stdio: "pipe"
|
|
@@ -283692,14 +284187,14 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
283692
284187
|
if (tier === "nf4-distilled") {
|
|
283693
284188
|
log22(`Weight tier: ${tier} \u2014 distilled NF4 (90% token match, ${repoInfo.sizeGB}GB)...`);
|
|
283694
284189
|
try {
|
|
283695
|
-
const weightPath =
|
|
284190
|
+
const weightPath = execSync39(
|
|
283696
284191
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
283697
284192
|
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
283698
284193
|
).trim();
|
|
283699
284194
|
if (existsSync46(weightPath)) {
|
|
283700
284195
|
if (!existsSync46(cachedBf16)) {
|
|
283701
284196
|
log22("Converting .pt checkpoint to safetensors (one-time)...");
|
|
283702
|
-
|
|
284197
|
+
execSync39(
|
|
283703
284198
|
`"${venvPython2}" -c "
|
|
283704
284199
|
import torch; from safetensors.torch import save_file
|
|
283705
284200
|
state = torch.load('${weightPath}', map_location='cpu', weights_only=True)
|
|
@@ -283731,13 +284226,13 @@ print('Converted')
|
|
|
283731
284226
|
}
|
|
283732
284227
|
}
|
|
283733
284228
|
try {
|
|
283734
|
-
const weightPath =
|
|
284229
|
+
const weightPath = execSync39(
|
|
283735
284230
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
283736
284231
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283737
284232
|
).trim();
|
|
283738
284233
|
if (existsSync46(dequantScript) && existsSync46(weightPath)) {
|
|
283739
284234
|
try {
|
|
283740
|
-
|
|
284235
|
+
execSync39(
|
|
283741
284236
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
283742
284237
|
{ timeout: 3e5, stdio: "pipe" }
|
|
283743
284238
|
);
|
|
@@ -283750,7 +284245,7 @@ print('Converted')
|
|
|
283750
284245
|
}
|
|
283751
284246
|
}
|
|
283752
284247
|
try {
|
|
283753
|
-
const mimiPath =
|
|
284248
|
+
const mimiPath = execSync39(
|
|
283754
284249
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
283755
284250
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283756
284251
|
).trim();
|
|
@@ -283758,7 +284253,7 @@ print('Converted')
|
|
|
283758
284253
|
} catch {
|
|
283759
284254
|
}
|
|
283760
284255
|
try {
|
|
283761
|
-
const tokPath =
|
|
284256
|
+
const tokPath = execSync39(
|
|
283762
284257
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
283763
284258
|
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
283764
284259
|
).trim();
|
|
@@ -283782,7 +284277,7 @@ print('Converted')
|
|
|
283782
284277
|
}
|
|
283783
284278
|
if (!ollamaModel) ollamaModel = "qwen3.5:4b";
|
|
283784
284279
|
try {
|
|
283785
|
-
const ollamaCheck =
|
|
284280
|
+
const ollamaCheck = execSync39("curl -s http://localhost:11434/api/tags", {
|
|
283786
284281
|
timeout: 3e3,
|
|
283787
284282
|
stdio: "pipe",
|
|
283788
284283
|
encoding: "utf8"
|
|
@@ -283856,7 +284351,7 @@ print('Converted')
|
|
|
283856
284351
|
return null;
|
|
283857
284352
|
}
|
|
283858
284353
|
try {
|
|
283859
|
-
|
|
284354
|
+
execSync39(`curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:${PORT}/`, {
|
|
283860
284355
|
timeout: 3e3,
|
|
283861
284356
|
stdio: "pipe",
|
|
283862
284357
|
encoding: "utf8"
|
|
@@ -283879,7 +284374,7 @@ function stopPersonaPlex() {
|
|
|
283879
284374
|
if (isNaN(pid) || pid <= 0) return;
|
|
283880
284375
|
try {
|
|
283881
284376
|
if (process.platform === "win32") {
|
|
283882
|
-
|
|
284377
|
+
execSync39(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
283883
284378
|
} else {
|
|
283884
284379
|
process.kill(pid, "SIGTERM");
|
|
283885
284380
|
}
|
|
@@ -284183,7 +284678,7 @@ __export(setup_exports, {
|
|
|
284183
284678
|
updateOllama: () => updateOllama
|
|
284184
284679
|
});
|
|
284185
284680
|
import * as readline from "node:readline";
|
|
284186
|
-
import { execSync as
|
|
284681
|
+
import { execSync as execSync40, spawn as spawn21, exec as exec4 } from "node:child_process";
|
|
284187
284682
|
import { promisify as promisify7 } from "node:util";
|
|
284188
284683
|
import { existsSync as existsSync47, writeFileSync as writeFileSync22, readFileSync as readFileSync37, appendFileSync as appendFileSync2, mkdirSync as mkdirSync21 } from "node:fs";
|
|
284189
284684
|
import { join as join64 } from "node:path";
|
|
@@ -284221,7 +284716,7 @@ function detectSystemSpecs() {
|
|
|
284221
284716
|
let gpuVramGB = 0;
|
|
284222
284717
|
let gpuName = "";
|
|
284223
284718
|
try {
|
|
284224
|
-
const memInfo =
|
|
284719
|
+
const memInfo = execSync40("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
284225
284720
|
encoding: "utf8",
|
|
284226
284721
|
timeout: 5e3
|
|
284227
284722
|
});
|
|
@@ -284241,7 +284736,7 @@ function detectSystemSpecs() {
|
|
|
284241
284736
|
} catch {
|
|
284242
284737
|
}
|
|
284243
284738
|
try {
|
|
284244
|
-
const nvidiaSmi =
|
|
284739
|
+
const nvidiaSmi = execSync40(
|
|
284245
284740
|
"nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null",
|
|
284246
284741
|
{ encoding: "utf8", timeout: 5e3 }
|
|
284247
284742
|
);
|
|
@@ -284415,7 +284910,7 @@ function ensureCurl() {
|
|
|
284415
284910
|
for (const s2 of strategies) {
|
|
284416
284911
|
if (hasCmd(s2.check)) {
|
|
284417
284912
|
try {
|
|
284418
|
-
|
|
284913
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284419
284914
|
if (hasCmd("curl")) {
|
|
284420
284915
|
process.stdout.write(` ${c3.green("\u2714")} curl installed via ${s2.label}.
|
|
284421
284916
|
`);
|
|
@@ -284429,7 +284924,7 @@ function ensureCurl() {
|
|
|
284429
284924
|
}
|
|
284430
284925
|
if (plat === "darwin") {
|
|
284431
284926
|
try {
|
|
284432
|
-
|
|
284927
|
+
execSync40("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
284433
284928
|
if (hasCmd("curl")) return true;
|
|
284434
284929
|
} catch {
|
|
284435
284930
|
}
|
|
@@ -284463,7 +284958,7 @@ function installOllamaLinux() {
|
|
|
284463
284958
|
|
|
284464
284959
|
`);
|
|
284465
284960
|
try {
|
|
284466
|
-
|
|
284961
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284467
284962
|
stdio: "inherit",
|
|
284468
284963
|
timeout: 3e5
|
|
284469
284964
|
});
|
|
@@ -284491,7 +284986,7 @@ async function installOllamaMac(_rl) {
|
|
|
284491
284986
|
|
|
284492
284987
|
`);
|
|
284493
284988
|
try {
|
|
284494
|
-
|
|
284989
|
+
execSync40(
|
|
284495
284990
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
284496
284991
|
{ stdio: "inherit", timeout: 6e5 }
|
|
284497
284992
|
);
|
|
@@ -284527,7 +285022,7 @@ async function installOllamaMac(_rl) {
|
|
|
284527
285022
|
|
|
284528
285023
|
`);
|
|
284529
285024
|
try {
|
|
284530
|
-
|
|
285025
|
+
execSync40("brew install ollama", {
|
|
284531
285026
|
stdio: "inherit",
|
|
284532
285027
|
timeout: 3e5
|
|
284533
285028
|
});
|
|
@@ -284554,7 +285049,7 @@ function installOllamaWindows() {
|
|
|
284554
285049
|
|
|
284555
285050
|
`);
|
|
284556
285051
|
try {
|
|
284557
|
-
|
|
285052
|
+
execSync40('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
284558
285053
|
stdio: "inherit",
|
|
284559
285054
|
timeout: 3e5
|
|
284560
285055
|
});
|
|
@@ -284634,7 +285129,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
284634
285129
|
}
|
|
284635
285130
|
function getOllamaVersion() {
|
|
284636
285131
|
try {
|
|
284637
|
-
const out =
|
|
285132
|
+
const out = execSync40("ollama --version", { encoding: "utf8", timeout: 5e3 });
|
|
284638
285133
|
const match = out.match(/(\d+\.\d+\.\d+)/);
|
|
284639
285134
|
return match ? match[1] : null;
|
|
284640
285135
|
} catch {
|
|
@@ -284680,7 +285175,7 @@ function updateOllama() {
|
|
|
284680
285175
|
return false;
|
|
284681
285176
|
}
|
|
284682
285177
|
try {
|
|
284683
|
-
|
|
285178
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284684
285179
|
stdio: "inherit",
|
|
284685
285180
|
timeout: 3e5
|
|
284686
285181
|
});
|
|
@@ -284691,7 +285186,7 @@ function updateOllama() {
|
|
|
284691
285186
|
}
|
|
284692
285187
|
function pullModelWithAutoUpdate(tag) {
|
|
284693
285188
|
try {
|
|
284694
|
-
|
|
285189
|
+
execSync40(`ollama pull ${tag}`, {
|
|
284695
285190
|
stdio: "inherit",
|
|
284696
285191
|
timeout: 36e5
|
|
284697
285192
|
// 1 hour max
|
|
@@ -284711,7 +285206,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
284711
285206
|
|
|
284712
285207
|
`);
|
|
284713
285208
|
try {
|
|
284714
|
-
|
|
285209
|
+
execSync40("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
284715
285210
|
stdio: "inherit",
|
|
284716
285211
|
timeout: 3e5
|
|
284717
285212
|
// 5 min max for install
|
|
@@ -284722,7 +285217,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
284722
285217
|
process.stdout.write(` ${c3.cyan("\u25CF")} Retrying pull of ${c3.bold(tag)}...
|
|
284723
285218
|
|
|
284724
285219
|
`);
|
|
284725
|
-
|
|
285220
|
+
execSync40(`ollama pull ${tag}`, {
|
|
284726
285221
|
stdio: "inherit",
|
|
284727
285222
|
timeout: 36e5
|
|
284728
285223
|
});
|
|
@@ -284811,7 +285306,7 @@ function ensurePython3() {
|
|
|
284811
285306
|
if (plat === "darwin") {
|
|
284812
285307
|
if (hasCmd("brew")) {
|
|
284813
285308
|
try {
|
|
284814
|
-
|
|
285309
|
+
execSync40("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
284815
285310
|
if (hasCmd("python3")) {
|
|
284816
285311
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via Homebrew.
|
|
284817
285312
|
`);
|
|
@@ -284824,7 +285319,7 @@ function ensurePython3() {
|
|
|
284824
285319
|
for (const s2 of strategies) {
|
|
284825
285320
|
if (hasCmd(s2.check)) {
|
|
284826
285321
|
try {
|
|
284827
|
-
|
|
285322
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284828
285323
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
284829
285324
|
process.stdout.write(` ${c3.green("\u2714")} Python3 installed via ${s2.label}.
|
|
284830
285325
|
`);
|
|
@@ -284840,11 +285335,11 @@ function ensurePython3() {
|
|
|
284840
285335
|
}
|
|
284841
285336
|
function checkPythonVenv() {
|
|
284842
285337
|
try {
|
|
284843
|
-
|
|
285338
|
+
execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
284844
285339
|
return true;
|
|
284845
285340
|
} catch {
|
|
284846
285341
|
try {
|
|
284847
|
-
|
|
285342
|
+
execSync40("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
284848
285343
|
return true;
|
|
284849
285344
|
} catch {
|
|
284850
285345
|
return false;
|
|
@@ -284863,7 +285358,7 @@ function ensurePythonVenv() {
|
|
|
284863
285358
|
for (const s2 of strategies) {
|
|
284864
285359
|
if (hasCmd(s2.check)) {
|
|
284865
285360
|
try {
|
|
284866
|
-
|
|
285361
|
+
execSync40(s2.install, { stdio: "inherit", timeout: 12e4 });
|
|
284867
285362
|
if (checkPythonVenv()) {
|
|
284868
285363
|
process.stdout.write(` ${c3.green("\u2714")} python3-venv installed via ${s2.label}.
|
|
284869
285364
|
`);
|
|
@@ -285291,7 +285786,7 @@ async function doSetup(config, rl) {
|
|
|
285291
285786
|
const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
|
|
285292
285787
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
285293
285788
|
process.stdout.write(` ${c3.dim("Creating model...")} `);
|
|
285294
|
-
|
|
285789
|
+
execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
285295
285790
|
stdio: "pipe",
|
|
285296
285791
|
timeout: 12e4
|
|
285297
285792
|
});
|
|
@@ -285342,7 +285837,7 @@ function isFirstRun() {
|
|
|
285342
285837
|
function hasCmd(cmd) {
|
|
285343
285838
|
try {
|
|
285344
285839
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
285345
|
-
|
|
285840
|
+
execSync40(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
285346
285841
|
return true;
|
|
285347
285842
|
} catch {
|
|
285348
285843
|
return false;
|
|
@@ -285354,7 +285849,7 @@ function detectPkgManager() {
|
|
|
285354
285849
|
if (hasCmd("choco")) return "choco";
|
|
285355
285850
|
if (hasCmd("winget")) return "winget";
|
|
285356
285851
|
try {
|
|
285357
|
-
|
|
285852
|
+
execSync40(
|
|
285358
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'))"`,
|
|
285359
285854
|
{ stdio: "pipe", timeout: 12e4 }
|
|
285360
285855
|
);
|
|
@@ -285366,7 +285861,7 @@ function detectPkgManager() {
|
|
|
285366
285861
|
if (plat === "darwin") {
|
|
285367
285862
|
if (hasCmd("brew")) return "brew";
|
|
285368
285863
|
try {
|
|
285369
|
-
|
|
285864
|
+
execSync40(
|
|
285370
285865
|
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
|
285371
285866
|
{ stdio: "pipe", timeout: 3e5, env: { ...process.env, NONINTERACTIVE: "1" } }
|
|
285372
285867
|
);
|
|
@@ -285386,7 +285881,7 @@ function getVenvDir() {
|
|
|
285386
285881
|
}
|
|
285387
285882
|
function hasVenvModule() {
|
|
285388
285883
|
try {
|
|
285389
|
-
|
|
285884
|
+
execSync40("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
285390
285885
|
return true;
|
|
285391
285886
|
} catch {
|
|
285392
285887
|
return false;
|
|
@@ -285410,8 +285905,8 @@ function ensureVenv(log22) {
|
|
|
285410
285905
|
try {
|
|
285411
285906
|
mkdirSync21(join64(homedir18(), ".open-agents"), { recursive: true });
|
|
285412
285907
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
285413
|
-
|
|
285414
|
-
|
|
285908
|
+
execSync40(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
285909
|
+
execSync40(`"${pipPath}" install --upgrade pip`, {
|
|
285415
285910
|
stdio: "pipe",
|
|
285416
285911
|
timeout: 6e4
|
|
285417
285912
|
});
|
|
@@ -285424,7 +285919,7 @@ function ensureVenv(log22) {
|
|
|
285424
285919
|
}
|
|
285425
285920
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
285426
285921
|
try {
|
|
285427
|
-
|
|
285922
|
+
execSync40(`sudo -n ${cmd}`, {
|
|
285428
285923
|
stdio: "pipe",
|
|
285429
285924
|
timeout: timeoutMs,
|
|
285430
285925
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -285437,7 +285932,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
285437
285932
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
285438
285933
|
try {
|
|
285439
285934
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
285440
|
-
|
|
285935
|
+
execSync40(`sudo -S bash -c '${escaped}'`, {
|
|
285441
285936
|
input: password + "\n",
|
|
285442
285937
|
stdio: ["pipe", "pipe", "pipe"],
|
|
285443
285938
|
timeout: timeoutMs,
|
|
@@ -285531,7 +286026,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285531
286026
|
let winNeedsElevation = false;
|
|
285532
286027
|
if (process.platform === "win32") {
|
|
285533
286028
|
try {
|
|
285534
|
-
|
|
286029
|
+
execSync40("net session", { stdio: "pipe", timeout: 3e3 });
|
|
285535
286030
|
} catch {
|
|
285536
286031
|
winNeedsElevation = true;
|
|
285537
286032
|
log22(`Installing ${labels} via ${pm2} (requires admin \u2014 UAC prompt will appear)...`);
|
|
@@ -285578,12 +286073,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285578
286073
|
if (needsSudo) {
|
|
285579
286074
|
await sudoInstall(installCmd, getPassword, log22, cachedPasswordRef, 18e4);
|
|
285580
286075
|
} else if (winNeedsElevation) {
|
|
285581
|
-
|
|
286076
|
+
execSync40(
|
|
285582
286077
|
`powershell -NoProfile -Command "Start-Process -FilePath 'cmd.exe' -ArgumentList '/c ${installCmd.replace(/'/g, "''")}' -Verb RunAs -Wait"`,
|
|
285583
286078
|
{ stdio: "pipe", timeout: 18e4 }
|
|
285584
286079
|
);
|
|
285585
286080
|
} else {
|
|
285586
|
-
|
|
286081
|
+
execSync40(installCmd, { stdio: "pipe", timeout: 18e4 });
|
|
285587
286082
|
}
|
|
285588
286083
|
} catch (e2) {
|
|
285589
286084
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -285596,7 +286091,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285596
286091
|
if (!hasCmd(d2.binary) && pipPkg) {
|
|
285597
286092
|
try {
|
|
285598
286093
|
const pipCmd = process.platform === "win32" ? `pip install ${pipPkg}` : `pip3 install ${pipPkg}`;
|
|
285599
|
-
|
|
286094
|
+
execSync40(pipCmd, { stdio: "pipe", timeout: 12e4 });
|
|
285600
286095
|
lastError = "";
|
|
285601
286096
|
} catch (e2) {
|
|
285602
286097
|
const stderr = e2.stderr?.toString?.()?.trim?.() ?? "";
|
|
@@ -285608,7 +286103,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285608
286103
|
}
|
|
285609
286104
|
if (process.platform === "win32" && !hasCmd(d2.binary)) {
|
|
285610
286105
|
try {
|
|
285611
|
-
const freshPath =
|
|
286106
|
+
const freshPath = execSync40(
|
|
285612
286107
|
`powershell -NoProfile -Command "[System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path','User')"`,
|
|
285613
286108
|
{ encoding: "utf8", timeout: 5e3, stdio: "pipe" }
|
|
285614
286109
|
).trim();
|
|
@@ -285654,7 +286149,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285654
286149
|
const venvCmds = {
|
|
285655
286150
|
apt: () => {
|
|
285656
286151
|
try {
|
|
285657
|
-
const pyVer =
|
|
286152
|
+
const pyVer = execSync40(
|
|
285658
286153
|
`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
285659
286154
|
{ encoding: "utf8", stdio: "pipe", timeout: 5e3 }
|
|
285660
286155
|
).trim();
|
|
@@ -285686,12 +286181,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285686
286181
|
const venvPip2 = join64(venvBin, "pip");
|
|
285687
286182
|
log22("Installing moondream-station in ~/.open-agents/venv...");
|
|
285688
286183
|
try {
|
|
285689
|
-
|
|
286184
|
+
execSync40(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
285690
286185
|
if (existsSync47(venvMoondream)) {
|
|
285691
286186
|
log22("moondream-station installed successfully.");
|
|
285692
286187
|
} else {
|
|
285693
286188
|
try {
|
|
285694
|
-
const check =
|
|
286189
|
+
const check = execSync40(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
285695
286190
|
if (check.includes("moondream")) {
|
|
285696
286191
|
log22("moondream-station package installed.");
|
|
285697
286192
|
}
|
|
@@ -285708,7 +286203,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285708
286203
|
const venvPip2 = join64(venvBin, isWin2 ? "pip.exe" : "pip");
|
|
285709
286204
|
let ocrStackInstalled = false;
|
|
285710
286205
|
try {
|
|
285711
|
-
|
|
286206
|
+
execSync40(
|
|
285712
286207
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
285713
286208
|
{ stdio: "pipe", timeout: 1e4 }
|
|
285714
286209
|
);
|
|
@@ -285719,12 +286214,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
285719
286214
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
285720
286215
|
log22("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
285721
286216
|
try {
|
|
285722
|
-
|
|
286217
|
+
execSync40(
|
|
285723
286218
|
`"${venvPip2}" install ${ocrPackages}`,
|
|
285724
286219
|
{ stdio: "pipe", timeout: 3e5 }
|
|
285725
286220
|
);
|
|
285726
286221
|
try {
|
|
285727
|
-
|
|
286222
|
+
execSync40(
|
|
285728
286223
|
`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`,
|
|
285729
286224
|
{ stdio: "pipe", timeout: 1e4 }
|
|
285730
286225
|
);
|
|
@@ -285760,7 +286255,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285760
286255
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
285761
286256
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
285762
286257
|
try {
|
|
285763
|
-
|
|
286258
|
+
execSync40(
|
|
285764
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"`,
|
|
285765
286260
|
{ stdio: "pipe", timeout: 6e4 }
|
|
285766
286261
|
);
|
|
@@ -285774,7 +286269,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285774
286269
|
} catch {
|
|
285775
286270
|
}
|
|
285776
286271
|
try {
|
|
285777
|
-
|
|
286272
|
+
execSync40(
|
|
285778
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`,
|
|
285779
286274
|
{ stdio: "pipe", timeout: 6e4 }
|
|
285780
286275
|
);
|
|
@@ -285786,7 +286281,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
285786
286281
|
}
|
|
285787
286282
|
} else if (os8 === "darwin") {
|
|
285788
286283
|
try {
|
|
285789
|
-
|
|
286284
|
+
execSync40("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
285790
286285
|
if (hasCmd("cloudflared")) {
|
|
285791
286286
|
log22("cloudflared installed via Homebrew.");
|
|
285792
286287
|
return true;
|
|
@@ -285866,7 +286361,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
285866
286361
|
mkdirSync21(modelDir2, { recursive: true });
|
|
285867
286362
|
const modelfilePath = join64(modelDir2, `Modelfile.${customName}`);
|
|
285868
286363
|
writeFileSync22(modelfilePath, modelfileContent + "\n", "utf8");
|
|
285869
|
-
|
|
286364
|
+
execSync40(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
285870
286365
|
stdio: "pipe",
|
|
285871
286366
|
timeout: 12e4
|
|
285872
286367
|
});
|
|
@@ -285952,7 +286447,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
285952
286447
|
}
|
|
285953
286448
|
async function ensureNeovim() {
|
|
285954
286449
|
try {
|
|
285955
|
-
const nvimPath =
|
|
286450
|
+
const nvimPath = execSync40("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
285956
286451
|
encoding: "utf8",
|
|
285957
286452
|
stdio: "pipe",
|
|
285958
286453
|
timeout: 5e3
|
|
@@ -285973,14 +286468,14 @@ async function ensureNeovim() {
|
|
|
285973
286468
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
285974
286469
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
285975
286470
|
try {
|
|
285976
|
-
|
|
285977
|
-
|
|
286471
|
+
execSync40(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
286472
|
+
execSync40(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
285978
286473
|
} catch (err) {
|
|
285979
286474
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
285980
286475
|
return null;
|
|
285981
286476
|
}
|
|
285982
286477
|
try {
|
|
285983
|
-
const ver =
|
|
286478
|
+
const ver = execSync40(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
285984
286479
|
console.log(` Installed: ${ver}`);
|
|
285985
286480
|
} catch {
|
|
285986
286481
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -285995,8 +286490,8 @@ async function ensureNeovim() {
|
|
|
285995
286490
|
if (hasCmd("brew")) {
|
|
285996
286491
|
console.log(" Installing Neovim via Homebrew...");
|
|
285997
286492
|
try {
|
|
285998
|
-
|
|
285999
|
-
const nvimPath =
|
|
286493
|
+
execSync40("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
286494
|
+
const nvimPath = execSync40("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
286000
286495
|
return nvimPath || null;
|
|
286001
286496
|
} catch {
|
|
286002
286497
|
console.log(" brew install neovim failed.");
|
|
@@ -286010,7 +286505,7 @@ async function ensureNeovim() {
|
|
|
286010
286505
|
if (hasCmd("choco")) {
|
|
286011
286506
|
console.log(" Installing Neovim via Chocolatey...");
|
|
286012
286507
|
try {
|
|
286013
|
-
|
|
286508
|
+
execSync40("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
286014
286509
|
return "nvim";
|
|
286015
286510
|
} catch {
|
|
286016
286511
|
console.log(" choco install neovim failed.");
|
|
@@ -286019,7 +286514,7 @@ async function ensureNeovim() {
|
|
|
286019
286514
|
if (hasCmd("winget")) {
|
|
286020
286515
|
console.log(" Installing Neovim via winget...");
|
|
286021
286516
|
try {
|
|
286022
|
-
|
|
286517
|
+
execSync40("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
286023
286518
|
stdio: "inherit",
|
|
286024
286519
|
timeout: 12e4
|
|
286025
286520
|
});
|
|
@@ -286270,7 +286765,7 @@ var init_drop_panel = __esm({
|
|
|
286270
286765
|
import { existsSync as existsSync49, unlinkSync as unlinkSync11 } from "node:fs";
|
|
286271
286766
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
286272
286767
|
import { join as join65 } from "node:path";
|
|
286273
|
-
import { execSync as
|
|
286768
|
+
import { execSync as execSync41 } from "node:child_process";
|
|
286274
286769
|
function isNeovimActive() {
|
|
286275
286770
|
return _state !== null && !_state.cleanedUp;
|
|
286276
286771
|
}
|
|
@@ -286287,7 +286782,7 @@ async function startNeovimMode(opts) {
|
|
|
286287
286782
|
}
|
|
286288
286783
|
let nvimPath;
|
|
286289
286784
|
try {
|
|
286290
|
-
nvimPath =
|
|
286785
|
+
nvimPath = execSync41("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
286291
286786
|
if (!nvimPath) throw new Error();
|
|
286292
286787
|
} catch {
|
|
286293
286788
|
const installed = await ensureNeovim();
|
|
@@ -286822,8 +287317,8 @@ async function startDaemon() {
|
|
|
286822
287317
|
let oaScript = process.argv[1];
|
|
286823
287318
|
if (!oaScript) {
|
|
286824
287319
|
try {
|
|
286825
|
-
const { execSync:
|
|
286826
|
-
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();
|
|
286827
287322
|
if (whichOa) oaScript = whichOa;
|
|
286828
287323
|
} catch {
|
|
286829
287324
|
}
|
|
@@ -288230,7 +288725,7 @@ __export(voice_exports, {
|
|
|
288230
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";
|
|
288231
288726
|
import { join as join68, dirname as dirname22 } from "node:path";
|
|
288232
288727
|
import { homedir as homedir20, tmpdir as tmpdir12, platform as platform4 } from "node:os";
|
|
288233
|
-
import { execSync as
|
|
288728
|
+
import { execSync as execSync42, spawn as nodeSpawn } from "node:child_process";
|
|
288234
288729
|
import { createRequire as createRequire2 } from "node:module";
|
|
288235
288730
|
function sanitizeForTTS(text) {
|
|
288236
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();
|
|
@@ -289918,7 +290413,7 @@ var init_voice = __esm({
|
|
|
289918
290413
|
}
|
|
289919
290414
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
289920
290415
|
try {
|
|
289921
|
-
|
|
290416
|
+
execSync42(`which ${player}`, { stdio: "pipe" });
|
|
289922
290417
|
return [player, path5];
|
|
289923
290418
|
} catch {
|
|
289924
290419
|
}
|
|
@@ -289946,7 +290441,7 @@ var init_voice = __esm({
|
|
|
289946
290441
|
if (this.python3Path) return this.python3Path;
|
|
289947
290442
|
for (const bin of ["python3", "python"]) {
|
|
289948
290443
|
try {
|
|
289949
|
-
const path5 =
|
|
290444
|
+
const path5 = execSync42(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
289950
290445
|
if (path5) {
|
|
289951
290446
|
this.python3Path = path5;
|
|
289952
290447
|
return path5;
|
|
@@ -290008,7 +290503,7 @@ var init_voice = __esm({
|
|
|
290008
290503
|
return false;
|
|
290009
290504
|
}
|
|
290010
290505
|
try {
|
|
290011
|
-
|
|
290506
|
+
execSync42(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
290012
290507
|
this.mlxInstalled = true;
|
|
290013
290508
|
return true;
|
|
290014
290509
|
} catch {
|
|
@@ -290071,14 +290566,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
290071
290566
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
290072
290567
|
].join("; ");
|
|
290073
290568
|
try {
|
|
290074
|
-
|
|
290569
|
+
execSync42(
|
|
290075
290570
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
290076
290571
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290077
290572
|
);
|
|
290078
290573
|
} catch (err) {
|
|
290079
290574
|
try {
|
|
290080
290575
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
290081
|
-
|
|
290576
|
+
execSync42(
|
|
290082
290577
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
290083
290578
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290084
290579
|
);
|
|
@@ -290145,14 +290640,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
290145
290640
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
290146
290641
|
].join("; ");
|
|
290147
290642
|
try {
|
|
290148
|
-
|
|
290643
|
+
execSync42(
|
|
290149
290644
|
`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`,
|
|
290150
290645
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290151
290646
|
);
|
|
290152
290647
|
} catch {
|
|
290153
290648
|
try {
|
|
290154
290649
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
290155
|
-
|
|
290650
|
+
execSync42(
|
|
290156
290651
|
`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`,
|
|
290157
290652
|
{ stdio: "pipe", timeout: 6e4, cwd: tmpdir12() }
|
|
290158
290653
|
);
|
|
@@ -295667,7 +296162,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
295667
296162
|
}
|
|
295668
296163
|
}
|
|
295669
296164
|
async function handleParallel(arg, ctx3) {
|
|
295670
|
-
const { execSync:
|
|
296165
|
+
const { execSync: execSync48 } = await import("node:child_process");
|
|
295671
296166
|
const baseUrl = ctx3.config.backendUrl || "http://localhost:11434";
|
|
295672
296167
|
const isRemote = ctx3.config.backendType === "nexus";
|
|
295673
296168
|
if (isRemote) {
|
|
@@ -295691,7 +296186,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
295691
296186
|
}
|
|
295692
296187
|
let systemdVal = "";
|
|
295693
296188
|
try {
|
|
295694
|
-
const out =
|
|
296189
|
+
const out = execSync48("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
295695
296190
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
295696
296191
|
if (match) systemdVal = match[1];
|
|
295697
296192
|
} catch {
|
|
@@ -295719,7 +296214,7 @@ async function handleParallel(arg, ctx3) {
|
|
|
295719
296214
|
}
|
|
295720
296215
|
const isSystemd = (() => {
|
|
295721
296216
|
try {
|
|
295722
|
-
const out =
|
|
296217
|
+
const out = execSync48("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
295723
296218
|
return out === "active" || out === "inactive";
|
|
295724
296219
|
} catch {
|
|
295725
296220
|
return false;
|
|
@@ -295733,10 +296228,10 @@ async function handleParallel(arg, ctx3) {
|
|
|
295733
296228
|
const overrideContent = `[Service]
|
|
295734
296229
|
Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
295735
296230
|
`;
|
|
295736
|
-
|
|
295737
|
-
|
|
295738
|
-
|
|
295739
|
-
|
|
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" });
|
|
295740
296235
|
let ready = false;
|
|
295741
296236
|
for (let i2 = 0; i2 < 30 && !ready; i2++) {
|
|
295742
296237
|
await new Promise((r2) => setTimeout(r2, 500));
|
|
@@ -295762,7 +296257,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
295762
296257
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n2}...`);
|
|
295763
296258
|
try {
|
|
295764
296259
|
try {
|
|
295765
|
-
|
|
296260
|
+
execSync48("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
295766
296261
|
} catch {
|
|
295767
296262
|
}
|
|
295768
296263
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
@@ -296814,18 +297309,18 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
296814
297309
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
296815
297310
|
let copied = false;
|
|
296816
297311
|
try {
|
|
296817
|
-
const { execSync:
|
|
297312
|
+
const { execSync: execSync48 } = __require("node:child_process");
|
|
296818
297313
|
const platform6 = process.platform;
|
|
296819
297314
|
if (platform6 === "darwin") {
|
|
296820
|
-
|
|
297315
|
+
execSync48("pbcopy", { input: cmd, timeout: 3e3 });
|
|
296821
297316
|
copied = true;
|
|
296822
297317
|
} else if (platform6 === "win32") {
|
|
296823
|
-
|
|
297318
|
+
execSync48("clip", { input: cmd, timeout: 3e3 });
|
|
296824
297319
|
copied = true;
|
|
296825
297320
|
} else {
|
|
296826
297321
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
296827
297322
|
try {
|
|
296828
|
-
|
|
297323
|
+
execSync48(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
296829
297324
|
copied = true;
|
|
296830
297325
|
break;
|
|
296831
297326
|
} catch {
|
|
@@ -296920,7 +297415,7 @@ var init_commands = __esm({
|
|
|
296920
297415
|
// packages/cli/src/tui/project-context.ts
|
|
296921
297416
|
import { existsSync as existsSync54, readFileSync as readFileSync42, readdirSync as readdirSync15 } from "node:fs";
|
|
296922
297417
|
import { join as join70, basename as basename13 } from "node:path";
|
|
296923
|
-
import { execSync as
|
|
297418
|
+
import { execSync as execSync43 } from "node:child_process";
|
|
296924
297419
|
import { homedir as homedir22, platform as platform5, release } from "node:os";
|
|
296925
297420
|
function getModelTier(modelName) {
|
|
296926
297421
|
const m2 = modelName.toLowerCase();
|
|
@@ -296962,18 +297457,18 @@ function loadProjectMap(repoRoot) {
|
|
|
296962
297457
|
}
|
|
296963
297458
|
function getGitInfo(repoRoot) {
|
|
296964
297459
|
try {
|
|
296965
|
-
|
|
297460
|
+
execSync43("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
296966
297461
|
} catch {
|
|
296967
297462
|
return "";
|
|
296968
297463
|
}
|
|
296969
297464
|
const lines = [];
|
|
296970
297465
|
try {
|
|
296971
|
-
const branch =
|
|
297466
|
+
const branch = execSync43("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296972
297467
|
if (branch) lines.push(`Branch: ${branch}`);
|
|
296973
297468
|
} catch {
|
|
296974
297469
|
}
|
|
296975
297470
|
try {
|
|
296976
|
-
const status =
|
|
297471
|
+
const status = execSync43("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296977
297472
|
if (status) {
|
|
296978
297473
|
const changed = status.split("\n").length;
|
|
296979
297474
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -296983,7 +297478,7 @@ function getGitInfo(repoRoot) {
|
|
|
296983
297478
|
} catch {
|
|
296984
297479
|
}
|
|
296985
297480
|
try {
|
|
296986
|
-
const log22 =
|
|
297481
|
+
const log22 = execSync43("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
296987
297482
|
if (log22) lines.push(`Recent commits:
|
|
296988
297483
|
${log22}`);
|
|
296989
297484
|
} catch {
|
|
@@ -299647,7 +300142,7 @@ var init_promptLoader3 = __esm({
|
|
|
299647
300142
|
// packages/cli/src/tui/dream-engine.ts
|
|
299648
300143
|
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync29, readFileSync as readFileSync46, existsSync as existsSync58, readdirSync as readdirSync17 } from "node:fs";
|
|
299649
300144
|
import { join as join75, basename as basename15 } from "node:path";
|
|
299650
|
-
import { execSync as
|
|
300145
|
+
import { execSync as execSync44 } from "node:child_process";
|
|
299651
300146
|
function setDreamWriteContent(fn) {
|
|
299652
300147
|
_dreamWriteContent = fn;
|
|
299653
300148
|
}
|
|
@@ -300021,7 +300516,7 @@ var init_dream_engine = __esm({
|
|
|
300021
300516
|
}
|
|
300022
300517
|
}
|
|
300023
300518
|
try {
|
|
300024
|
-
const output =
|
|
300519
|
+
const output = execSync44(cmd, {
|
|
300025
300520
|
cwd: this.repoRoot,
|
|
300026
300521
|
timeout: 3e4,
|
|
300027
300522
|
encoding: "utf-8",
|
|
@@ -300880,17 +301375,17 @@ ${summaryResult}
|
|
|
300880
301375
|
try {
|
|
300881
301376
|
mkdirSync29(checkpointDir, { recursive: true });
|
|
300882
301377
|
try {
|
|
300883
|
-
const gitStatus =
|
|
301378
|
+
const gitStatus = execSync44("git status --porcelain", {
|
|
300884
301379
|
cwd: this.repoRoot,
|
|
300885
301380
|
encoding: "utf-8",
|
|
300886
301381
|
timeout: 1e4
|
|
300887
301382
|
});
|
|
300888
|
-
const gitDiff =
|
|
301383
|
+
const gitDiff = execSync44("git diff", {
|
|
300889
301384
|
cwd: this.repoRoot,
|
|
300890
301385
|
encoding: "utf-8",
|
|
300891
301386
|
timeout: 1e4
|
|
300892
301387
|
});
|
|
300893
|
-
const gitHash =
|
|
301388
|
+
const gitHash = execSync44("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
300894
301389
|
cwd: this.repoRoot,
|
|
300895
301390
|
encoding: "utf-8",
|
|
300896
301391
|
timeout: 5e3
|
|
@@ -306483,7 +306978,7 @@ var init_profiles = __esm({
|
|
|
306483
306978
|
});
|
|
306484
306979
|
|
|
306485
306980
|
// packages/cli/src/docker.ts
|
|
306486
|
-
import { execSync as
|
|
306981
|
+
import { execSync as execSync45, spawn as spawn23 } from "node:child_process";
|
|
306487
306982
|
import { existsSync as existsSync66, mkdirSync as mkdirSync35, writeFileSync as writeFileSync33 } from "node:fs";
|
|
306488
306983
|
import { join as join83, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
306489
306984
|
import { homedir as homedir24 } from "node:os";
|
|
@@ -306504,7 +306999,7 @@ function getDockerDir() {
|
|
|
306504
306999
|
}
|
|
306505
307000
|
function isDockerAvailable() {
|
|
306506
307001
|
try {
|
|
306507
|
-
|
|
307002
|
+
execSync45("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
306508
307003
|
return true;
|
|
306509
307004
|
} catch {
|
|
306510
307005
|
return false;
|
|
@@ -306512,7 +307007,7 @@ function isDockerAvailable() {
|
|
|
306512
307007
|
}
|
|
306513
307008
|
function isDockerInstalled() {
|
|
306514
307009
|
try {
|
|
306515
|
-
|
|
307010
|
+
execSync45("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
306516
307011
|
return true;
|
|
306517
307012
|
} catch {
|
|
306518
307013
|
return false;
|
|
@@ -306537,31 +307032,31 @@ async function ensureDocker() {
|
|
|
306537
307032
|
}
|
|
306538
307033
|
try {
|
|
306539
307034
|
console.log("[oa-docker] Docker not found. Installing via get.docker.com...");
|
|
306540
|
-
|
|
307035
|
+
execSync45("curl -fsSL https://get.docker.com | sh", {
|
|
306541
307036
|
stdio: "inherit",
|
|
306542
307037
|
timeout: 3e5
|
|
306543
307038
|
});
|
|
306544
307039
|
const user = process.env["USER"] || process.env["LOGNAME"];
|
|
306545
307040
|
if (user) {
|
|
306546
307041
|
try {
|
|
306547
|
-
|
|
307042
|
+
execSync45(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
|
|
306548
307043
|
} catch {
|
|
306549
307044
|
}
|
|
306550
307045
|
}
|
|
306551
307046
|
try {
|
|
306552
|
-
|
|
307047
|
+
execSync45("sudo systemctl start docker", { stdio: "pipe", timeout: 15e3 });
|
|
306553
307048
|
} catch {
|
|
306554
307049
|
}
|
|
306555
307050
|
try {
|
|
306556
|
-
|
|
306557
|
-
const runtimes =
|
|
307051
|
+
execSync45("nvidia-smi", { stdio: "pipe", timeout: 5e3 });
|
|
307052
|
+
const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
|
|
306558
307053
|
stdio: "pipe",
|
|
306559
307054
|
timeout: 5e3
|
|
306560
307055
|
}).toString();
|
|
306561
307056
|
if (!runtimes.includes("nvidia")) {
|
|
306562
307057
|
console.log("[oa-docker] NVIDIA GPU detected. Installing nvidia-container-toolkit...");
|
|
306563
307058
|
try {
|
|
306564
|
-
|
|
307059
|
+
execSync45(`
|
|
306565
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
|
|
306566
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
|
|
306567
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 )
|
|
@@ -306591,7 +307086,7 @@ async function ensureDocker() {
|
|
|
306591
307086
|
}
|
|
306592
307087
|
async function ensureNvidiaToolkit() {
|
|
306593
307088
|
try {
|
|
306594
|
-
|
|
307089
|
+
execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", { stdio: "pipe", timeout: 5e3 });
|
|
306595
307090
|
} catch {
|
|
306596
307091
|
return { ok: false, message: "No NVIDIA GPU detected (nvidia-smi not found)" };
|
|
306597
307092
|
}
|
|
@@ -306602,7 +307097,7 @@ async function ensureNvidiaToolkit() {
|
|
|
306602
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" };
|
|
306603
307098
|
}
|
|
306604
307099
|
try {
|
|
306605
|
-
|
|
307100
|
+
execSync45(`
|
|
306606
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
|
|
306607
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
|
|
306608
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 )
|
|
@@ -306616,7 +307111,7 @@ async function ensureNvidiaToolkit() {
|
|
|
306616
307111
|
}
|
|
306617
307112
|
function isOaImageBuilt() {
|
|
306618
307113
|
try {
|
|
306619
|
-
const out =
|
|
307114
|
+
const out = execSync45(`docker images -q ${OA_IMAGE}:${OA_IMAGE_TAG}`, {
|
|
306620
307115
|
stdio: "pipe",
|
|
306621
307116
|
timeout: 5e3
|
|
306622
307117
|
}).toString().trim();
|
|
@@ -306640,7 +307135,7 @@ async function ensureOaImage(force = false) {
|
|
|
306640
307135
|
}
|
|
306641
307136
|
try {
|
|
306642
307137
|
console.log(`[oa-docker] Building image ${OA_IMAGE}:${OA_IMAGE_TAG}...`);
|
|
306643
|
-
|
|
307138
|
+
execSync45(`docker build -t ${OA_IMAGE}:${OA_IMAGE_TAG} ${buildContext}`, {
|
|
306644
307139
|
stdio: "inherit",
|
|
306645
307140
|
timeout: 6e5
|
|
306646
307141
|
// 10 min
|
|
@@ -306714,11 +307209,11 @@ exec "$@"
|
|
|
306714
307209
|
}
|
|
306715
307210
|
function hasNvidiaGpu() {
|
|
306716
307211
|
try {
|
|
306717
|
-
|
|
307212
|
+
execSync45("nvidia-smi --query-gpu=name --format=csv,noheader", {
|
|
306718
307213
|
stdio: "pipe",
|
|
306719
307214
|
timeout: 5e3
|
|
306720
307215
|
});
|
|
306721
|
-
const runtimes =
|
|
307216
|
+
const runtimes = execSync45("docker info --format '{{json .Runtimes}}'", {
|
|
306722
307217
|
stdio: "pipe",
|
|
306723
307218
|
timeout: 5e3
|
|
306724
307219
|
}).toString();
|
|
@@ -306788,7 +307283,7 @@ import * as https3 from "node:https";
|
|
|
306788
307283
|
import { createRequire as createRequire4 } from "node:module";
|
|
306789
307284
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
306790
307285
|
import { dirname as dirname25, join as join84, resolve as resolve34 } from "node:path";
|
|
306791
|
-
import { spawn as spawn24, execSync as
|
|
307286
|
+
import { spawn as spawn24, execSync as execSync46 } from "node:child_process";
|
|
306792
307287
|
import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync34, readFileSync as readFileSync53, readdirSync as readdirSync23, existsSync as existsSync67 } from "node:fs";
|
|
306793
307288
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
306794
307289
|
function getVersion3() {
|
|
@@ -307796,7 +308291,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
307796
308291
|
const containerName = `oa-${id}`;
|
|
307797
308292
|
if (job.sandbox === "container") {
|
|
307798
308293
|
try {
|
|
307799
|
-
|
|
308294
|
+
execSync46(`docker stop ${containerName}`, { timeout: 5e3, stdio: "ignore" });
|
|
307800
308295
|
} catch {
|
|
307801
308296
|
}
|
|
307802
308297
|
}
|
|
@@ -308706,7 +309201,7 @@ import { createRequire as createRequire5 } from "node:module";
|
|
|
308706
309201
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
308707
309202
|
import { readFileSync as readFileSync54, writeFileSync as writeFileSync35, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync37 } from "node:fs";
|
|
308708
309203
|
import { existsSync as existsSync68 } from "node:fs";
|
|
308709
|
-
import { execSync as
|
|
309204
|
+
import { execSync as execSync47 } from "node:child_process";
|
|
308710
309205
|
import { homedir as homedir25 } from "node:os";
|
|
308711
309206
|
function formatTimeAgo(date) {
|
|
308712
309207
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -308873,6 +309368,8 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
308873
309368
|
new CameraCaptureTool(),
|
|
308874
309369
|
new AudioCaptureTool(),
|
|
308875
309370
|
new AudioPlaybackTool(),
|
|
309371
|
+
new WifiControlTool(),
|
|
309372
|
+
new BluetoothScanTool(),
|
|
308876
309373
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
308877
309374
|
(() => {
|
|
308878
309375
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -313031,7 +313528,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313031
313528
|
try {
|
|
313032
313529
|
if (process.platform === "win32") {
|
|
313033
313530
|
try {
|
|
313034
|
-
|
|
313531
|
+
execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
313035
313532
|
} catch {
|
|
313036
313533
|
}
|
|
313037
313534
|
} else {
|
|
@@ -313058,7 +313555,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313058
313555
|
if (pid > 0) {
|
|
313059
313556
|
if (process.platform === "win32") {
|
|
313060
313557
|
try {
|
|
313061
|
-
|
|
313558
|
+
execSync47(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
313062
313559
|
} catch {
|
|
313063
313560
|
}
|
|
313064
313561
|
} else {
|
|
@@ -313075,7 +313572,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313075
313572
|
} catch {
|
|
313076
313573
|
}
|
|
313077
313574
|
try {
|
|
313078
|
-
|
|
313575
|
+
execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
313079
313576
|
} catch {
|
|
313080
313577
|
}
|
|
313081
313578
|
const oaPath = join85(repoRoot, OA_DIR);
|
|
@@ -313089,14 +313586,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
313089
313586
|
} catch (err) {
|
|
313090
313587
|
if (attempt < 2) {
|
|
313091
313588
|
try {
|
|
313092
|
-
|
|
313589
|
+
execSync47(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
313093
313590
|
} catch {
|
|
313094
313591
|
}
|
|
313095
313592
|
} else {
|
|
313096
313593
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
313097
313594
|
if (process.platform === "win32") {
|
|
313098
313595
|
try {
|
|
313099
|
-
|
|
313596
|
+
execSync47(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
313100
313597
|
deleted = true;
|
|
313101
313598
|
} catch {
|
|
313102
313599
|
}
|