open-agents-ai 0.103.68 → 0.103.70
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 +171 -64
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12130,6 +12130,26 @@ const blockedPeers = [];
|
|
|
12130
12130
|
// Both peers connect to wss://demo.nats.io:8443, so NATS request/reply bridges the gap.
|
|
12131
12131
|
var _natsConn = null;
|
|
12132
12132
|
var _natsCodec = null;
|
|
12133
|
+
var _tokensByRequest = {};
|
|
12134
|
+
|
|
12135
|
+
// Check if an error is a connectivity/dial failure (should trigger NATS fallback)
|
|
12136
|
+
// vs an application-level error (auth rejected, capability not found \u2014 no point retrying via NATS)
|
|
12137
|
+
function isDialFailure(errMsg) {
|
|
12138
|
+
var appErrors = ['unauthorized', 'capability not found', 'not registered', 'auth rejected'];
|
|
12139
|
+
var lower = errMsg.toLowerCase();
|
|
12140
|
+
for (var i = 0; i < appErrors.length; i++) {
|
|
12141
|
+
if (lower.includes(appErrors[i])) return false;
|
|
12142
|
+
}
|
|
12143
|
+
// Any network/transport error should fall back to NATS
|
|
12144
|
+
return lower.includes('multiaddrs failed') || lower.includes('econnrefused') ||
|
|
12145
|
+
lower.includes('etimedout') || lower.includes('dial to peer') ||
|
|
12146
|
+
lower.includes('no route') || lower.includes('circuit relay') ||
|
|
12147
|
+
lower.includes('stream was reset') || lower.includes('timeout') ||
|
|
12148
|
+
lower.includes('connection reset') || lower.includes('ehostunreach') ||
|
|
12149
|
+
lower.includes('enetunreach') || lower.includes('peer not reachable') ||
|
|
12150
|
+
lower.includes('dial error') || lower.includes('aborted') ||
|
|
12151
|
+
lower.includes('connection refused');
|
|
12152
|
+
}
|
|
12133
12153
|
|
|
12134
12154
|
function writeStatus(extra = {}) {
|
|
12135
12155
|
const caps = typeof nexus.getRegisteredCapabilities === 'function'
|
|
@@ -12293,7 +12313,7 @@ async function handleCmd(cmd) {
|
|
|
12293
12313
|
var qpcErrMsg = qpcErr.message || String(qpcErr);
|
|
12294
12314
|
dlog('query_peer_caps: ERROR ' + qpcErrMsg);
|
|
12295
12315
|
// NATS fallback for peer cap discovery across NAT
|
|
12296
|
-
if (_natsConn && _natsCodec && qpcErrMsg
|
|
12316
|
+
if (_natsConn && _natsCodec && isDialFailure(qpcErrMsg)) {
|
|
12297
12317
|
dlog('query_peer_caps: trying NATS relay fallback');
|
|
12298
12318
|
try {
|
|
12299
12319
|
var _qpcNatsSubject = 'nexus.invoke.' + String(qpcPeerId);
|
|
@@ -12341,8 +12361,8 @@ async function handleCmd(cmd) {
|
|
|
12341
12361
|
} catch (invokeErr) {
|
|
12342
12362
|
var invokeErrMsg = invokeErr.message || String(invokeErr);
|
|
12343
12363
|
dlog('invoke_capability: ERROR ' + invokeErrMsg);
|
|
12344
|
-
// NATS fallback \u2014 if direct dial failed (NAT), retry via NATS relay
|
|
12345
|
-
if (_natsConn && _natsCodec && invokeErrMsg
|
|
12364
|
+
// NATS fallback \u2014 if direct dial failed (NAT/timeout/refused), retry via NATS relay
|
|
12365
|
+
if (_natsConn && _natsCodec && isDialFailure(invokeErrMsg)) {
|
|
12346
12366
|
dlog('invoke_capability: trying NATS relay fallback for ' + peerId.slice(0, 20));
|
|
12347
12367
|
try {
|
|
12348
12368
|
var _icNatsSubject = 'nexus.invoke.' + peerId;
|
|
@@ -12420,8 +12440,8 @@ async function handleCmd(cmd) {
|
|
|
12420
12440
|
} catch (riErr) {
|
|
12421
12441
|
var riErrMsg = riErr.message || String(riErr);
|
|
12422
12442
|
dlog('remote_infer: ERROR (explicit peer) ' + riErrMsg);
|
|
12423
|
-
// NATS fallback \u2014 if direct dial failed (NAT/firewall), retry via NATS relay
|
|
12424
|
-
if (_natsConn && _natsCodec && riErrMsg
|
|
12443
|
+
// NATS fallback \u2014 if direct dial failed (NAT/firewall/timeout), retry via NATS relay
|
|
12444
|
+
if (_natsConn && _natsCodec && isDialFailure(riErrMsg)) {
|
|
12425
12445
|
dlog('remote_infer: trying NATS relay fallback for ' + riTargetPeer.slice(0, 20));
|
|
12426
12446
|
try {
|
|
12427
12447
|
var _riNatsSubject = 'nexus.invoke.' + riTargetPeer;
|
|
@@ -12488,6 +12508,36 @@ async function handleCmd(cmd) {
|
|
|
12488
12508
|
}
|
|
12489
12509
|
dlog('remote_infer: auto-discover took ' + (Date.now() - discStart) + 'ms');
|
|
12490
12510
|
|
|
12511
|
+
// If libp2p auto-discover failed, try NATS relay against discovered peers from cache
|
|
12512
|
+
if (!riResult && _natsConn && _natsCodec) {
|
|
12513
|
+
try {
|
|
12514
|
+
var _dpFile = join(nexusDir, 'discovered-peers.json');
|
|
12515
|
+
if (existsSync(_dpFile)) {
|
|
12516
|
+
var _dpData = JSON.parse(readFileSync(_dpFile, 'utf8'));
|
|
12517
|
+
var _dpPeers = Object.keys(_dpData).filter(function(p) { return p.startsWith('12D3KooW'); });
|
|
12518
|
+
dlog('remote_infer: trying NATS relay on ' + _dpPeers.length + ' cached peers');
|
|
12519
|
+
for (var _dpi = 0; _dpi < _dpPeers.length && !riResult; _dpi++) {
|
|
12520
|
+
var _dpPid = _dpPeers[_dpi];
|
|
12521
|
+
try {
|
|
12522
|
+
var _dpSubject = 'nexus.invoke.' + _dpPid;
|
|
12523
|
+
var _dpPayload = JSON.stringify({ capability: riCapName, input: riData, from: nexus.peerId || '' });
|
|
12524
|
+
var _dpResp = await _natsConn.request(_dpSubject, _natsCodec.encode(_dpPayload), { timeout: 180000 });
|
|
12525
|
+
var _dpResult = JSON.parse(_natsCodec.decode(_dpResp.data));
|
|
12526
|
+
if (_dpResult && !_dpResult.error) {
|
|
12527
|
+
riResult = _dpResult;
|
|
12528
|
+
riTargetPeer = _dpPid;
|
|
12529
|
+
dlog('remote_infer: SUCCESS via NATS relay peer ' + _dpPid.slice(0, 20));
|
|
12530
|
+
}
|
|
12531
|
+
} catch (_dpErr) {
|
|
12532
|
+
dlog('remote_infer: NATS peer ' + _dpPid.slice(0, 20) + ' failed: ' + (_dpErr.message || _dpErr));
|
|
12533
|
+
}
|
|
12534
|
+
}
|
|
12535
|
+
}
|
|
12536
|
+
} catch (_dpCacheErr) {
|
|
12537
|
+
dlog('remote_infer: NATS discovery cache error: ' + (_dpCacheErr.message || _dpCacheErr));
|
|
12538
|
+
}
|
|
12539
|
+
}
|
|
12540
|
+
|
|
12491
12541
|
if (!riResult) {
|
|
12492
12542
|
writeResp(id, { ok: false, output: 'No peer found with capability: ' + riCapName + '. Ensure a provider is running expose with model ' + riModel });
|
|
12493
12543
|
return;
|
|
@@ -13100,6 +13150,12 @@ async function handleCmd(cmd) {
|
|
|
13100
13150
|
// Register system_metrics capability \u2014 returns CPU/GPU/memory utilization
|
|
13101
13151
|
if (typeof nexus.registerCapability === 'function') {
|
|
13102
13152
|
nexus.registerCapability('system_metrics', async (request, stream) => {
|
|
13153
|
+
// Stream safety wrapper \u2014 prevents unguarded writes after consumer disconnects
|
|
13154
|
+
var smStreamClosed = false;
|
|
13155
|
+
async function smWrite(msg) {
|
|
13156
|
+
if (smStreamClosed) return;
|
|
13157
|
+
try { await stream.write(msg); } catch { smStreamClosed = true; }
|
|
13158
|
+
}
|
|
13103
13159
|
// Collect input via stream data events (auth_key arrives in invoke.chunk, NOT invoke.open)
|
|
13104
13160
|
var smDataChunks = [];
|
|
13105
13161
|
var smInputDone = false;
|
|
@@ -13113,7 +13169,7 @@ async function handleCmd(cmd) {
|
|
|
13113
13169
|
});
|
|
13114
13170
|
|
|
13115
13171
|
// Accept invocation so consumer sends data
|
|
13116
|
-
await
|
|
13172
|
+
await smWrite({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: true });
|
|
13117
13173
|
|
|
13118
13174
|
// Wait briefly for data (auth key arrives in chunk)
|
|
13119
13175
|
var smWait = 0;
|
|
@@ -13138,9 +13194,9 @@ async function handleCmd(cmd) {
|
|
|
13138
13194
|
}
|
|
13139
13195
|
if (smAuthKey !== exposeAuthKey) {
|
|
13140
13196
|
dlog('system_metrics: auth REJECTED from ' + (request.from || 'unknown'));
|
|
13141
|
-
await
|
|
13142
|
-
await
|
|
13143
|
-
stream.close();
|
|
13197
|
+
await smWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'Unauthorized' });
|
|
13198
|
+
await smWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
13199
|
+
try { stream.close(); } catch {}
|
|
13144
13200
|
return;
|
|
13145
13201
|
}
|
|
13146
13202
|
dlog('system_metrics: auth OK');
|
|
@@ -13175,13 +13231,13 @@ async function handleCmd(cmd) {
|
|
|
13175
13231
|
gpu: gpuInfo,
|
|
13176
13232
|
timestamp: new Date().toISOString(),
|
|
13177
13233
|
};
|
|
13178
|
-
await
|
|
13179
|
-
await
|
|
13234
|
+
await smWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'result', data: JSON.stringify(metricsPayload) });
|
|
13235
|
+
await smWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: JSON.stringify(metricsPayload).length } });
|
|
13180
13236
|
} catch (me) {
|
|
13181
|
-
await
|
|
13182
|
-
await
|
|
13237
|
+
await smWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'error', data: 'metrics error: ' + me.message });
|
|
13238
|
+
await smWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
13183
13239
|
}
|
|
13184
|
-
stream.close();
|
|
13240
|
+
try { stream.close(); } catch {}
|
|
13185
13241
|
});
|
|
13186
13242
|
dlog('system_metrics capability registered');
|
|
13187
13243
|
}
|
|
@@ -13380,7 +13436,6 @@ process.on('unhandledRejection', (reason) => {
|
|
|
13380
13436
|
// The nexus library fires this hook AFTER handler returns, so it has the correct
|
|
13381
13437
|
// peerId from connection context. We stash token data per requestId so the hook
|
|
13382
13438
|
// can merge them into one complete record written to metering.jsonl.
|
|
13383
|
-
var _tokensByRequest = {};
|
|
13384
13439
|
try {
|
|
13385
13440
|
if (nexus.metering && typeof nexus.metering.addHook === 'function') {
|
|
13386
13441
|
nexus.metering.addHook(function(record) {
|
|
@@ -13532,25 +13587,39 @@ process.on('unhandledRejection', (reason) => {
|
|
|
13532
13587
|
continue;
|
|
13533
13588
|
}
|
|
13534
13589
|
|
|
13535
|
-
// Create mock stream handle that captures the handler's output
|
|
13590
|
+
// Create mock stream handle that captures the handler's output.
|
|
13591
|
+
// Uses retroactive delivery: if handler registers onData after data is
|
|
13592
|
+
// already queued, deliver immediately. Eliminates timing race.
|
|
13536
13593
|
var _nResults = [];
|
|
13537
|
-
var
|
|
13594
|
+
var _nDataCbs = [];
|
|
13595
|
+
var _nDataDelivered = false;
|
|
13538
13596
|
var _nHandle = {
|
|
13539
13597
|
write: async function(msg) {
|
|
13540
13598
|
if (msg && msg.type === 'invoke.event') _nResults.push(msg);
|
|
13541
|
-
if (msg && msg.type === 'invoke.done') _nHandleDone = true;
|
|
13542
13599
|
},
|
|
13543
13600
|
onData: function(cb) {
|
|
13544
|
-
|
|
13545
|
-
|
|
13601
|
+
if (_nDataDelivered) {
|
|
13602
|
+
// Data already flushed \u2014 deliver retroactively
|
|
13546
13603
|
try {
|
|
13547
13604
|
cb({ type: 'invoke.chunk', data: _nInputStr, seq: 0 });
|
|
13548
13605
|
cb({ type: 'invoke.done' });
|
|
13549
13606
|
} catch {}
|
|
13550
|
-
}
|
|
13607
|
+
} else {
|
|
13608
|
+
_nDataCbs.push(cb);
|
|
13609
|
+
}
|
|
13551
13610
|
},
|
|
13552
13611
|
close: function() {},
|
|
13553
13612
|
};
|
|
13613
|
+
// Flush input data to any registered onData listeners after 50ms
|
|
13614
|
+
setTimeout(function() {
|
|
13615
|
+
_nDataDelivered = true;
|
|
13616
|
+
for (var _di = 0; _di < _nDataCbs.length; _di++) {
|
|
13617
|
+
try {
|
|
13618
|
+
_nDataCbs[_di]({ type: 'invoke.chunk', data: _nInputStr, seq: 0 });
|
|
13619
|
+
_nDataCbs[_di]({ type: 'invoke.done' });
|
|
13620
|
+
} catch {}
|
|
13621
|
+
}
|
|
13622
|
+
}, 50);
|
|
13554
13623
|
|
|
13555
13624
|
var _nRequest = {
|
|
13556
13625
|
type: 'invoke.open',
|
|
@@ -13803,7 +13872,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13803
13872
|
result = await this.sendDaemonCmd("query_peer_caps", args, 2e4);
|
|
13804
13873
|
break;
|
|
13805
13874
|
case "invoke_capability":
|
|
13806
|
-
result = await this.sendDaemonCmd("invoke_capability", args,
|
|
13875
|
+
result = await this.sendDaemonCmd("invoke_capability", args, 32e4);
|
|
13807
13876
|
break;
|
|
13808
13877
|
case "store_content":
|
|
13809
13878
|
result = await this.sendDaemonCmd("store_content", args);
|
|
@@ -14899,7 +14968,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14899
14968
|
} else {
|
|
14900
14969
|
daemonArgs.prompt = prompt;
|
|
14901
14970
|
}
|
|
14902
|
-
const result = await this.sendDaemonCmd("remote_infer", daemonArgs,
|
|
14971
|
+
const result = await this.sendDaemonCmd("remote_infer", daemonArgs, 32e4);
|
|
14903
14972
|
let peerUsed = args.target_peer || "auto-selected";
|
|
14904
14973
|
try {
|
|
14905
14974
|
const parsed = JSON.parse(result);
|
|
@@ -35530,12 +35599,6 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
35530
35599
|
process.stdout.write("\n");
|
|
35531
35600
|
const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
|
|
35532
35601
|
const info = await checkForUpdate(currentVersion, true);
|
|
35533
|
-
if (!info) {
|
|
35534
|
-
checkSpinner.stop(`You're on the latest version (v${currentVersion}).`);
|
|
35535
|
-
process.stdout.write("\n");
|
|
35536
|
-
return;
|
|
35537
|
-
}
|
|
35538
|
-
checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
|
|
35539
35602
|
const { exec: exec3, execSync: es2 } = await import("node:child_process");
|
|
35540
35603
|
let needsSudo = false;
|
|
35541
35604
|
try {
|
|
@@ -35548,21 +35611,6 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
35548
35611
|
}
|
|
35549
35612
|
} catch {
|
|
35550
35613
|
}
|
|
35551
|
-
if (needsSudo) {
|
|
35552
|
-
renderInfo("Global npm directory requires elevated permissions.");
|
|
35553
|
-
renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
|
|
35554
|
-
process.stdout.write("\n");
|
|
35555
|
-
try {
|
|
35556
|
-
es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
|
|
35557
|
-
} catch {
|
|
35558
|
-
renderWarning("Could not acquire sudo credentials. Try: sudo npm i -g open-agents-ai");
|
|
35559
|
-
return;
|
|
35560
|
-
}
|
|
35561
|
-
}
|
|
35562
|
-
const sudoPrefix = needsSudo ? "sudo " : "";
|
|
35563
|
-
const installSpinner = startInlineSpinner("Installing update");
|
|
35564
|
-
const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
|
|
35565
|
-
let installOk = false;
|
|
35566
35614
|
let installError = "";
|
|
35567
35615
|
const runInstall2 = (cmd) => new Promise((resolve31) => {
|
|
35568
35616
|
const child = exec3(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
@@ -35572,35 +35620,84 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
35572
35620
|
});
|
|
35573
35621
|
child.stdout?.resume();
|
|
35574
35622
|
});
|
|
35575
|
-
|
|
35576
|
-
|
|
35577
|
-
|
|
35623
|
+
if (needsSudo) {
|
|
35624
|
+
renderInfo("Global npm directory requires elevated permissions.");
|
|
35625
|
+
renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
|
|
35626
|
+
process.stdout.write("\n");
|
|
35578
35627
|
try {
|
|
35579
|
-
|
|
35580
|
-
const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
|
|
35581
|
-
es2(`${sudoPrefix}find "${globalModules}" -maxdepth 1 -name ".open-agents-ai-*" -type d -exec rm -rf {} + 2>/dev/null || true`, { timeout: 15e3 });
|
|
35582
|
-
es2(`${sudoPrefix}rm -rf "${globalModules}/open-agents-ai" 2>/dev/null || true`, { timeout: 15e3 });
|
|
35628
|
+
es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
|
|
35583
35629
|
} catch {
|
|
35630
|
+
renderWarning("Could not acquire sudo credentials. Try: sudo npm i -g open-agents-ai");
|
|
35631
|
+
return;
|
|
35584
35632
|
}
|
|
35585
|
-
|
|
35586
|
-
|
|
35633
|
+
}
|
|
35634
|
+
const sudoPrefix = needsSudo ? "sudo " : "";
|
|
35635
|
+
let primaryUpdated = false;
|
|
35636
|
+
if (!info) {
|
|
35637
|
+
checkSpinner.stop(`Primary package up to date (v${currentVersion}).`);
|
|
35638
|
+
} else {
|
|
35639
|
+
checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
|
|
35640
|
+
const installSpinner = startInlineSpinner("Installing update");
|
|
35641
|
+
const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
|
|
35642
|
+
let installOk = false;
|
|
35587
35643
|
installOk = await runInstall2(installCmd);
|
|
35644
|
+
if (!installOk && /ENOTEMPTY|errno -39/i.test(installError)) {
|
|
35645
|
+
installSpinner.stop("Cleaning stale npm temp files...");
|
|
35646
|
+
try {
|
|
35647
|
+
const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
35648
|
+
const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
|
|
35649
|
+
es2(`${sudoPrefix}find "${globalModules}" -maxdepth 1 -name ".open-agents-ai-*" -type d -exec rm -rf {} + 2>/dev/null || true`, { timeout: 15e3 });
|
|
35650
|
+
es2(`${sudoPrefix}rm -rf "${globalModules}/open-agents-ai" 2>/dev/null || true`, { timeout: 15e3 });
|
|
35651
|
+
} catch {
|
|
35652
|
+
}
|
|
35653
|
+
const retrySpinner = startInlineSpinner("Retrying install");
|
|
35654
|
+
installError = "";
|
|
35655
|
+
installOk = await runInstall2(installCmd);
|
|
35656
|
+
if (!installOk) {
|
|
35657
|
+
retrySpinner.stop("Retry failed.");
|
|
35658
|
+
} else {
|
|
35659
|
+
retrySpinner.stop(`Update installed (v${info.latestVersion}).`);
|
|
35660
|
+
}
|
|
35661
|
+
}
|
|
35588
35662
|
if (!installOk) {
|
|
35589
|
-
|
|
35590
|
-
|
|
35591
|
-
|
|
35663
|
+
installSpinner.stop("Update install failed.");
|
|
35664
|
+
const errPreview = installError.split("\n").filter((l) => l.trim()).slice(-3).join("\n ");
|
|
35665
|
+
if (errPreview)
|
|
35666
|
+
renderWarning(`Error:
|
|
35667
|
+
${errPreview}`);
|
|
35668
|
+
renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
|
|
35669
|
+
return;
|
|
35592
35670
|
}
|
|
35671
|
+
installSpinner.stop(`Update installed (v${info.latestVersion}).`);
|
|
35672
|
+
primaryUpdated = true;
|
|
35593
35673
|
}
|
|
35594
|
-
|
|
35595
|
-
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35600
|
-
|
|
35674
|
+
const depsSpinner = startInlineSpinner("Checking subordinate dependencies");
|
|
35675
|
+
let depsUpdated = false;
|
|
35676
|
+
try {
|
|
35677
|
+
const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
35678
|
+
const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
|
|
35679
|
+
const { existsSync: fe, readFileSync: rf } = await import("node:fs");
|
|
35680
|
+
const { join: pj } = await import("node:path");
|
|
35681
|
+
const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
|
|
35682
|
+
if (fe(pkgPath)) {
|
|
35683
|
+
const pkg = JSON.parse(rf(pkgPath, "utf8"));
|
|
35684
|
+
const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
|
|
35685
|
+
const depNames = Object.keys(allDeps);
|
|
35686
|
+
if (depNames.length > 0) {
|
|
35687
|
+
const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
|
|
35688
|
+
const updateOk = await runInstall2(updateCmd);
|
|
35689
|
+
if (updateOk)
|
|
35690
|
+
depsUpdated = true;
|
|
35691
|
+
}
|
|
35692
|
+
}
|
|
35693
|
+
} catch {
|
|
35694
|
+
}
|
|
35695
|
+
depsSpinner.stop(depsUpdated ? "Dependencies updated to latest." : "Dependencies checked.");
|
|
35696
|
+
if (!primaryUpdated && !depsUpdated) {
|
|
35697
|
+
renderInfo("Everything is up to date \u2014 no changes needed.");
|
|
35698
|
+
process.stdout.write("\n");
|
|
35601
35699
|
return;
|
|
35602
35700
|
}
|
|
35603
|
-
installSpinner.stop(`Update installed (v${info.latestVersion}).`);
|
|
35604
35701
|
const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
|
|
35605
35702
|
const rebuildOk = await new Promise((resolve31) => {
|
|
35606
35703
|
const child = exec3(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve31(true));
|
|
@@ -47499,6 +47596,16 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
47499
47596
|
});
|
|
47500
47597
|
}
|
|
47501
47598
|
}
|
|
47599
|
+
try {
|
|
47600
|
+
const autoNexus = new NexusTool(repoRoot);
|
|
47601
|
+
autoNexus.execute({ action: "connect" }).then((r) => {
|
|
47602
|
+
if (r.success && r.output.includes("Connected")) {
|
|
47603
|
+
writeContent(() => renderInfo("Nexus P2P network connected."));
|
|
47604
|
+
}
|
|
47605
|
+
}).catch(() => {
|
|
47606
|
+
});
|
|
47607
|
+
} catch {
|
|
47608
|
+
}
|
|
47502
47609
|
try {
|
|
47503
47610
|
const oaDir = join50(repoRoot, ".oa");
|
|
47504
47611
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
package/package.json
CHANGED