open-agents-ai 0.187.148 → 0.187.150
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 +371 -137
- 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"() {
|
|
@@ -256456,10 +256456,14 @@ var init_gps_location = __esm({
|
|
|
256456
256456
|
init_system_auth();
|
|
256457
256457
|
GPS_USB_IDS = [
|
|
256458
256458
|
// ── GlobalSat / BU-series (SiRF Star IV, Prolific UART bridge) ──────────
|
|
256459
|
-
|
|
256460
|
-
|
|
256461
|
-
{ vid: "067b", pid: "
|
|
256462
|
-
{ vid: "067b", pid: "
|
|
256459
|
+
// BU-353N, BU-353S4, BU-363, BU-503, BU-355 all use Prolific UART chips
|
|
256460
|
+
// The BU-363 specifically is a common USB GPS puck with SiRF Star IV
|
|
256461
|
+
{ vid: "067b", pid: "2303", name: "GlobalSat BU-353/363 (Prolific PL2303)", baud: 4800, notes: "Most popular USB GPS puck family" },
|
|
256462
|
+
{ vid: "067b", pid: "23a3", name: "GlobalSat BU-353S4/363 (Prolific PL2303GT)", baud: 4800 },
|
|
256463
|
+
{ vid: "067b", pid: "2304", name: "GlobalSat BU-series (Prolific PL2303HXD)", baud: 4800 },
|
|
256464
|
+
{ vid: "067b", pid: "aaa0", name: "GlobalSat BU-series (Prolific PL2303HX Rev A)", baud: 4800 },
|
|
256465
|
+
{ vid: "067b", pid: "aaa2", name: "GlobalSat BU-series (Prolific PL2303 var)", baud: 4800 },
|
|
256466
|
+
{ vid: "067b", pid: "2300", name: "Prolific PL2300 (GPS serial)", baud: 4800 },
|
|
256463
256467
|
// ── U-blox GNSS family (direct USB — ACM devices) ──────────────────────
|
|
256464
256468
|
{ vid: "1546", pid: "01a5", name: "U-blox 5 (LEA-5T)", baud: 9600 },
|
|
256465
256469
|
{ vid: "1546", pid: "01a6", name: "U-blox 6 (NEO-6M)", baud: 9600, notes: "Very common maker GPS" },
|
|
@@ -256545,13 +256549,63 @@ var init_gps_location = __esm({
|
|
|
256545
256549
|
},
|
|
256546
256550
|
required: ["action"]
|
|
256547
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
|
+
}
|
|
256548
256602
|
async execute(args) {
|
|
256549
256603
|
const action = args["action"];
|
|
256550
256604
|
const start2 = performance.now();
|
|
256551
256605
|
try {
|
|
256552
256606
|
switch (action) {
|
|
256553
256607
|
case "detect":
|
|
256554
|
-
return await this.detectGps(start2);
|
|
256608
|
+
return await this.detectGps(args, start2);
|
|
256555
256609
|
case "fix":
|
|
256556
256610
|
return await this.getFix(args, start2);
|
|
256557
256611
|
case "nmea":
|
|
@@ -256572,64 +256626,128 @@ var init_gps_location = __esm({
|
|
|
256572
256626
|
// =========================================================================
|
|
256573
256627
|
// Detect GPS hardware
|
|
256574
256628
|
// =========================================================================
|
|
256575
|
-
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) {
|
|
256576
256728
|
const devices = [];
|
|
256577
256729
|
try {
|
|
256578
256730
|
const lsusb = execSync36("lsusb 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
256579
256731
|
for (const known of GPS_USB_IDS) {
|
|
256580
256732
|
if (lsusb.toLowerCase().includes(`${known.vid}:${known.pid}`)) {
|
|
256581
|
-
|
|
256582
|
-
devices.push(` USB: ${known.name} \u2014 ${line?.trim() || `${known.vid}:${known.pid}`}`);
|
|
256583
|
-
}
|
|
256584
|
-
}
|
|
256585
|
-
for (const line of lsusb.split("\n")) {
|
|
256586
|
-
if (/gps|gnss|navsat/i.test(line) && !devices.some((d2) => d2.includes(line.trim()))) {
|
|
256587
|
-
devices.push(` USB: ${line.trim()}`);
|
|
256733
|
+
devices.push(` ${known.name}`);
|
|
256588
256734
|
}
|
|
256589
256735
|
}
|
|
256590
256736
|
} catch {
|
|
256591
256737
|
}
|
|
256592
|
-
|
|
256593
|
-
|
|
256594
|
-
|
|
256595
|
-
|
|
256596
|
-
|
|
256597
|
-
} catch {
|
|
256598
|
-
}
|
|
256599
|
-
}
|
|
256600
|
-
for (const dev of serialDevs) {
|
|
256601
|
-
try {
|
|
256602
|
-
const udev = execSync36(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
|
|
256603
|
-
const vendor = udev.match(/ID_VENDOR=(.+)/)?.[1] || "";
|
|
256604
|
-
const model = udev.match(/ID_MODEL=(.+)/)?.[1] || "";
|
|
256605
|
-
const serial = udev.match(/ID_SERIAL_SHORT=(.+)/)?.[1] || "";
|
|
256606
|
-
const isGps = GPS_USB_IDS.some((g) => udev.toLowerCase().includes(g.vid)) || /gps|gnss|prolific|cp210x|u-blox|ublox|sirf/i.test(udev);
|
|
256607
|
-
if (isGps) {
|
|
256608
|
-
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)`);
|
|
256609
256743
|
}
|
|
256610
|
-
} catch {
|
|
256611
256744
|
}
|
|
256612
|
-
}
|
|
256613
|
-
let gpsdRunning = false;
|
|
256614
|
-
try {
|
|
256615
|
-
execSync36("pgrep gpsd", { timeout: 3e3, stdio: "pipe" });
|
|
256616
|
-
gpsdRunning = true;
|
|
256617
|
-
devices.push(" Service: gpsd is running");
|
|
256618
256745
|
} catch {
|
|
256619
256746
|
}
|
|
256620
|
-
if (devices.length === 0) {
|
|
256621
|
-
return {
|
|
256622
|
-
success: true,
|
|
256623
|
-
output: "No GPS devices detected. Connect a USB GPS receiver (BU-353N, U-blox 7, etc.)." + (serialDevs.length > 0 ? `
|
|
256624
|
-
|
|
256625
|
-
Serial devices found but not identified as GPS: ${serialDevs.join(", ")}` : ""),
|
|
256626
|
-
durationMs: performance.now() - start2
|
|
256627
|
-
};
|
|
256628
|
-
}
|
|
256629
256747
|
return {
|
|
256630
256748
|
success: true,
|
|
256631
|
-
output: `GPS devices
|
|
256632
|
-
${devices.join("\n")}`
|
|
256749
|
+
output: devices.length > 0 ? `Potential GPS devices:
|
|
256750
|
+
${devices.join("\n")}` : "No GPS devices found. Connect a USB GPS receiver.",
|
|
256633
256751
|
durationMs: performance.now() - start2
|
|
256634
256752
|
};
|
|
256635
256753
|
}
|
|
@@ -256675,42 +256793,150 @@ Raw: ${JSON.stringify(fix)}`,
|
|
|
256675
256793
|
} catch {
|
|
256676
256794
|
}
|
|
256677
256795
|
}
|
|
256678
|
-
return this.
|
|
256796
|
+
return this.getFixPyserial(args, start2);
|
|
256679
256797
|
}
|
|
256680
|
-
/**
|
|
256681
|
-
|
|
256682
|
-
const device = args["device"] ||
|
|
256683
|
-
if (!device) {
|
|
256684
|
-
return { success: false, output: "", error: "No GPS device found. Connect a USB GPS receiver.", durationMs: performance.now() - start2 };
|
|
256685
|
-
}
|
|
256798
|
+
/** Get GPS fix using pyserial+pynmea2 — proven stack from gps_service/server.py */
|
|
256799
|
+
async getFixPyserial(args, start2) {
|
|
256800
|
+
const device = args["device"] || "";
|
|
256686
256801
|
const timeout2 = args["timeout"] || 30;
|
|
256687
|
-
const baud = this.detectBaud(device);
|
|
256688
256802
|
try {
|
|
256689
|
-
|
|
256690
|
-
|
|
256691
|
-
|
|
256692
|
-
|
|
256693
|
-
|
|
256694
|
-
|
|
256695
|
-
|
|
256696
|
-
|
|
256697
|
-
|
|
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
|
+
}
|
|
256698
256926
|
return {
|
|
256699
256927
|
success: true,
|
|
256700
|
-
output: `GPS Fix (
|
|
256701
|
-
Position: ${
|
|
256702
|
-
Altitude: ${
|
|
256703
|
-
|
|
256704
|
-
|
|
256705
|
-
|
|
256706
|
-
|
|
256707
|
-
|
|
256708
|
-
Raw GGA: ${gga || "none"}
|
|
256709
|
-
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}`,
|
|
256710
256936
|
durationMs: performance.now() - start2
|
|
256711
256937
|
};
|
|
256712
256938
|
} catch (err) {
|
|
256713
|
-
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 };
|
|
256714
256940
|
}
|
|
256715
256941
|
}
|
|
256716
256942
|
// =========================================================================
|
|
@@ -256899,16 +257125,24 @@ ${content.slice(0, 500)}`,
|
|
|
256899
257125
|
"/dev/ttyACM1",
|
|
256900
257126
|
"/dev/ttyACM2"
|
|
256901
257127
|
];
|
|
257128
|
+
const GPS_VENDOR_IDS = /* @__PURE__ */ new Set(["1546", "091e", "1163", "0df7", "16d0", "2c7c", "152a"]);
|
|
257129
|
+
const UART_BRIDGE_VIDS = /* @__PURE__ */ new Set(["067b", "10c4", "0403", "1a86"]);
|
|
256902
257130
|
for (const dev of candidates) {
|
|
256903
257131
|
if (!existsSync34(dev))
|
|
256904
257132
|
continue;
|
|
256905
257133
|
try {
|
|
256906
257134
|
const udev = execSync36(`udevadm info --query=all --name=${dev} 2>/dev/null`, { encoding: "utf8", timeout: 3e3 });
|
|
257135
|
+
const vidMatch = udev.match(/ID_VENDOR_ID=([0-9a-f]+)/i);
|
|
257136
|
+
const vid = vidMatch?.[1]?.toLowerCase() || "";
|
|
257137
|
+
if (vid && GPS_VENDOR_IDS.has(vid))
|
|
257138
|
+
return dev;
|
|
256907
257139
|
for (const gps of GPS_USB_IDS) {
|
|
256908
257140
|
if (udev.toLowerCase().includes(gps.vid) && udev.toLowerCase().includes(gps.pid))
|
|
256909
257141
|
return dev;
|
|
256910
257142
|
}
|
|
256911
|
-
if (
|
|
257143
|
+
if (vid && UART_BRIDGE_VIDS.has(vid) && dev.includes("ttyUSB"))
|
|
257144
|
+
return dev;
|
|
257145
|
+
if (/gps|gnss|sirf|ublox|u-blox|globalsat|garmin|trimble|quectel|septentrio|bu-353|bu-636|navsat/i.test(udev))
|
|
256912
257146
|
return dev;
|
|
256913
257147
|
} catch {
|
|
256914
257148
|
}
|
|
@@ -258238,10 +258472,10 @@ var init_client3 = __esm({
|
|
|
258238
258472
|
// packages/execution/dist/mcp/manager.js
|
|
258239
258473
|
import { existsSync as existsSync36, readFileSync as readFileSync26 } from "node:fs";
|
|
258240
258474
|
import { join as join50 } from "node:path";
|
|
258241
|
-
import { homedir as
|
|
258475
|
+
import { homedir as homedir14 } from "node:os";
|
|
258242
258476
|
function loadMcpConfig(repoRoot) {
|
|
258243
258477
|
const servers = {};
|
|
258244
|
-
const globalPath = join50(
|
|
258478
|
+
const globalPath = join50(homedir14(), ".open-agents", "mcp.json");
|
|
258245
258479
|
if (existsSync36(globalPath)) {
|
|
258246
258480
|
try {
|
|
258247
258481
|
const global2 = JSON.parse(readFileSync26(globalPath, "utf8"));
|
|
@@ -258545,10 +258779,10 @@ var init_mcp = __esm({
|
|
|
258545
258779
|
// packages/execution/dist/plugins/plugin-system.js
|
|
258546
258780
|
import { existsSync as existsSync37, readdirSync as readdirSync7, readFileSync as readFileSync27 } from "node:fs";
|
|
258547
258781
|
import { join as join51 } from "node:path";
|
|
258548
|
-
import { homedir as
|
|
258782
|
+
import { homedir as homedir15 } from "node:os";
|
|
258549
258783
|
function discoverPlugins(repoRoot) {
|
|
258550
258784
|
const plugins = [];
|
|
258551
|
-
const globalDir = join51(
|
|
258785
|
+
const globalDir = join51(homedir15(), ".open-agents", "plugins");
|
|
258552
258786
|
if (existsSync37(globalDir)) {
|
|
258553
258787
|
plugins.push(...loadPluginsFromDir(globalDir));
|
|
258554
258788
|
}
|
|
@@ -259975,10 +260209,10 @@ var init_buildRunner = __esm({
|
|
|
259975
260209
|
// packages/execution/dist/constraints.js
|
|
259976
260210
|
import { existsSync as existsSync42, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync18 } from "node:fs";
|
|
259977
260211
|
import { join as join55 } from "node:path";
|
|
259978
|
-
import { homedir as
|
|
260212
|
+
import { homedir as homedir16 } from "node:os";
|
|
259979
260213
|
function loadConstraints(projectRoot) {
|
|
259980
260214
|
projectConstraints = loadFile(join55(projectRoot, ".oa", "constraints.json"));
|
|
259981
|
-
globalConstraints = loadFile(join55(
|
|
260215
|
+
globalConstraints = loadFile(join55(homedir16(), ".open-agents", "constraints.json"));
|
|
259982
260216
|
}
|
|
259983
260217
|
function loadFile(path5) {
|
|
259984
260218
|
try {
|
|
@@ -269995,7 +270229,7 @@ __export(listen_exports, {
|
|
|
269995
270229
|
import { spawn as spawn17, execSync as execSync41 } from "node:child_process";
|
|
269996
270230
|
import { existsSync as existsSync45, mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readdirSync as readdirSync9 } from "node:fs";
|
|
269997
270231
|
import { join as join60, dirname as dirname16 } from "node:path";
|
|
269998
|
-
import { homedir as
|
|
270232
|
+
import { homedir as homedir17 } from "node:os";
|
|
269999
270233
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
270000
270234
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
270001
270235
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -270105,7 +270339,7 @@ function findLiveWhisperScript() {
|
|
|
270105
270339
|
}
|
|
270106
270340
|
} catch {
|
|
270107
270341
|
}
|
|
270108
|
-
const nvmBase = join60(
|
|
270342
|
+
const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
|
|
270109
270343
|
if (existsSync45(nvmBase)) {
|
|
270110
270344
|
try {
|
|
270111
270345
|
for (const ver of readdirSync9(nvmBase)) {
|
|
@@ -270353,7 +270587,7 @@ var init_listen = __esm({
|
|
|
270353
270587
|
}
|
|
270354
270588
|
} catch {
|
|
270355
270589
|
}
|
|
270356
|
-
const nvmBase = join60(
|
|
270590
|
+
const nvmBase = join60(homedir17(), ".nvm", "versions", "node");
|
|
270357
270591
|
if (existsSync45(nvmBase)) {
|
|
270358
270592
|
try {
|
|
270359
270593
|
const { readdirSync: readdirSync26 } = await import("node:fs");
|
|
@@ -280179,7 +280413,7 @@ __export(oa_directory_exports, {
|
|
|
280179
280413
|
});
|
|
280180
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";
|
|
280181
280415
|
import { join as join65, relative as relative4, basename as basename12 } from "node:path";
|
|
280182
|
-
import { homedir as
|
|
280416
|
+
import { homedir as homedir18 } from "node:os";
|
|
280183
280417
|
function initOaDirectory(repoRoot) {
|
|
280184
280418
|
const oaPath = join65(repoRoot, OA_DIR);
|
|
280185
280419
|
for (const sub of SUBDIRS) {
|
|
@@ -280219,7 +280453,7 @@ function saveProjectSettings(repoRoot, settings) {
|
|
|
280219
280453
|
writeFileSync22(join65(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
280220
280454
|
}
|
|
280221
280455
|
function loadGlobalSettings() {
|
|
280222
|
-
const settingsPath = join65(
|
|
280456
|
+
const settingsPath = join65(homedir18(), ".open-agents", "settings.json");
|
|
280223
280457
|
try {
|
|
280224
280458
|
if (existsSync49(settingsPath)) {
|
|
280225
280459
|
return JSON.parse(readFileSync37(settingsPath, "utf-8"));
|
|
@@ -280229,7 +280463,7 @@ function loadGlobalSettings() {
|
|
|
280229
280463
|
return {};
|
|
280230
280464
|
}
|
|
280231
280465
|
function saveGlobalSettings(settings) {
|
|
280232
|
-
const dir = join65(
|
|
280466
|
+
const dir = join65(homedir18(), ".open-agents");
|
|
280233
280467
|
mkdirSync22(dir, { recursive: true });
|
|
280234
280468
|
const existing = loadGlobalSettings();
|
|
280235
280469
|
const merged = { ...existing, ...settings };
|
|
@@ -280727,13 +280961,13 @@ function recordUsage(kind, value2, opts) {
|
|
|
280727
280961
|
}
|
|
280728
280962
|
saveUsageFile(filePath, data);
|
|
280729
280963
|
};
|
|
280730
|
-
update2(join65(
|
|
280964
|
+
update2(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
|
|
280731
280965
|
if (opts?.repoRoot) {
|
|
280732
280966
|
update2(join65(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
280733
280967
|
}
|
|
280734
280968
|
}
|
|
280735
280969
|
function loadUsageHistory(kind, repoRoot) {
|
|
280736
|
-
const globalPath = join65(
|
|
280970
|
+
const globalPath = join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE);
|
|
280737
280971
|
const globalData = loadUsageFile(globalPath);
|
|
280738
280972
|
const localData = repoRoot ? loadUsageFile(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
280739
280973
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -280764,7 +280998,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
280764
280998
|
saveUsageFile(filePath, data);
|
|
280765
280999
|
}
|
|
280766
281000
|
};
|
|
280767
|
-
remove(join65(
|
|
281001
|
+
remove(join65(homedir18(), ".open-agents", USAGE_HISTORY_FILE));
|
|
280768
281002
|
if (repoRoot) {
|
|
280769
281003
|
remove(join65(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
280770
281004
|
}
|
|
@@ -285320,7 +285554,7 @@ __export(personaplex_exports, {
|
|
|
285320
285554
|
});
|
|
285321
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";
|
|
285322
285556
|
import { join as join66, dirname as dirname20 } from "node:path";
|
|
285323
|
-
import { homedir as
|
|
285557
|
+
import { homedir as homedir19 } from "node:os";
|
|
285324
285558
|
import { execSync as execSync44, spawn as spawn20 } from "node:child_process";
|
|
285325
285559
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
285326
285560
|
function execAsync(cmd, opts = {}) {
|
|
@@ -285915,7 +286149,7 @@ print('Converted')
|
|
|
285915
286149
|
let ollamaModel = process.env["HYBRID_LLM_MODEL"] || "";
|
|
285916
286150
|
if (!ollamaModel) {
|
|
285917
286151
|
try {
|
|
285918
|
-
const oaConfig = JSON.parse(readFileSync39(join66(
|
|
286152
|
+
const oaConfig = JSON.parse(readFileSync39(join66(homedir19(), ".open-agents", "config.json"), "utf8"));
|
|
285919
286153
|
if (oaConfig.model) ollamaModel = oaConfig.model;
|
|
285920
286154
|
} catch {
|
|
285921
286155
|
}
|
|
@@ -286186,7 +286420,7 @@ function provisionShippedVoices(onInfo) {
|
|
|
286186
286420
|
return deployed;
|
|
286187
286421
|
}
|
|
286188
286422
|
function getHFVoicesDir() {
|
|
286189
|
-
const hfBase = join66(
|
|
286423
|
+
const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
286190
286424
|
if (!existsSync50(hfBase)) return null;
|
|
286191
286425
|
try {
|
|
286192
286426
|
const snapshots = join66(hfBase, "snapshots");
|
|
@@ -286202,7 +286436,7 @@ function getHFVoicesDir() {
|
|
|
286202
286436
|
function patchFrontendVoiceList(onInfo) {
|
|
286203
286437
|
const log22 = onInfo ?? (() => {
|
|
286204
286438
|
});
|
|
286205
|
-
const hfBase = join66(
|
|
286439
|
+
const hfBase = join66(homedir19(), ".cache", "huggingface", "hub", "models--nvidia--personaplex-7b-v1");
|
|
286206
286440
|
if (!existsSync50(hfBase)) return;
|
|
286207
286441
|
try {
|
|
286208
286442
|
const snapshots = join66(hfBase, "snapshots");
|
|
@@ -286280,7 +286514,7 @@ var init_personaplex = __esm({
|
|
|
286280
286514
|
nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
|
|
286281
286515
|
"nf4-distilled": { repo: "cudabenchmarktest/personaplex-7b-nf4-distilled", file: "student_best.pt", sizeGB: 16.7, needsToken: false }
|
|
286282
286516
|
};
|
|
286283
|
-
PERSONAPLEX_DIR = join66(
|
|
286517
|
+
PERSONAPLEX_DIR = join66(homedir19(), ".open-agents", "voice", "personaplex");
|
|
286284
286518
|
PID_FILE = join66(PERSONAPLEX_DIR, "daemon.pid");
|
|
286285
286519
|
PORT_FILE = join66(PERSONAPLEX_DIR, "daemon.port");
|
|
286286
286520
|
LOG_FILE = join66(PERSONAPLEX_DIR, "daemon.log");
|
|
@@ -286327,7 +286561,7 @@ import { execSync as execSync45, spawn as spawn21, exec as exec4 } from "node:ch
|
|
|
286327
286561
|
import { promisify as promisify7 } from "node:util";
|
|
286328
286562
|
import { existsSync as existsSync51, writeFileSync as writeFileSync24, readFileSync as readFileSync40, appendFileSync as appendFileSync2, mkdirSync as mkdirSync24 } from "node:fs";
|
|
286329
286563
|
import { join as join67 } from "node:path";
|
|
286330
|
-
import { homedir as
|
|
286564
|
+
import { homedir as homedir20, platform as platform3 } from "node:os";
|
|
286331
286565
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
286332
286566
|
if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
|
|
286333
286567
|
try {
|
|
@@ -287426,7 +287660,7 @@ async function doSetup(config, rl) {
|
|
|
287426
287660
|
`PARAMETER num_predict ${numPredict}`,
|
|
287427
287661
|
`PARAMETER stop "<|endoftext|>"`
|
|
287428
287662
|
].join("\n");
|
|
287429
|
-
const modelDir2 = join67(
|
|
287663
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
287430
287664
|
mkdirSync24(modelDir2, { recursive: true });
|
|
287431
287665
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
287432
287666
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -287474,7 +287708,7 @@ async function isModelAvailable(config) {
|
|
|
287474
287708
|
}
|
|
287475
287709
|
function isFirstRun() {
|
|
287476
287710
|
try {
|
|
287477
|
-
return !existsSync51(join67(
|
|
287711
|
+
return !existsSync51(join67(homedir20(), ".open-agents", "config.json"));
|
|
287478
287712
|
} catch {
|
|
287479
287713
|
return true;
|
|
287480
287714
|
}
|
|
@@ -287522,7 +287756,7 @@ function detectPkgManager() {
|
|
|
287522
287756
|
return null;
|
|
287523
287757
|
}
|
|
287524
287758
|
function getVenvDir() {
|
|
287525
|
-
return join67(
|
|
287759
|
+
return join67(homedir20(), ".open-agents", "venv");
|
|
287526
287760
|
}
|
|
287527
287761
|
function hasVenvModule() {
|
|
287528
287762
|
try {
|
|
@@ -287548,7 +287782,7 @@ function ensureVenv(log22) {
|
|
|
287548
287782
|
return null;
|
|
287549
287783
|
}
|
|
287550
287784
|
try {
|
|
287551
|
-
mkdirSync24(join67(
|
|
287785
|
+
mkdirSync24(join67(homedir20(), ".open-agents"), { recursive: true });
|
|
287552
287786
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
287553
287787
|
execSync45(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
287554
287788
|
execSync45(`"${pipPath}" install --upgrade pip`, {
|
|
@@ -287648,7 +287882,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
287648
287882
|
];
|
|
287649
287883
|
{
|
|
287650
287884
|
const pm2 = detectPkgManager();
|
|
287651
|
-
const _visionMarkerDir = join67(
|
|
287885
|
+
const _visionMarkerDir = join67(homedir20(), ".open-agents");
|
|
287652
287886
|
const _visionMarkerFile = join67(_visionMarkerDir, "vision-deps-installed.json");
|
|
287653
287887
|
let _visionPreviouslyInstalled = /* @__PURE__ */ new Set();
|
|
287654
287888
|
try {
|
|
@@ -287901,11 +288135,11 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
287901
288135
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
287902
288136
|
try {
|
|
287903
288137
|
execSync45(
|
|
287904
|
-
`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"`,
|
|
287905
288139
|
{ stdio: "pipe", timeout: 6e4 }
|
|
287906
288140
|
);
|
|
287907
|
-
if (!process.env.PATH?.includes(`${
|
|
287908
|
-
process.env.PATH = `${
|
|
288141
|
+
if (!process.env.PATH?.includes(`${homedir20()}/.local/bin`)) {
|
|
288142
|
+
process.env.PATH = `${homedir20()}/.local/bin:${process.env.PATH}`;
|
|
287909
288143
|
}
|
|
287910
288144
|
if (hasCmd("cloudflared")) {
|
|
287911
288145
|
log22("cloudflared installed.");
|
|
@@ -288002,7 +288236,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
|
|
|
288002
288236
|
`PARAMETER num_predict ${numPredict}`,
|
|
288003
288237
|
`PARAMETER stop "<|endoftext|>"`
|
|
288004
288238
|
].join("\n");
|
|
288005
|
-
const modelDir2 = join67(
|
|
288239
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
288006
288240
|
mkdirSync24(modelDir2, { recursive: true });
|
|
288007
288241
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
288008
288242
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -288027,7 +288261,7 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
288027
288261
|
`PARAMETER num_predict ${numPredict}`,
|
|
288028
288262
|
`PARAMETER stop "<|endoftext|>"`
|
|
288029
288263
|
].join("\n");
|
|
288030
|
-
const modelDir2 = join67(
|
|
288264
|
+
const modelDir2 = join67(homedir20(), ".open-agents", "models");
|
|
288031
288265
|
mkdirSync24(modelDir2, { recursive: true });
|
|
288032
288266
|
const modelfilePath = join67(modelDir2, `Modelfile.${customName}`);
|
|
288033
288267
|
writeFileSync24(modelfilePath, modelfileContent + "\n", "utf8");
|
|
@@ -288103,7 +288337,7 @@ async function ensureNeovim() {
|
|
|
288103
288337
|
const platform6 = process.platform;
|
|
288104
288338
|
const arch2 = process.arch;
|
|
288105
288339
|
if (platform6 === "linux") {
|
|
288106
|
-
const binDir = join67(
|
|
288340
|
+
const binDir = join67(homedir20(), ".local", "bin");
|
|
288107
288341
|
const nvimDest = join67(binDir, "nvim");
|
|
288108
288342
|
try {
|
|
288109
288343
|
mkdirSync24(binDir, { recursive: true });
|
|
@@ -288175,7 +288409,7 @@ async function ensureNeovim() {
|
|
|
288175
288409
|
}
|
|
288176
288410
|
function ensurePathInShellRc(binDir) {
|
|
288177
288411
|
const shell = process.env.SHELL ?? "";
|
|
288178
|
-
const rcFile = shell.includes("zsh") ? join67(
|
|
288412
|
+
const rcFile = shell.includes("zsh") ? join67(homedir20(), ".zshrc") : join67(homedir20(), ".bashrc");
|
|
288179
288413
|
try {
|
|
288180
288414
|
const rcContent = existsSync51(rcFile) ? readFileSync40(rcFile, "utf8") : "";
|
|
288181
288415
|
if (rcContent.includes(binDir)) return;
|
|
@@ -288918,7 +289152,7 @@ __export(daemon_exports, {
|
|
|
288918
289152
|
import { spawn as spawn22 } from "node:child_process";
|
|
288919
289153
|
import { existsSync as existsSync54, readFileSync as readFileSync41, writeFileSync as writeFileSync25, mkdirSync as mkdirSync25, unlinkSync as unlinkSync13 } from "node:fs";
|
|
288920
289154
|
import { join as join69 } from "node:path";
|
|
288921
|
-
import { homedir as
|
|
289155
|
+
import { homedir as homedir21 } from "node:os";
|
|
288922
289156
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
288923
289157
|
import { dirname as dirname21 } from "node:path";
|
|
288924
289158
|
function getDaemonPort() {
|
|
@@ -289069,7 +289303,7 @@ var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
|
|
|
289069
289303
|
var init_daemon = __esm({
|
|
289070
289304
|
"packages/cli/src/daemon.ts"() {
|
|
289071
289305
|
"use strict";
|
|
289072
|
-
OA_DIR2 = join69(
|
|
289306
|
+
OA_DIR2 = join69(homedir21(), ".open-agents");
|
|
289073
289307
|
PID_FILE2 = join69(OA_DIR2, "daemon.pid");
|
|
289074
289308
|
DEFAULT_PORT2 = 11435;
|
|
289075
289309
|
}
|
|
@@ -290369,7 +290603,7 @@ __export(voice_exports, {
|
|
|
290369
290603
|
});
|
|
290370
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";
|
|
290371
290605
|
import { join as join71, dirname as dirname22 } from "node:path";
|
|
290372
|
-
import { homedir as
|
|
290606
|
+
import { homedir as homedir22, tmpdir as tmpdir15, platform as platform4 } from "node:os";
|
|
290373
290607
|
import { execSync as execSync47, spawn as nodeSpawn } from "node:child_process";
|
|
290374
290608
|
import { createRequire as createRequire2 } from "node:module";
|
|
290375
290609
|
function sanitizeForTTS(text) {
|
|
@@ -290393,7 +290627,7 @@ function listVoiceModels() {
|
|
|
290393
290627
|
}));
|
|
290394
290628
|
}
|
|
290395
290629
|
function voiceDir() {
|
|
290396
|
-
return join71(
|
|
290630
|
+
return join71(homedir22(), ".open-agents", "voice");
|
|
290397
290631
|
}
|
|
290398
290632
|
function modelsDir() {
|
|
290399
290633
|
return join71(voiceDir(), "models");
|
|
@@ -291325,7 +291559,7 @@ var init_voice = __esm({
|
|
|
291325
291559
|
}
|
|
291326
291560
|
p2 = p2.replace(/\\ /g, " ");
|
|
291327
291561
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
291328
|
-
p2 = join71(
|
|
291562
|
+
p2 = join71(homedir22(), p2.slice(1));
|
|
291329
291563
|
}
|
|
291330
291564
|
if (!existsSync56(p2)) {
|
|
291331
291565
|
return `File not found: ${p2}
|
|
@@ -293675,9 +293909,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
293675
293909
|
renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
|
|
293676
293910
|
}
|
|
293677
293911
|
} else if (sub === "name") {
|
|
293678
|
-
const { homedir:
|
|
293912
|
+
const { homedir: homedir29 } = __require("node:os");
|
|
293679
293913
|
const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
|
|
293680
|
-
const namePath = __require("node:path").join(
|
|
293914
|
+
const namePath = __require("node:path").join(homedir29(), ".open-agents", "agent-name");
|
|
293681
293915
|
if (rest2) {
|
|
293682
293916
|
const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
|
|
293683
293917
|
if (!customName) {
|
|
@@ -295376,8 +295610,8 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
295376
295610
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
295377
295611
|
if (!sponsorName || sponsorName.length < 2) {
|
|
295378
295612
|
try {
|
|
295379
|
-
const { homedir:
|
|
295380
|
-
const namePath = __require("path").join(
|
|
295613
|
+
const { homedir: homedir29 } = __require("os");
|
|
295614
|
+
const namePath = __require("path").join(homedir29(), ".open-agents", "agent-name");
|
|
295381
295615
|
if (existsSync57(namePath)) sponsorName = readFileSync44(namePath, "utf8").trim();
|
|
295382
295616
|
} catch {
|
|
295383
295617
|
}
|
|
@@ -296837,9 +297071,9 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
296837
297071
|
}
|
|
296838
297072
|
const { basename: basename19, join: pathJoin } = await import("node:path");
|
|
296839
297073
|
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync43, existsSync: exists2 } = await import("node:fs");
|
|
296840
|
-
const { homedir:
|
|
297074
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
296841
297075
|
const modelName = basename19(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
296842
|
-
const destDir = pathJoin(
|
|
297076
|
+
const destDir = pathJoin(homedir29(), ".open-agents", "voice", "models", modelName);
|
|
296843
297077
|
if (!exists2(destDir)) mkdirSync43(destDir, { recursive: true });
|
|
296844
297078
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
296845
297079
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
@@ -299061,7 +299295,7 @@ var init_commands = __esm({
|
|
|
299061
299295
|
import { existsSync as existsSync58, readFileSync as readFileSync45, readdirSync as readdirSync15 } from "node:fs";
|
|
299062
299296
|
import { join as join73, basename as basename13 } from "node:path";
|
|
299063
299297
|
import { execSync as execSync48 } from "node:child_process";
|
|
299064
|
-
import { homedir as
|
|
299298
|
+
import { homedir as homedir24, platform as platform5, release } from "node:os";
|
|
299065
299299
|
function getModelTier(modelName) {
|
|
299066
299300
|
const m2 = modelName.toLowerCase();
|
|
299067
299301
|
const sizeMatch = m2.match(/\b(\d+)b\b/);
|
|
@@ -299140,7 +299374,7 @@ function loadMemoryContext(repoRoot) {
|
|
|
299140
299374
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
299141
299375
|
if (legacyEntries) sections.push(legacyEntries);
|
|
299142
299376
|
}
|
|
299143
|
-
const globalMemDir = join73(
|
|
299377
|
+
const globalMemDir = join73(homedir24(), ".open-agents", "memory");
|
|
299144
299378
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
299145
299379
|
if (globalEntries) sections.push(globalEntries);
|
|
299146
299380
|
return sections.join("\n\n");
|
|
@@ -308431,10 +308665,10 @@ var init_usage_tracker = __esm({
|
|
|
308431
308665
|
// packages/cli/src/api/profiles.ts
|
|
308432
308666
|
import { existsSync as existsSync69, readFileSync as readFileSync55, writeFileSync as writeFileSync34, mkdirSync as mkdirSync37, readdirSync as readdirSync22, unlinkSync as unlinkSync17 } from "node:fs";
|
|
308433
308667
|
import { join as join85 } from "node:path";
|
|
308434
|
-
import { homedir as
|
|
308668
|
+
import { homedir as homedir25 } from "node:os";
|
|
308435
308669
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3 } from "node:crypto";
|
|
308436
308670
|
function globalProfileDir() {
|
|
308437
|
-
return join85(
|
|
308671
|
+
return join85(homedir25(), ".open-agents", "profiles");
|
|
308438
308672
|
}
|
|
308439
308673
|
function projectProfileDir(projectDir) {
|
|
308440
308674
|
return join85(projectDir || process.cwd(), ".oa", "profiles");
|
|
@@ -308626,7 +308860,7 @@ var init_profiles = __esm({
|
|
|
308626
308860
|
import { execSync as execSync50, spawn as spawn23 } from "node:child_process";
|
|
308627
308861
|
import { existsSync as existsSync70, mkdirSync as mkdirSync38, writeFileSync as writeFileSync35 } from "node:fs";
|
|
308628
308862
|
import { join as join86, resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
308629
|
-
import { homedir as
|
|
308863
|
+
import { homedir as homedir26 } from "node:os";
|
|
308630
308864
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
308631
308865
|
function getDockerDir() {
|
|
308632
308866
|
try {
|
|
@@ -308774,7 +309008,7 @@ async function ensureOaImage(force = false) {
|
|
|
308774
309008
|
if (existsSync70(join86(dockerDir, "Dockerfile"))) {
|
|
308775
309009
|
buildContext = dockerDir;
|
|
308776
309010
|
} else {
|
|
308777
|
-
buildContext = join86(
|
|
309011
|
+
buildContext = join86(homedir26(), ".oa", "docker-build");
|
|
308778
309012
|
mkdirSync38(buildContext, { recursive: true });
|
|
308779
309013
|
writeDockerfiles(buildContext);
|
|
308780
309014
|
}
|
|
@@ -310847,7 +311081,7 @@ import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
|
310847
311081
|
import { readFileSync as readFileSync57, writeFileSync as writeFileSync37, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync40 } from "node:fs";
|
|
310848
311082
|
import { existsSync as existsSync72 } from "node:fs";
|
|
310849
311083
|
import { execSync as execSync52 } from "node:child_process";
|
|
310850
|
-
import { homedir as
|
|
311084
|
+
import { homedir as homedir27 } from "node:os";
|
|
310851
311085
|
function formatTimeAgo(date) {
|
|
310852
311086
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
310853
311087
|
if (seconds < 60) return "just now";
|
|
@@ -313409,7 +313643,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
313409
313643
|
const hits = allCompletions.filter((c7) => c7.toLowerCase().startsWith(lower));
|
|
313410
313644
|
return [hits, line];
|
|
313411
313645
|
}
|
|
313412
|
-
const HISTORY_DIR = join88(
|
|
313646
|
+
const HISTORY_DIR = join88(homedir27(), ".open-agents");
|
|
313413
313647
|
const HISTORY_FILE = join88(HISTORY_DIR, "repl-history");
|
|
313414
313648
|
const MAX_HISTORY_LINES = 500;
|
|
313415
313649
|
let savedHistory = [];
|
|
@@ -315195,7 +315429,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
315195
315429
|
} catch {
|
|
315196
315430
|
}
|
|
315197
315431
|
try {
|
|
315198
|
-
const voiceDir2 = join88(
|
|
315432
|
+
const voiceDir2 = join88(homedir27(), ".open-agents", "voice");
|
|
315199
315433
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
315200
315434
|
for (const pf of voicePidFiles) {
|
|
315201
315435
|
const pidPath = join88(voiceDir2, pf);
|
|
@@ -315308,8 +315542,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
315308
315542
|
try {
|
|
315309
315543
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
315310
315544
|
if (isPersonaPlexRunning2()) {
|
|
315311
|
-
const ppPidFile = join88(
|
|
315312
|
-
const ppPortFile = join88(
|
|
315545
|
+
const ppPidFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
315546
|
+
const ppPortFile = join88(homedir27(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
315313
315547
|
if (existsSync72(ppPidFile)) {
|
|
315314
315548
|
const ppPid = parseInt(readFileSync57(ppPidFile, "utf8").trim(), 10);
|
|
315315
315549
|
const ppPort = existsSync72(ppPortFile) ? parseInt(readFileSync57(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
@@ -317229,7 +317463,7 @@ __export(config_exports2, {
|
|
|
317229
317463
|
configCommand: () => configCommand
|
|
317230
317464
|
});
|
|
317231
317465
|
import { join as join91, resolve as resolve38 } from "node:path";
|
|
317232
|
-
import { homedir as
|
|
317466
|
+
import { homedir as homedir28 } from "node:os";
|
|
317233
317467
|
import { cwd as cwd3 } from "node:process";
|
|
317234
317468
|
function redactIfSensitive(key, value2) {
|
|
317235
317469
|
if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
|
|
@@ -317310,7 +317544,7 @@ function handleShow(opts, config) {
|
|
|
317310
317544
|
}
|
|
317311
317545
|
}
|
|
317312
317546
|
printSection("Config File");
|
|
317313
|
-
printInfo(`~/.open-agents/config.json (${join91(
|
|
317547
|
+
printInfo(`~/.open-agents/config.json (${join91(homedir28(), ".open-agents", "config.json")})`);
|
|
317314
317548
|
printSection("Priority Chain");
|
|
317315
317549
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
317316
317550
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -318115,8 +318349,8 @@ function crashLog(label, err) {
|
|
|
318115
318349
|
try {
|
|
318116
318350
|
const { appendFileSync: appendFileSync7, mkdirSync: mkdirSync43 } = __require("node:fs");
|
|
318117
318351
|
const { join: join94 } = __require("node:path");
|
|
318118
|
-
const { homedir:
|
|
318119
|
-
const logDir = join94(
|
|
318352
|
+
const { homedir: homedir29 } = __require("node:os");
|
|
318353
|
+
const logDir = join94(homedir29(), ".open-agents");
|
|
318120
318354
|
mkdirSync43(logDir, { recursive: true });
|
|
318121
318355
|
appendFileSync7(join94(logDir, "crash.log"), logLine);
|
|
318122
318356
|
} catch {
|
package/package.json
CHANGED