open-agents-ai 0.187.149 → 0.187.151
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 +378 -138
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -256448,7 +256448,7 @@ ${output}`, durationMs: performance.now() - start2 };
|
|
|
256448
256448
|
import { execSync as execSync36, spawnSync as spawnSync2 } from "node:child_process";
|
|
256449
256449
|
import { existsSync as existsSync34, readFileSync as readFileSync25, writeFileSync as writeFileSync13, mkdirSync as mkdirSync14 } from "node:fs";
|
|
256450
256450
|
import { join as join48 } from "node:path";
|
|
256451
|
-
import { tmpdir as tmpdir12 } from "node:os";
|
|
256451
|
+
import { tmpdir as tmpdir12, homedir as homedir13 } from "node:os";
|
|
256452
256452
|
var GPS_USB_IDS, GpsLocationTool;
|
|
256453
256453
|
var init_gps_location = __esm({
|
|
256454
256454
|
"packages/execution/dist/tools/gps-location.js"() {
|
|
@@ -256549,13 +256549,63 @@ var init_gps_location = __esm({
|
|
|
256549
256549
|
},
|
|
256550
256550
|
required: ["action"]
|
|
256551
256551
|
};
|
|
256552
|
+
/** Venv for pyserial + pynmea2 (same stack as proven gps_service) */
|
|
256553
|
+
GPS_VENV = join48(homedir13(), ".open-agents", "gps-venv");
|
|
256554
|
+
GPS_PYTHON = join48(this.GPS_VENV, "bin", "python3");
|
|
256555
|
+
GPS_PIP = join48(this.GPS_VENV, "bin", "pip");
|
|
256556
|
+
/** Ensure pyserial + pynmea2 venv exists */
|
|
256557
|
+
async ensureGpsVenv() {
|
|
256558
|
+
if (existsSync34(this.GPS_PYTHON)) {
|
|
256559
|
+
try {
|
|
256560
|
+
execSync36(`${this.GPS_PYTHON} -c "import serial, pynmea2"`, { timeout: 5e3, stdio: "pipe" });
|
|
256561
|
+
return true;
|
|
256562
|
+
} catch {
|
|
256563
|
+
}
|
|
256564
|
+
}
|
|
256565
|
+
try {
|
|
256566
|
+
execSync36(`python3 -m venv ${this.GPS_VENV}`, { timeout: 3e4, stdio: "pipe" });
|
|
256567
|
+
execSync36(`${this.GPS_PIP} install pyserial pynmea2`, { timeout: 6e4, stdio: "pipe" });
|
|
256568
|
+
return true;
|
|
256569
|
+
} catch {
|
|
256570
|
+
return false;
|
|
256571
|
+
}
|
|
256572
|
+
}
|
|
256573
|
+
/** Run a Python GPS script using pyserial+pynmea2 and return JSON result */
|
|
256574
|
+
async runGpsPython(script, timeoutMs = 3e4) {
|
|
256575
|
+
await this.ensureGpsVenv();
|
|
256576
|
+
const scriptFile = join48(tmpdir12(), `oa-gps-${Date.now()}.py`);
|
|
256577
|
+
writeFileSync13(scriptFile, script);
|
|
256578
|
+
try {
|
|
256579
|
+
const output = execSync36(`${this.GPS_PYTHON} ${scriptFile}`, {
|
|
256580
|
+
encoding: "utf8",
|
|
256581
|
+
timeout: timeoutMs,
|
|
256582
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
256583
|
+
});
|
|
256584
|
+
const lastLine = output.trim().split("\n").pop() || "{}";
|
|
256585
|
+
return JSON.parse(lastLine);
|
|
256586
|
+
} catch (err) {
|
|
256587
|
+
const stderr = err.stderr?.toString() || "";
|
|
256588
|
+
const stdout = err.stdout?.toString() || "";
|
|
256589
|
+
for (const src2 of [stdout, stderr]) {
|
|
256590
|
+
const lines = src2.trim().split("\n");
|
|
256591
|
+
for (let i2 = lines.length - 1; i2 >= 0; i2--) {
|
|
256592
|
+
try {
|
|
256593
|
+
return JSON.parse(lines[i2]);
|
|
256594
|
+
} catch {
|
|
256595
|
+
continue;
|
|
256596
|
+
}
|
|
256597
|
+
}
|
|
256598
|
+
}
|
|
256599
|
+
throw new Error(stderr.slice(0, 300) || stdout.slice(0, 300) || "GPS Python script failed");
|
|
256600
|
+
}
|
|
256601
|
+
}
|
|
256552
256602
|
async execute(args) {
|
|
256553
256603
|
const action = args["action"];
|
|
256554
256604
|
const start2 = performance.now();
|
|
256555
256605
|
try {
|
|
256556
256606
|
switch (action) {
|
|
256557
256607
|
case "detect":
|
|
256558
|
-
return await this.detectGps(start2);
|
|
256608
|
+
return await this.detectGps(args, start2);
|
|
256559
256609
|
case "fix":
|
|
256560
256610
|
return await this.getFix(args, start2);
|
|
256561
256611
|
case "nmea":
|
|
@@ -256576,64 +256626,128 @@ var init_gps_location = __esm({
|
|
|
256576
256626
|
// =========================================================================
|
|
256577
256627
|
// Detect GPS hardware
|
|
256578
256628
|
// =========================================================================
|
|
256579
|
-
async detectGps(start2) {
|
|
256629
|
+
async detectGps(args, start2) {
|
|
256630
|
+
try {
|
|
256631
|
+
const result = await this.runGpsPython(`
|
|
256632
|
+
import json, sys
|
|
256633
|
+
try:
|
|
256634
|
+
from serial.tools import list_ports
|
|
256635
|
+
import serial
|
|
256636
|
+
|
|
256637
|
+
candidates = []
|
|
256638
|
+
for p in list_ports.comports():
|
|
256639
|
+
dev = p.device or ""
|
|
256640
|
+
desc = (p.description or "").lower()
|
|
256641
|
+
hwid = (p.hwid or "").lower()
|
|
256642
|
+
vid = getattr(p, 'vid', None)
|
|
256643
|
+
pid = getattr(p, 'pid', None)
|
|
256644
|
+
manufacturer = getattr(p, 'manufacturer', '') or ''
|
|
256645
|
+
product = getattr(p, 'product', '') or ''
|
|
256646
|
+
|
|
256647
|
+
score = 0
|
|
256648
|
+
label = f"{dev}: {p.description or 'unknown'}"
|
|
256649
|
+
if vid: label += f" [VID:PID={vid:04x}:{pid:04x}]"
|
|
256650
|
+
|
|
256651
|
+
# GPS-specific keywords
|
|
256652
|
+
if "gps" in desc or "gnss" in desc or "gps" in manufacturer.lower():
|
|
256653
|
+
score += 10
|
|
256654
|
+
# Known GPS vendors (u-blox=0x1546, Garmin=0x091e, GlobalSat/Prolific=0x067b)
|
|
256655
|
+
if vid in (0x1546, 0x091e, 0x2c7c, 0x152a, 0x0df7, 0x16d0):
|
|
256656
|
+
score += 8
|
|
256657
|
+
# UART bridges commonly used for GPS (Prolific, FTDI, CP210x, CH340)
|
|
256658
|
+
if vid in (0x067b, 0x0403, 0x10c4, 0x1a86):
|
|
256659
|
+
score += 4
|
|
256660
|
+
# ttyUSB devices are very often GPS
|
|
256661
|
+
if "ttyUSB" in dev:
|
|
256662
|
+
score += 3
|
|
256663
|
+
# USB serial in general
|
|
256664
|
+
if "usb" in hwid:
|
|
256665
|
+
score += 2
|
|
256666
|
+
if any(k in dev for k in ("ttyUSB", "ttyACM", "cu.usb", "COM")):
|
|
256667
|
+
score += 1
|
|
256668
|
+
|
|
256669
|
+
if score > 0:
|
|
256670
|
+
candidates.append({"device": dev, "label": label, "score": score,
|
|
256671
|
+
"vid": f"{vid:04x}" if vid else None,
|
|
256672
|
+
"pid": f"{pid:04x}" if pid else None,
|
|
256673
|
+
"manufacturer": manufacturer, "product": product})
|
|
256674
|
+
|
|
256675
|
+
candidates.sort(key=lambda x: -x["score"])
|
|
256676
|
+
|
|
256677
|
+
# Also try to read NMEA from top candidate to confirm it's GPS
|
|
256678
|
+
gps_confirmed = None
|
|
256679
|
+
for c in candidates[:3]:
|
|
256680
|
+
try:
|
|
256681
|
+
with serial.Serial(c["device"], 4800, timeout=2) as ser:
|
|
256682
|
+
ser.reset_input_buffer()
|
|
256683
|
+
for _ in range(20):
|
|
256684
|
+
line = ser.readline().decode(errors="ignore").strip()
|
|
256685
|
+
if line.startswith("$G"):
|
|
256686
|
+
c["nmea_confirmed"] = True
|
|
256687
|
+
gps_confirmed = c["device"]
|
|
256688
|
+
break
|
|
256689
|
+
except: pass
|
|
256690
|
+
if not gps_confirmed:
|
|
256691
|
+
try:
|
|
256692
|
+
with serial.Serial(c["device"], 9600, timeout=2) as ser:
|
|
256693
|
+
ser.reset_input_buffer()
|
|
256694
|
+
for _ in range(20):
|
|
256695
|
+
line = ser.readline().decode(errors="ignore").strip()
|
|
256696
|
+
if line.startswith("$G"):
|
|
256697
|
+
c["nmea_confirmed"] = True
|
|
256698
|
+
gps_confirmed = c["device"]
|
|
256699
|
+
break
|
|
256700
|
+
except: pass
|
|
256701
|
+
|
|
256702
|
+
print(json.dumps({"success": True, "candidates": candidates, "gps_confirmed": gps_confirmed}))
|
|
256703
|
+
except Exception as e:
|
|
256704
|
+
print(json.dumps({"success": False, "error": str(e)}))
|
|
256705
|
+
`, 15e3);
|
|
256706
|
+
if (!result.success) {
|
|
256707
|
+
return { success: false, output: "", error: `GPS detect failed: ${result.error}`, durationMs: performance.now() - start2 };
|
|
256708
|
+
}
|
|
256709
|
+
const candidates = result.candidates || [];
|
|
256710
|
+
if (candidates.length === 0) {
|
|
256711
|
+
return { success: true, output: "No GPS devices detected. Connect a USB GPS receiver (BU-353N, BU-363, U-blox 7, etc.).", durationMs: performance.now() - start2 };
|
|
256712
|
+
}
|
|
256713
|
+
const lines = candidates.map((c7) => ` ${c7.device}: ${c7.label}${c7.nmea_confirmed ? " \u2713 NMEA confirmed" : ""} (score: ${c7.score})`);
|
|
256714
|
+
return {
|
|
256715
|
+
success: true,
|
|
256716
|
+
output: `GPS device(s) found:
|
|
256717
|
+
${lines.join("\n")}` + (result.gps_confirmed ? `
|
|
256718
|
+
|
|
256719
|
+
Confirmed GPS on: ${result.gps_confirmed} (NMEA sentences detected)` : "\n\nNo NMEA confirmed yet \u2014 device may need time to initialize."),
|
|
256720
|
+
durationMs: performance.now() - start2
|
|
256721
|
+
};
|
|
256722
|
+
} catch (err) {
|
|
256723
|
+
return this.detectGpsFallback(start2);
|
|
256724
|
+
}
|
|
256725
|
+
}
|
|
256726
|
+
/** Fallback detection using lsusb + udevadm (no Python) */
|
|
256727
|
+
detectGpsFallback(start2) {
|
|
256580
256728
|
const devices = [];
|
|
256581
256729
|
try {
|
|
256582
256730
|
const lsusb = execSync36("lsusb 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
256583
256731
|
for (const known of GPS_USB_IDS) {
|
|
256584
256732
|
if (lsusb.toLowerCase().includes(`${known.vid}:${known.pid}`)) {
|
|
256585
|
-
|
|
256586
|
-
devices.push(` USB: ${known.name} \u2014 ${line?.trim() || `${known.vid}:${known.pid}`}`);
|
|
256587
|
-
}
|
|
256588
|
-
}
|
|
256589
|
-
for (const line of lsusb.split("\n")) {
|
|
256590
|
-
if (/gps|gnss|navsat/i.test(line) && !devices.some((d2) => d2.includes(line.trim()))) {
|
|
256591
|
-
devices.push(` USB: ${line.trim()}`);
|
|
256733
|
+
devices.push(` ${known.name}`);
|
|
256592
256734
|
}
|
|
256593
256735
|
}
|
|
256594
256736
|
} catch {
|
|
256595
256737
|
}
|
|
256596
|
-
|
|
256597
|
-
|
|
256598
|
-
|
|
256599
|
-
|
|
256600
|
-
|
|
256601
|
-
} catch {
|
|
256602
|
-
}
|
|
256603
|
-
}
|
|
256604
|
-
for (const dev of serialDevs) {
|
|
256605
|
-
try {
|
|
256606
|
-
const udev = execSync36(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
|
|
256607
|
-
const vendor = udev.match(/ID_VENDOR=(.+)/)?.[1] || "";
|
|
256608
|
-
const model = udev.match(/ID_MODEL=(.+)/)?.[1] || "";
|
|
256609
|
-
const serial = udev.match(/ID_SERIAL_SHORT=(.+)/)?.[1] || "";
|
|
256610
|
-
const isGps = GPS_USB_IDS.some((g) => udev.toLowerCase().includes(g.vid)) || /gps|gnss|prolific|cp210x|u-blox|ublox|sirf/i.test(udev);
|
|
256611
|
-
if (isGps) {
|
|
256612
|
-
devices.push(` Serial: ${dev} \u2014 ${model || vendor} ${serial ? `(SN: ${serial})` : ""}`);
|
|
256738
|
+
try {
|
|
256739
|
+
const serialDevs = execSync36("ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim().split("\n").filter(Boolean);
|
|
256740
|
+
for (const dev of serialDevs) {
|
|
256741
|
+
if (!devices.some((d2) => d2.includes(dev))) {
|
|
256742
|
+
devices.push(` Serial: ${dev} (unidentified \u2014 may be GPS)`);
|
|
256613
256743
|
}
|
|
256614
|
-
} catch {
|
|
256615
256744
|
}
|
|
256616
|
-
}
|
|
256617
|
-
let gpsdRunning = false;
|
|
256618
|
-
try {
|
|
256619
|
-
execSync36("pgrep gpsd", { timeout: 3e3, stdio: "pipe" });
|
|
256620
|
-
gpsdRunning = true;
|
|
256621
|
-
devices.push(" Service: gpsd is running");
|
|
256622
256745
|
} catch {
|
|
256623
256746
|
}
|
|
256624
|
-
if (devices.length === 0) {
|
|
256625
|
-
return {
|
|
256626
|
-
success: true,
|
|
256627
|
-
output: "No GPS devices detected. Connect a USB GPS receiver (BU-353N, U-blox 7, etc.)." + (serialDevs.length > 0 ? `
|
|
256628
|
-
|
|
256629
|
-
Serial devices found but not identified as GPS: ${serialDevs.join(", ")}` : ""),
|
|
256630
|
-
durationMs: performance.now() - start2
|
|
256631
|
-
};
|
|
256632
|
-
}
|
|
256633
256747
|
return {
|
|
256634
256748
|
success: true,
|
|
256635
|
-
output: `GPS devices
|
|
256636
|
-
${devices.join("\n")}`
|
|
256749
|
+
output: devices.length > 0 ? `Potential GPS devices:
|
|
256750
|
+
${devices.join("\n")}` : "No GPS devices found. Connect a USB GPS receiver.",
|
|
256637
256751
|
durationMs: performance.now() - start2
|
|
256638
256752
|
};
|
|
256639
256753
|
}
|
|
@@ -256679,42 +256793,150 @@ Raw: ${JSON.stringify(fix)}`,
|
|
|
256679
256793
|
} catch {
|
|
256680
256794
|
}
|
|
256681
256795
|
}
|
|
256682
|
-
return this.
|
|
256796
|
+
return this.getFixPyserial(args, start2);
|
|
256683
256797
|
}
|
|
256684
|
-
/**
|
|
256685
|
-
|
|
256686
|
-
const device = args["device"] ||
|
|
256687
|
-
if (!device) {
|
|
256688
|
-
return { success: false, output: "", error: "No GPS device found. Connect a USB GPS receiver.", durationMs: performance.now() - start2 };
|
|
256689
|
-
}
|
|
256798
|
+
/** Get GPS fix using pyserial+pynmea2 — proven stack from gps_service/server.py */
|
|
256799
|
+
async getFixPyserial(args, start2) {
|
|
256800
|
+
const device = args["device"] || "";
|
|
256690
256801
|
const timeout2 = args["timeout"] || 30;
|
|
256691
|
-
const baud = this.detectBaud(device);
|
|
256692
256802
|
try {
|
|
256693
|
-
|
|
256694
|
-
|
|
256695
|
-
|
|
256696
|
-
|
|
256697
|
-
|
|
256698
|
-
|
|
256699
|
-
|
|
256700
|
-
|
|
256701
|
-
|
|
256803
|
+
const result = await this.runGpsPython(`
|
|
256804
|
+
import json, sys, time
|
|
256805
|
+
import serial
|
|
256806
|
+
import pynmea2
|
|
256807
|
+
|
|
256808
|
+
def guess_port():
|
|
256809
|
+
try:
|
|
256810
|
+
from serial.tools import list_ports
|
|
256811
|
+
for p in list_ports.comports():
|
|
256812
|
+
dev = p.device or ""
|
|
256813
|
+
desc = (p.description or "").lower()
|
|
256814
|
+
vid = getattr(p, 'vid', None)
|
|
256815
|
+
if vid in (0x1546, 0x091e, 0x067b, 0x0403, 0x10c4, 0x1a86, 0x2c7c, 0x152a, 0x0df7):
|
|
256816
|
+
return dev, vid
|
|
256817
|
+
if "gps" in desc or "gnss" in desc:
|
|
256818
|
+
return dev, vid
|
|
256819
|
+
if "ttyUSB" in dev:
|
|
256820
|
+
return dev, vid
|
|
256821
|
+
return None, None
|
|
256822
|
+
except:
|
|
256823
|
+
import os
|
|
256824
|
+
for p in ("/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyACM0"):
|
|
256825
|
+
if os.path.exists(p):
|
|
256826
|
+
return p, None
|
|
256827
|
+
return None, None
|
|
256828
|
+
|
|
256829
|
+
port = "${device}" if "${device}" else None
|
|
256830
|
+
vid = None
|
|
256831
|
+
if not port:
|
|
256832
|
+
port, vid = guess_port()
|
|
256833
|
+
if not port:
|
|
256834
|
+
print(json.dumps({"success": False, "error": "No GPS serial device found. Connect a USB GPS receiver."}))
|
|
256835
|
+
sys.exit(0)
|
|
256836
|
+
|
|
256837
|
+
# Try common baud rates \u2014 BU-353/363 use 4800, U-blox uses 9600
|
|
256838
|
+
last_lat = last_lon = last_alt = last_sats = last_hdop = last_speed = last_track = None
|
|
256839
|
+
fix_valid = False
|
|
256840
|
+
raw_sentences = []
|
|
256841
|
+
found_nmea = False
|
|
256842
|
+
|
|
256843
|
+
for baud in [4800, 9600, 38400, 115200]:
|
|
256844
|
+
try:
|
|
256845
|
+
with serial.Serial(port, baud, timeout=2) as ser:
|
|
256846
|
+
ser.reset_input_buffer()
|
|
256847
|
+
deadline = time.time() + min(${timeout2}, 15)
|
|
256848
|
+
while time.time() < deadline:
|
|
256849
|
+
try:
|
|
256850
|
+
line = ser.readline().decode(errors="ignore").strip()
|
|
256851
|
+
except: continue
|
|
256852
|
+
if not line.startswith("$"):
|
|
256853
|
+
continue
|
|
256854
|
+
found_nmea = True
|
|
256855
|
+
raw_sentences.append(line)
|
|
256856
|
+
|
|
256857
|
+
try:
|
|
256858
|
+
msg = pynmea2.parse(line, check=True)
|
|
256859
|
+
except: continue
|
|
256860
|
+
|
|
256861
|
+
if msg.sentence_type == "GGA":
|
|
256862
|
+
try:
|
|
256863
|
+
fix_valid = int(getattr(msg, 'gps_qual', 0) or 0) > 0
|
|
256864
|
+
if msg.latitude is not None: last_lat = float(msg.latitude)
|
|
256865
|
+
if msg.longitude is not None: last_lon = float(msg.longitude)
|
|
256866
|
+
if msg.altitude not in (None, ""): last_alt = float(msg.altitude)
|
|
256867
|
+
if msg.num_sats not in (None, ""): last_sats = int(msg.num_sats)
|
|
256868
|
+
if msg.horizontal_dil not in (None, ""): last_hdop = float(msg.horizontal_dil)
|
|
256869
|
+
except: pass
|
|
256870
|
+
|
|
256871
|
+
elif msg.sentence_type == "RMC":
|
|
256872
|
+
try:
|
|
256873
|
+
rmc_valid = getattr(msg, 'status', '') == 'A'
|
|
256874
|
+
if rmc_valid: fix_valid = True
|
|
256875
|
+
if msg.latitude is not None: last_lat = float(msg.latitude)
|
|
256876
|
+
if msg.longitude is not None: last_lon = float(msg.longitude)
|
|
256877
|
+
if msg.spd_over_grnd not in (None, ""): last_speed = float(msg.spd_over_grnd)
|
|
256878
|
+
if msg.true_course not in (None, ""): last_track = float(msg.true_course)
|
|
256879
|
+
except: pass
|
|
256880
|
+
|
|
256881
|
+
# If we have a valid fix with lat/lon, we're done
|
|
256882
|
+
if fix_valid and last_lat is not None and last_lon is not None:
|
|
256883
|
+
break
|
|
256884
|
+
|
|
256885
|
+
if found_nmea:
|
|
256886
|
+
break # found NMEA at this baud rate, stop trying others
|
|
256887
|
+
except Exception as e:
|
|
256888
|
+
continue
|
|
256889
|
+
|
|
256890
|
+
if not found_nmea:
|
|
256891
|
+
print(json.dumps({"success": False, "error": f"No NMEA data from {port}. Device may not be a GPS or needs different permissions."}))
|
|
256892
|
+
elif last_lat is None or last_lon is None:
|
|
256893
|
+
print(json.dumps({
|
|
256894
|
+
"success": True,
|
|
256895
|
+
"fix": False,
|
|
256896
|
+
"port": port,
|
|
256897
|
+
"baud": baud,
|
|
256898
|
+
"message": f"GPS on {port} responding but no fix yet. Sentences seen: {len(raw_sentences)}. Try again \u2014 cold start takes 30-60s.",
|
|
256899
|
+
"sample_nmea": raw_sentences[:3],
|
|
256900
|
+
}))
|
|
256901
|
+
else:
|
|
256902
|
+
print(json.dumps({
|
|
256903
|
+
"success": True,
|
|
256904
|
+
"fix": True,
|
|
256905
|
+
"port": port,
|
|
256906
|
+
"baud": baud,
|
|
256907
|
+
"lat": last_lat,
|
|
256908
|
+
"lon": last_lon,
|
|
256909
|
+
"alt_m": last_alt,
|
|
256910
|
+
"speed_knots": last_speed,
|
|
256911
|
+
"track_deg": last_track,
|
|
256912
|
+
"sats": last_sats,
|
|
256913
|
+
"hdop": last_hdop,
|
|
256914
|
+
"fix_valid": fix_valid,
|
|
256915
|
+
"sentences_read": len(raw_sentences),
|
|
256916
|
+
}))
|
|
256917
|
+
`, (timeout2 + 20) * 1e3);
|
|
256918
|
+
if (!result.success) {
|
|
256919
|
+
return { success: false, output: "", error: result.error || "GPS fix failed", durationMs: performance.now() - start2 };
|
|
256920
|
+
}
|
|
256921
|
+
if (!result.fix) {
|
|
256922
|
+
return { success: true, output: result.message + (result.sample_nmea ? `
|
|
256923
|
+
|
|
256924
|
+
Sample: ${result.sample_nmea.join("\n")}` : ""), durationMs: performance.now() - start2 };
|
|
256925
|
+
}
|
|
256702
256926
|
return {
|
|
256703
256927
|
success: true,
|
|
256704
|
-
output: `GPS Fix (
|
|
256705
|
-
Position: ${
|
|
256706
|
-
Altitude: ${
|
|
256707
|
-
|
|
256708
|
-
|
|
256709
|
-
|
|
256710
|
-
|
|
256711
|
-
|
|
256712
|
-
Raw GGA: ${gga || "none"}
|
|
256713
|
-
Raw RMC: ${rmc || "none"}`,
|
|
256928
|
+
output: `GPS Fix (${result.port} @ ${result.baud} baud):
|
|
256929
|
+
Position: ${result.lat}, ${result.lon}
|
|
256930
|
+
Altitude: ${result.alt_m != null ? result.alt_m + "m" : "unknown"}
|
|
256931
|
+
Speed: ${result.speed_knots != null ? (result.speed_knots * 1.852).toFixed(1) + " km/h" : "unknown"}
|
|
256932
|
+
Heading: ${result.track_deg != null ? result.track_deg + "\xB0" : "unknown"}
|
|
256933
|
+
Satellites: ${result.sats ?? "unknown"}${result.hdop ? ` (HDOP: ${result.hdop})` : ""}
|
|
256934
|
+
Fix valid: ${result.fix_valid ? "yes" : "no"}
|
|
256935
|
+
Sentences read: ${result.sentences_read}`,
|
|
256714
256936
|
durationMs: performance.now() - start2
|
|
256715
256937
|
};
|
|
256716
256938
|
} catch (err) {
|
|
256717
|
-
return { success: false, output: "", error: `
|
|
256939
|
+
return { success: false, output: "", error: `GPS fix error: ${err instanceof Error ? err.message : String(err)}`, durationMs: performance.now() - start2 };
|
|
256718
256940
|
}
|
|
256719
256941
|
}
|
|
256720
256942
|
// =========================================================================
|
|
@@ -258250,10 +258472,10 @@ var init_client3 = __esm({
|
|
|
258250
258472
|
// packages/execution/dist/mcp/manager.js
|
|
258251
258473
|
import { existsSync as existsSync36, readFileSync as readFileSync26 } from "node:fs";
|
|
258252
258474
|
import { join as join50 } from "node:path";
|
|
258253
|
-
import { homedir as
|
|
258475
|
+
import { homedir as homedir14 } from "node:os";
|
|
258254
258476
|
function loadMcpConfig(repoRoot) {
|
|
258255
258477
|
const servers = {};
|
|
258256
|
-
const globalPath = join50(
|
|
258478
|
+
const globalPath = join50(homedir14(), ".open-agents", "mcp.json");
|
|
258257
258479
|
if (existsSync36(globalPath)) {
|
|
258258
258480
|
try {
|
|
258259
258481
|
const global2 = JSON.parse(readFileSync26(globalPath, "utf8"));
|
|
@@ -258557,10 +258779,10 @@ var init_mcp = __esm({
|
|
|
258557
258779
|
// packages/execution/dist/plugins/plugin-system.js
|
|
258558
258780
|
import { existsSync as existsSync37, readdirSync as readdirSync7, readFileSync as readFileSync27 } from "node:fs";
|
|
258559
258781
|
import { join as join51 } from "node:path";
|
|
258560
|
-
import { homedir as
|
|
258782
|
+
import { homedir as homedir15 } from "node:os";
|
|
258561
258783
|
function discoverPlugins(repoRoot) {
|
|
258562
258784
|
const plugins = [];
|
|
258563
|
-
const globalDir = join51(
|
|
258785
|
+
const globalDir = join51(homedir15(), ".open-agents", "plugins");
|
|
258564
258786
|
if (existsSync37(globalDir)) {
|
|
258565
258787
|
plugins.push(...loadPluginsFromDir(globalDir));
|
|
258566
258788
|
}
|
|
@@ -259987,10 +260209,10 @@ var init_buildRunner = __esm({
|
|
|
259987
260209
|
// packages/execution/dist/constraints.js
|
|
259988
260210
|
import { existsSync as existsSync42, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync18 } from "node:fs";
|
|
259989
260211
|
import { join as join55 } from "node:path";
|
|
259990
|
-
import { homedir as
|
|
260212
|
+
import { homedir as homedir16 } from "node:os";
|
|
259991
260213
|
function loadConstraints(projectRoot) {
|
|
259992
260214
|
projectConstraints = loadFile(join55(projectRoot, ".oa", "constraints.json"));
|
|
259993
|
-
globalConstraints = loadFile(join55(
|
|
260215
|
+
globalConstraints = loadFile(join55(homedir16(), ".open-agents", "constraints.json"));
|
|
259994
260216
|
}
|
|
259995
260217
|
function loadFile(path5) {
|
|
259996
260218
|
try {
|
|
@@ -270007,7 +270229,7 @@ __export(listen_exports, {
|
|
|
270007
270229
|
import { spawn as spawn17, execSync as execSync41 } from "node:child_process";
|
|
270008
270230
|
import { existsSync as existsSync45, mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readdirSync as readdirSync9 } from "node:fs";
|
|
270009
270231
|
import { join as join60, dirname as dirname16 } from "node:path";
|
|
270010
|
-
import { homedir as
|
|
270232
|
+
import { homedir as homedir17 } from "node:os";
|
|
270011
270233
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
270012
270234
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
270013
270235
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -270117,7 +270339,7 @@ function findLiveWhisperScript() {
|
|
|
270117
270339
|
}
|
|
270118
270340
|
} catch {
|
|
270119
270341
|
}
|
|
270120
|
-
const nvmBase = join60(
|
|
270342
|
+
const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
|
|
270121
270343
|
if (existsSync45(nvmBase)) {
|
|
270122
270344
|
try {
|
|
270123
270345
|
for (const ver of readdirSync9(nvmBase)) {
|
|
@@ -270365,7 +270587,7 @@ var init_listen = __esm({
|
|
|
270365
270587
|
}
|
|
270366
270588
|
} catch {
|
|
270367
270589
|
}
|
|
270368
|
-
const nvmBase = join60(
|
|
270590
|
+
const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
|
|
270369
270591
|
if (existsSync45(nvmBase)) {
|
|
270370
270592
|
try {
|
|
270371
270593
|
const { readdirSync: readdirSync26 } = await import("node:fs");
|
|
@@ -280191,7 +280413,7 @@ __export(oa_directory_exports, {
|
|
|
280191
280413
|
});
|
|
280192
280414
|
import { existsSync as existsSync49, mkdirSync as mkdirSync22, readFileSync as readFileSync37, writeFileSync as writeFileSync22, readdirSync as readdirSync11, statSync as statSync16, unlinkSync as unlinkSync11 } from "node:fs";
|
|
280193
280415
|
import { join as join65, relative as relative4, basename as basename12 } from "node:path";
|
|
280194
|
-
import { homedir as
|
|
280416
|
+
import { homedir as homedir18 } from "node:os";
|
|
280195
280417
|
function initOaDirectory(repoRoot) {
|
|
280196
280418
|
const oaPath = join65(repoRoot, OA_DIR);
|
|
280197
280419
|
for (const sub of SUBDIRS) {
|
|
@@ -280231,7 +280453,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
280231
280453
|
writeFileSync22(join65(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
280232
280454
|
}
|
|
280233
280455
|
function loadGlobalSettings() {
|
|
280234
|
-
const settingsPath = join65(
|
|
280456
|
+
const settingsPath = join65(homedir18(), ".open-agents", "settings.json");
|
|
280235
280457
|
try {
|
|
280236
280458
|
if (existsSync49(settingsPath)) {
|
|
280237
280459
|
return JSON.parse(readFileSync37(settingsPath, "utf-8"));
|
|
@@ -280241,7 +280463,7 @@ function loadGlobalSettings() {
|
|
|
280241
280463
|
return {};
|
|
280242
280464
|
}
|
|
280243
280465
|
function saveGlobalSettings(settings) {
|
|
280244
|
-
const dir = join65(
|
|
280466
|
+
const dir = join65(homedir18(), ".open-agents");
|
|
280245
280467
|
mkdirSync22(dir, { recursive: true });
|
|
280246
280468
|
const existing = loadGlobalSettings();
|
|
280247
280469
|
const merged = { ...existing, ...settings };
|
|
@@ -280739,13 +280961,13 @@ function recordUsage(kind, value2, opts) {
|
|
|
280739
280961
|
}
|
|
280740
280962
|
saveUsageFile(filePath, data);
|
|
280741
280963
|
};
|
|
280742
|
-
update2(join65(
|
|
280964
|
+
update2(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
|
|
280743
280965
|
if (opts?.repoRoot) {
|
|
280744
280966
|
update2(join65(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
280745
280967
|
}
|
|
280746
280968
|
}
|
|
280747
280969
|
function loadUsageHistory(kind, repoRoot) {
|
|
280748
|
-
const globalPath = join65(
|
|
280970
|
+
const globalPath = join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE);
|
|
280749
280971
|
const globalData = loadUsageFile(globalPath);
|
|
280750
280972
|
const localData = repoRoot ? loadUsageFile(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
280751
280973
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -280776,7 +280998,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
280776
280998
|
saveUsageFile(filePath, data);
|
|
280777
280999
|
}
|
|
280778
281000
|
};
|
|
280779
|
-
remove(join65(
|
|
281001
|
+
remove(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
|
|
280780
281002
|
if (repoRoot) {
|
|
280781
281003
|
remove(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
280782
281004
|
}
|
|
@@ -285332,7 +285554,7 @@ __export(personaplex_exports, {
|
|
|
285332
285554
|
});
|
|
285333
285555
|
import { existsSync as existsSync50, writeFileSync as writeFileSync23, readFileSync as readFileSync39, mkdirSync as mkdirSync23, copyFileSync as copyFileSync2, readdirSync as readdirSync12, statSync as statSync17 } from "node:fs";
|
|
285334
285556
|
import { join as join66, dirname as dirname20 } from "node:path";
|
|
285335
|
-
import { homedir as
|
|
285557
|
+
import { homedir as homedir19 } from "node:os";
|
|
285336
285558
|
import { execSync as execSync44, spawn as spawn20 } from "node:child_process";
|
|
285337
285559
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
285338
285560
|
function execAsync(cmd, opts = {}) {
|
|
@@ -285927,7 +286149,7 @@ print('Converted')
|
|
|
285927
286149
|
let ollamaModel = process.env["HYBRID_LLM_MODEL"] || "";
|
|
285928
286150
|
if (!ollamaModel) {
|
|
285929
286151
|
try {
|
|
285930
|
-
const oaConfig = JSON.parse(readFileSync39(join66(
|
|
286152
|
+
const oaConfig = JSON.parse(readFileSync39(join66(homedir19(), ".open-agents", "config.json"), "utf8"));
|
|
285931
286153
|
if (oaConfig.model) ollamaModel = oaConfig.model;
|
|
285932
286154
|
} catch {
|
|
285933
286155
|
}
|
|
@@ -286198,7 +286420,7 @@ function provisionShippedVoices(onInfo) {
|
|
|
286198
286420
|
return deployed;
|
|
286199
286421
|
}
|
|
286200
286422
|
function getHFVoicesDir() {
|
|
286201
|
-
const hfBase = join66(
|
|
286423
|
+
const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
286202
286424
|
if (!existsSync50(hfBase)) return null;
|
|
286203
286425
|
try {
|
|
286204
286426
|
const snapshots = join66(hfBase, "snapshots");
|
|
@@ -286214,7 +286436,7 @@ function getHFVoicesDir() {
|
|
|
286214
286436
|
function patchFrontendVoiceList(onInfo) {
|
|
286215
286437
|
const log22 = onInfo ?? (() => {
|
|
286216
286438
|
});
|
|
286217
|
-
const hfBase = join66(
|
|
286439
|
+
const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
286218
286440
|
if (!existsSync50(hfBase)) return;
|
|
286219
286441
|
try {
|
|
286220
286442
|
const snapshots = join66(hfBase, "snapshots");
|
|
@@ -286292,7 +286514,7 @@ var init_personaplex = __esm({
|
|
|
286292
286514
|
nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
|
|
286293
286515
|
"nf4-distilled": { repo: "cudabenchmarktest/personaplex-7b-nf4-distilled", file: "student_best.pt", sizeGB: 16.7, needsToken: false }
|
|
286294
286516
|
};
|
|
286295
|
-
PERSONAPLEX_DIR = join66(
|
|
286517
|
+
PERSONAPLEX_DIR = join66(homedir19(), ".open-agents", "voice", "personaplex");
|
|
286296
286518
|
PID_FILE = join66(PERSONAPLEX_DIR, "daemon.pid");
|
|
286297
286519
|
PORT_FILE = join66(PERSONAPLEX_DIR, "daemon.port");
|
|
286298
286520
|
LOG_FILE = join66(PERSONAPLEX_DIR, "daemon.log");
|
|
@@ -286339,7 +286561,7 @@ import { execSync as execSync45, spawn as spawn21, exec as exec4 } from "node:ch
|
|
|
286339
286561
|
import { promisify as promisify7 } from "node:util";
|
|
286340
286562
|
import { existsSync as existsSync51, writeFileSync as writeFileSync24, readFileSync as readFileSync40, appendFileSync as appendFileSync2, mkdirSync as mkdirSync24 } from "node:fs";
|
|
286341
286563
|
import { join as join67 } from "node:path";
|
|
286342
|
-
import { homedir as
|
|
286564
|
+
import { homedir as homedir20, platform as platform3 } from "node:os";
|
|
286343
286565
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
286344
286566
|
if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
|
|
286345
286567
|
try {
|
|
@@ -287438,7 +287660,7 @@ async function doSetup(config, rl) {
|
|
|
287438
287660
|
`PARAMETER num_predict ${numPredict}`,
|
|
287439
287661
|
`PARAMETER stop "<|endoftext|>"`
|
|
287440
287662
|
].join("\n");
|
|
287441
|
-
const modelDir2 = join67(
|
|
287663
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
287442
287664
|
mkdirSync24(modelDir2, { recursive: true });
|
|
287443
287665
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
287444
287666
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -287486,7 +287708,7 @@ async function isModelAvailable(config) {
|
|
|
287486
287708
|
}
|
|
287487
287709
|
function isFirstRun() {
|
|
287488
287710
|
try {
|
|
287489
|
-
return !existsSync51(join67(
|
|
287711
|
+
return !existsSync51(join67(homedir20(), ".open-agents", "config.json"));
|
|
287490
287712
|
} catch {
|
|
287491
287713
|
return true;
|
|
287492
287714
|
}
|
|
@@ -287534,7 +287756,7 @@ function detectPkgManager() {
|
|
|
287534
287756
|
return null;
|
|
287535
287757
|
}
|
|
287536
287758
|
function getVenvDir() {
|
|
287537
|
-
return join67(
|
|
287759
|
+
return join67(homedir20(), ".open-agents", "venv");
|
|
287538
287760
|
}
|
|
287539
287761
|
function hasVenvModule() {
|
|
287540
287762
|
try {
|
|
@@ -287560,7 +287782,7 @@ function ensureVenv(log22) {
|
|
|
287560
287782
|
return null;
|
|
287561
287783
|
}
|
|
287562
287784
|
try {
|
|
287563
|
-
mkdirSync24(join67(
|
|
287785
|
+
mkdirSync24(join67(homedir20(), ".open-agents"), { recursive: true });
|
|
287564
287786
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
287565
287787
|
execSync45(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
287566
287788
|
execSync45(`"${pipPath}" install --upgrade pip`, {
|
|
@@ -287660,7 +287882,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
287660
287882
|
];
|
|
287661
287883
|
{
|
|
287662
287884
|
const pm2 = detectPkgManager();
|
|
287663
|
-
const _visionMarkerDir = join67(
|
|
287885
|
+
const _visionMarkerDir = join67(homedir20(), ".open-agents");
|
|
287664
287886
|
const _visionMarkerFile = join67(_visionMarkerDir, "vision-deps-installed.json");
|
|
287665
287887
|
let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
|
|
287666
287888
|
try {
|
|
@@ -287913,11 +288135,11 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
287913
288135
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
287914
288136
|
try {
|
|
287915
288137
|
execSync45(
|
|
287916
|
-
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${
|
|
288138
|
+
`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir20()}/.local/bin" && mv /tmp/cloudflared "${homedir20()}/.local/bin/cloudflared"`,
|
|
287917
288139
|
{ stdio: "pipe", timeout: 6e4 }
|
|
287918
288140
|
);
|
|
287919
|
-
if (!process.env.PATH?.includes(`${
|
|
287920
|
-
process.env.PATH = `${
|
|
288141
|
+
if (!process.env.PATH?.includes(`${homedir20()}/.local/bin`)) {
|
|
288142
|
+
process.env.PATH = `${homedir20()}/.local/bin:${process.env.PATH}`;
|
|
287921
288143
|
}
|
|
287922
288144
|
if (hasCmd("cloudflared")) {
|
|
287923
288145
|
log22("cloudflared installed.");
|
|
@@ -288014,7 +288236,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
288014
288236
|
`PARAMETER num_predict ${numPredict}`,
|
|
288015
288237
|
`PARAMETER stop "<|endoftext|>"`
|
|
288016
288238
|
].join("\n");
|
|
288017
|
-
const modelDir2 = join67(
|
|
288239
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
288018
288240
|
mkdirSync24(modelDir2, { recursive: true });
|
|
288019
288241
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
288020
288242
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -288039,7 +288261,7 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
288039
288261
|
`PARAMETER num_predict ${numPredict}`,
|
|
288040
288262
|
`PARAMETER stop "<|endoftext|>"`
|
|
288041
288263
|
].join("\n");
|
|
288042
|
-
const modelDir2 = join67(
|
|
288264
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
288043
288265
|
mkdirSync24(modelDir2, { recursive: true });
|
|
288044
288266
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
288045
288267
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -288115,7 +288337,7 @@ async function ensureNeovim() {
|
|
|
288115
288337
|
const platform6 = process.platform;
|
|
288116
288338
|
const arch2 = process.arch;
|
|
288117
288339
|
if (platform6 === "linux") {
|
|
288118
|
-
const binDir = join67(
|
|
288340
|
+
const binDir = join67(homedir20(), ".local", "bin");
|
|
288119
288341
|
const nvimDest = join67(binDir, "nvim");
|
|
288120
288342
|
try {
|
|
288121
288343
|
mkdirSync24(binDir, { recursive: true });
|
|
@@ -288187,7 +288409,7 @@ async function ensureNeovim() {
|
|
|
288187
288409
|
}
|
|
288188
288410
|
function ensurePathInShellRc(binDir) {
|
|
288189
288411
|
const shell = process.env.SHELL ?? "";
|
|
288190
|
-
const rcFile = shell.includes("zsh") ? join67(
|
|
288412
|
+
const rcFile = shell.includes("zsh") ? join67(homedir20(), ".zshrc") : join67(homedir20(), ".bashrc");
|
|
288191
288413
|
try {
|
|
288192
288414
|
const rcContent = existsSync51(rcFile) ? readFileSync40(rcFile, "utf8") : "";
|
|
288193
288415
|
if (rcContent.includes(binDir)) return;
|
|
@@ -288930,7 +289152,7 @@ __export(daemon_exports, {
|
|
|
288930
289152
|
import { spawn as spawn22 } from "node:child_process";
|
|
288931
289153
|
import { existsSync as existsSync54, readFileSync as readFileSync41, writeFileSync as writeFileSync25, mkdirSync as mkdirSync25, unlinkSync as unlinkSync13 } from "node:fs";
|
|
288932
289154
|
import { join as join69 } from "node:path";
|
|
288933
|
-
import { homedir as
|
|
289155
|
+
import { homedir as homedir21 } from "node:os";
|
|
288934
289156
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
288935
289157
|
import { dirname as dirname21 } from "node:path";
|
|
288936
289158
|
function getDaemonPort() {
|
|
@@ -289081,7 +289303,7 @@ var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
|
|
|
289081
289303
|
var init_daemon = __esm({
|
|
289082
289304
|
"packages/cli/src/daemon.ts"() {
|
|
289083
289305
|
"use strict";
|
|
289084
|
-
OA_DIR2 = join69(
|
|
289306
|
+
OA_DIR2 = join69(homedir21(), ".open-agents");
|
|
289085
289307
|
PID_FILE2 = join69(OA_DIR2, "daemon.pid");
|
|
289086
289308
|
DEFAULT_PORT2 = 11435;
|
|
289087
289309
|
}
|
|
@@ -290381,7 +290603,7 @@ __export(voice_exports, {
|
|
|
290381
290603
|
});
|
|
290382
290604
|
import { existsSync as existsSync56, mkdirSync as mkdirSync27, writeFileSync as writeFileSync27, readFileSync as readFileSync43, unlinkSync as unlinkSync14, readdirSync as readdirSync13, statSync as statSync18 } from "node:fs";
|
|
290383
290605
|
import { join as join71, dirname as dirname22 } from "node:path";
|
|
290384
|
-
import { homedir as
|
|
290606
|
+
import { homedir as homedir22, tmpdir as tmpdir15, platform as platform4 } from "node:os";
|
|
290385
290607
|
import { execSync as execSync47, spawn as nodeSpawn } from "node:child_process";
|
|
290386
290608
|
import { createRequire as createRequire2 } from "node:module";
|
|
290387
290609
|
function sanitizeForTTS(text) {
|
|
@@ -290405,7 +290627,7 @@ function listVoiceModels() {
|
|
|
290405
290627
|
}));
|
|
290406
290628
|
}
|
|
290407
290629
|
function voiceDir() {
|
|
290408
|
-
return join71(
|
|
290630
|
+
return join71(homedir22(), ".open-agents", "voice");
|
|
290409
290631
|
}
|
|
290410
290632
|
function modelsDir() {
|
|
290411
290633
|
return join71(voiceDir(), "models");
|
|
@@ -291337,7 +291559,7 @@ var init_voice = __esm({
|
|
|
291337
291559
|
}
|
|
291338
291560
|
p2 = p2.replace(/\\ /g, " ");
|
|
291339
291561
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
291340
|
-
p2 = join71(
|
|
291562
|
+
p2 = join71(homedir22(), p2.slice(1));
|
|
291341
291563
|
}
|
|
291342
291564
|
if (!existsSync56(p2)) {
|
|
291343
291565
|
return `File not found: ${p2}
|
|
@@ -292541,11 +292763,27 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
292541
292763
|
// ARM: install individually so we get clear error messages per package.
|
|
292542
292764
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
292543
292765
|
{ cmd: `${pipCmd} -m pip install --quiet "setuptools<81" wheel`, fatal: true, label: "setuptools" },
|
|
292544
|
-
// Jetson: try NVIDIA's prebuilt PyTorch wheel
|
|
292545
|
-
|
|
292546
|
-
|
|
292547
|
-
|
|
292548
|
-
|
|
292766
|
+
// Jetson: try NVIDIA's prebuilt PyTorch wheel for detected JetPack version.
|
|
292767
|
+
// JetPack versions have different PyTorch wheel URLs:
|
|
292768
|
+
// JP6.x: https://developer.download.nvidia.com/compute/redist/jp/v60/pytorch/
|
|
292769
|
+
// JP5.x: https://developer.download.nvidia.com/compute/redist/jp/v51/pytorch/
|
|
292770
|
+
// Auto-detect JetPack version from /etc/nv_tegra_release or dpkg.
|
|
292771
|
+
...isJetson ? (() => {
|
|
292772
|
+
let jpVer = "v60";
|
|
292773
|
+
try {
|
|
292774
|
+
const tegra = existsSync56("/etc/nv_tegra_release") ? execSync47("cat /etc/nv_tegra_release 2>/dev/null", { encoding: "utf8", timeout: 3e3 }).trim() : "";
|
|
292775
|
+
const dpkg = execSync47("dpkg -l nvidia-jetpack 2>/dev/null | grep nvidia-jetpack | awk '{print $3}'", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
292776
|
+
const ver = dpkg || process.env.JETSON_L4T_VERSION || "";
|
|
292777
|
+
if (ver.startsWith("5.") || tegra.includes("R35") || tegra.includes("R34")) jpVer = "v51";
|
|
292778
|
+
else if (ver.startsWith("6.1") || tegra.includes("R36.4")) jpVer = "v61";
|
|
292779
|
+
else if (ver.startsWith("6.") || tegra.includes("R36")) jpVer = "v60";
|
|
292780
|
+
} catch {
|
|
292781
|
+
}
|
|
292782
|
+
return [
|
|
292783
|
+
{ cmd: `${pipCmd} -m pip install --quiet torch torchvision torchaudio --index-url https://developer.download.nvidia.com/compute/redist/jp/${jpVer}/pytorch/ 2>/dev/null || ${pipCmd} -m pip install --quiet torch torchaudio`, fatal: true, label: `PyTorch (Jetson JP ${jpVer})` },
|
|
292784
|
+
{ cmd: `${pipCmd} -m pip install --quiet onnxruntime-gpu 2>/dev/null || true`, fatal: false, label: "onnxruntime-gpu (Jetson, optional)" }
|
|
292785
|
+
];
|
|
292786
|
+
})() : [
|
|
292549
292787
|
// Non-Jetson ARM: use default PyPI (has aarch64 wheels).
|
|
292550
292788
|
// DO NOT use --index-url https://download.pytorch.org/whl/cpu — that index
|
|
292551
292789
|
// only has x86_64 wheels. ARM needs the standard PyPI torch package.
|
|
@@ -292563,7 +292801,9 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
|
292563
292801
|
{ cmd: `${pipCmd} -m pip install --quiet lhotse`, fatal: true, label: "lhotse" },
|
|
292564
292802
|
// vocos: try pip, fallback to building from source if wheels missing
|
|
292565
292803
|
{ cmd: `${pipCmd} -m pip install --quiet vocos 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation vocos`, fatal: true, label: "vocos" },
|
|
292566
|
-
|
|
292804
|
+
// LinaCodec: needs C++ build tools on ARM. Install with --no-build-isolation
|
|
292805
|
+
// and fallback to CPU-only if CUDA compilation fails.
|
|
292806
|
+
{ cmd: `${pipCmd} -m pip install --quiet "git+https://github.com/ysharma3501/LinaCodec.git" 2>/dev/null || ${pipCmd} -m pip install --quiet --no-build-isolation "git+https://github.com/ysharma3501/LinaCodec.git"`, fatal: true, label: "LinaCodec (voice cloning codec)" },
|
|
292567
292807
|
// Non-fatal (not hard-imported by LuxTTS):
|
|
292568
292808
|
{ cmd: `${pipCmd} -m pip install --quiet piper-phonemize --find-links https://k2-fsa.github.io/icefall/piper_phonemize.html`, fatal: false, label: "piper-phonemize (optional)" },
|
|
292569
292809
|
{ cmd: `${pipCmd} -m pip install --quiet jieba pypinyin cn2an`, fatal: true, label: "Chinese text processing" },
|
|
@@ -293687,9 +293927,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293687
293927
|
renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
|
|
293688
293928
|
}
|
|
293689
293929
|
} else if (sub === "name") {
|
|
293690
|
-
const { homedir:
|
|
293930
|
+
const { homedir: homedir29 } = __require("node:os");
|
|
293691
293931
|
const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
|
|
293692
|
-
const namePath = __require("node:path").join(
|
|
293932
|
+
const namePath = __require("node:path").join(homedir29(), ".open-agents", "agent-name");
|
|
293693
293933
|
if (rest2) {
|
|
293694
293934
|
const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
|
|
293695
293935
|
if (!customName) {
|
|
@@ -295388,8 +295628,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
295388
295628
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
295389
295629
|
if (!sponsorName || sponsorName.length < 2) {
|
|
295390
295630
|
try {
|
|
295391
|
-
const { homedir:
|
|
295392
|
-
const namePath = __require("path").join(
|
|
295631
|
+
const { homedir: homedir29 } = __require("os");
|
|
295632
|
+
const namePath = __require("path").join(homedir29(), ".open-agents", "agent-name");
|
|
295393
295633
|
if (existsSync57(namePath)) sponsorName = readFileSync44(namePath, "utf8").trim();
|
|
295394
295634
|
} catch {
|
|
295395
295635
|
}
|
|
@@ -296849,9 +297089,9 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
296849
297089
|
}
|
|
296850
297090
|
const { basename: basename19, join: pathJoin } = await import("node:path");
|
|
296851
297091
|
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync43, existsSync: exists2 } = await import("node:fs");
|
|
296852
|
-
const { homedir:
|
|
297092
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
296853
297093
|
const modelName = basename19(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
296854
|
-
const destDir = pathJoin(
|
|
297094
|
+
const destDir = pathJoin(homedir29(), ".open-agents", "voice", "models", modelName);
|
|
296855
297095
|
if (!exists2(destDir)) mkdirSync43(destDir, { recursive: true });
|
|
296856
297096
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
296857
297097
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
@@ -299073,7 +299313,7 @@ var init_commands = __esm({
|
|
|
299073
299313
|
import { existsSync as existsSync58, readFileSync as readFileSync45, readdirSync as readdirSync15 } from "node:fs";
|
|
299074
299314
|
import { join as join73, basename as basename13 } from "node:path";
|
|
299075
299315
|
import { execSync as execSync48 } from "node:child_process";
|
|
299076
|
-
import { homedir as
|
|
299316
|
+
import { homedir as homedir24, platform as platform5, release } from "node:os";
|
|
299077
299317
|
function getModelTier(modelName) {
|
|
299078
299318
|
const m2 = modelName.toLowerCase();
|
|
299079
299319
|
const sizeMatch = m2.match(/\b(\d+)b\b/);
|
|
@@ -299152,7 +299392,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
299152
299392
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
299153
299393
|
if (legacyEntries) sections.push(legacyEntries);
|
|
299154
299394
|
}
|
|
299155
|
-
const globalMemDir = join73(
|
|
299395
|
+
const globalMemDir = join73(homedir24(), ".open-agents", "memory");
|
|
299156
299396
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
299157
299397
|
if (globalEntries) sections.push(globalEntries);
|
|
299158
299398
|
return sections.join("\n\n");
|
|
@@ -308443,10 +308683,10 @@ var init_usage_tracker = __esm({
|
|
|
308443
308683
|
// packages/cli/src/api/profiles.ts
|
|
308444
308684
|
import { existsSync as existsSync69, readFileSync as readFileSync55, writeFileSync as writeFileSync34, mkdirSync as mkdirSync37, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
|
|
308445
308685
|
import { join as join85 } from "node:path";
|
|
308446
|
-
import { homedir as
|
|
308686
|
+
import { homedir as homedir25 } from "node:os";
|
|
308447
308687
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
|
|
308448
308688
|
function globalProfileDir() {
|
|
308449
|
-
return join85(
|
|
308689
|
+
return join85(homedir25(), ".open-agents", "profiles");
|
|
308450
308690
|
}
|
|
308451
308691
|
function projectProfileDir(projectDir) {
|
|
308452
308692
|
return join85(projectDir || process.cwd(), ".oa", "profiles");
|
|
@@ -308638,7 +308878,7 @@ var init_profiles = __esm({
|
|
|
308638
308878
|
import { execSync as execSync50, spawn as spawn23 } from "node:child_process";
|
|
308639
308879
|
import { existsSync as existsSync70, mkdirSync as mkdirSync38, writeFileSync as writeFileSync35 } from "node:fs";
|
|
308640
308880
|
import { join as join86, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
308641
|
-
import { homedir as
|
|
308881
|
+
import { homedir as homedir26 } from "node:os";
|
|
308642
308882
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
308643
308883
|
function getDockerDir() {
|
|
308644
308884
|
try {
|
|
@@ -308786,7 +309026,7 @@ async function ensureOaImage(force = false) {
|
|
|
308786
309026
|
if (existsSync70(join86(dockerDir, "Dockerfile"))) {
|
|
308787
309027
|
buildContext = dockerDir;
|
|
308788
309028
|
} else {
|
|
308789
|
-
buildContext = join86(
|
|
309029
|
+
buildContext = join86(homedir26(), ".oa", "docker-build");
|
|
308790
309030
|
mkdirSync38(buildContext, { recursive: true });
|
|
308791
309031
|
writeDockerfiles(buildContext);
|
|
308792
309032
|
}
|
|
@@ -310859,7 +311099,7 @@ import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
|
310859
311099
|
import { readFileSync as readFileSync57, writeFileSync as writeFileSync37, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync40 } from "node:fs";
|
|
310860
311100
|
import { existsSync as existsSync72 } from "node:fs";
|
|
310861
311101
|
import { execSync as execSync52 } from "node:child_process";
|
|
310862
|
-
import { homedir as
|
|
311102
|
+
import { homedir as homedir27 } from "node:os";
|
|
310863
311103
|
function formatTimeAgo(date) {
|
|
310864
311104
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
310865
311105
|
if (seconds < 60) return "just now";
|
|
@@ -313421,7 +313661,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
313421
313661
|
const hits = allCompletions.filter((c7) => c7.toLowerCase().startsWith(lower));
|
|
313422
313662
|
return [hits, line];
|
|
313423
313663
|
}
|
|
313424
|
-
const HISTORY_DIR = join88(
|
|
313664
|
+
const HISTORY_DIR = join88(homedir27(), ".open-agents");
|
|
313425
313665
|
const HISTORY_FILE = join88(HISTORY_DIR, "repl-history");
|
|
313426
313666
|
const MAX_HISTORY_LINES = 500;
|
|
313427
313667
|
let savedHistory = [];
|
|
@@ -315207,7 +315447,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
315207
315447
|
} catch {
|
|
315208
315448
|
}
|
|
315209
315449
|
try {
|
|
315210
|
-
const voiceDir2 = join88(
|
|
315450
|
+
const voiceDir2 = join88(homedir27(), ".open-agents", "voice");
|
|
315211
315451
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
315212
315452
|
for (const pf of voicePidFiles) {
|
|
315213
315453
|
const pidPath = join88(voiceDir2, pf);
|
|
@@ -315320,8 +315560,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
315320
315560
|
try {
|
|
315321
315561
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
315322
315562
|
if (isPersonaPlexRunning2()) {
|
|
315323
|
-
const ppPidFile = join88(
|
|
315324
|
-
const ppPortFile = join88(
|
|
315563
|
+
const ppPidFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
315564
|
+
const ppPortFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
315325
315565
|
if (existsSync72(ppPidFile)) {
|
|
315326
315566
|
const ppPid = parseInt(readFileSync57(ppPidFile, "utf8").trim(), 10);
|
|
315327
315567
|
const ppPort = existsSync72(ppPortFile) ? parseInt(readFileSync57(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
@@ -317241,7 +317481,7 @@ __export(config_exports2, {
|
|
|
317241
317481
|
configCommand: () => configCommand
|
|
317242
317482
|
});
|
|
317243
317483
|
import { join as join91, resolve as resolve38 } from "node:path";
|
|
317244
|
-
import { homedir as
|
|
317484
|
+
import { homedir as homedir28 } from "node:os";
|
|
317245
317485
|
import { cwd as cwd3 } from "node:process";
|
|
317246
317486
|
function redactIfSensitive(key, value2) {
|
|
317247
317487
|
if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
|
|
@@ -317322,7 +317562,7 @@ function handleShow(opts, config) {
|
|
|
317322
317562
|
}
|
|
317323
317563
|
}
|
|
317324
317564
|
printSection("Config File");
|
|
317325
|
-
printInfo(`~/.open-agents/config.json (${join91(
|
|
317565
|
+
printInfo(`~/.open-agents/config.json (${join91(homedir28(), ".open-agents", "config.json")})`);
|
|
317326
317566
|
printSection("Priority Chain");
|
|
317327
317567
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
317328
317568
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -318127,8 +318367,8 @@ function crashLog(label, err) {
|
|
|
318127
318367
|
try {
|
|
318128
318368
|
const { appendFileSync: appendFileSync7, mkdirSync: mkdirSync43 } = __require("node:fs");
|
|
318129
318369
|
const { join: join94 } = __require("node:path");
|
|
318130
|
-
const { homedir:
|
|
318131
|
-
const logDir = join94(
|
|
318370
|
+
const { homedir: homedir29 } = __require("node:os");
|
|
318371
|
+
const logDir = join94(homedir29(), ".open-agents");
|
|
318132
318372
|
mkdirSync43(logDir, { recursive: true });
|
|
318133
318373
|
appendFileSync7(join94(logDir, "crash.log"), logLine);
|
|
318134
318374
|
} catch {
|
package/package.json
CHANGED