open-agents-ai 0.103.67 → 0.103.69
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 +201 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12126,6 +12126,11 @@ const rooms = new Map();
|
|
|
12126
12126
|
let connected = false;
|
|
12127
12127
|
const blockedPeers = [];
|
|
12128
12128
|
|
|
12129
|
+
// NATS invoke relay \u2014 for cross-NAT fallback when direct libp2p dial fails.
|
|
12130
|
+
// Both peers connect to wss://demo.nats.io:8443, so NATS request/reply bridges the gap.
|
|
12131
|
+
var _natsConn = null;
|
|
12132
|
+
var _natsCodec = null;
|
|
12133
|
+
|
|
12129
12134
|
function writeStatus(extra = {}) {
|
|
12130
12135
|
const caps = typeof nexus.getRegisteredCapabilities === 'function'
|
|
12131
12136
|
? nexus.getRegisteredCapabilities() : [];
|
|
@@ -12285,8 +12290,37 @@ async function handleCmd(cmd) {
|
|
|
12285
12290
|
dlog('query_peer_caps: SUCCESS');
|
|
12286
12291
|
writeResp(id, { ok: true, output: typeof qpcResult === 'string' ? qpcResult : JSON.stringify(qpcResult, null, 2) });
|
|
12287
12292
|
} catch (qpcErr) {
|
|
12288
|
-
|
|
12289
|
-
|
|
12293
|
+
var qpcErrMsg = qpcErr.message || String(qpcErr);
|
|
12294
|
+
dlog('query_peer_caps: ERROR ' + qpcErrMsg);
|
|
12295
|
+
// NATS fallback for peer cap discovery across NAT
|
|
12296
|
+
if (_natsConn && _natsCodec && qpcErrMsg.includes('multiaddrs failed')) {
|
|
12297
|
+
dlog('query_peer_caps: trying NATS relay fallback');
|
|
12298
|
+
try {
|
|
12299
|
+
var _qpcNatsSubject = 'nexus.invoke.' + String(qpcPeerId);
|
|
12300
|
+
var _qpcNatsPayload = JSON.stringify({
|
|
12301
|
+
capability: '__list_capabilities',
|
|
12302
|
+
input: qpcInput,
|
|
12303
|
+
from: nexus.peerId || '',
|
|
12304
|
+
});
|
|
12305
|
+
var _qpcNatsResp = await _natsConn.request(
|
|
12306
|
+
_qpcNatsSubject,
|
|
12307
|
+
_natsCodec.encode(_qpcNatsPayload),
|
|
12308
|
+
{ timeout: 15000 }
|
|
12309
|
+
);
|
|
12310
|
+
var _qpcNatsResult = JSON.parse(_natsCodec.decode(_qpcNatsResp.data));
|
|
12311
|
+
if (_qpcNatsResult && _qpcNatsResult.error) {
|
|
12312
|
+
writeResp(id, { ok: false, output: 'query_peer_caps (NATS): ' + _qpcNatsResult.error });
|
|
12313
|
+
} else {
|
|
12314
|
+
dlog('query_peer_caps: SUCCESS via NATS relay');
|
|
12315
|
+
writeResp(id, { ok: true, output: typeof _qpcNatsResult === 'string' ? _qpcNatsResult : JSON.stringify(_qpcNatsResult, null, 2) });
|
|
12316
|
+
}
|
|
12317
|
+
} catch (_qpcNatsErr) {
|
|
12318
|
+
dlog('query_peer_caps: NATS fallback also failed: ' + (_qpcNatsErr.message || _qpcNatsErr));
|
|
12319
|
+
writeResp(id, { ok: false, output: 'query_peer_caps error (libp2p + NATS): ' + qpcErrMsg });
|
|
12320
|
+
}
|
|
12321
|
+
} else {
|
|
12322
|
+
writeResp(id, { ok: false, output: 'query_peer_caps error: ' + qpcErrMsg });
|
|
12323
|
+
}
|
|
12290
12324
|
}
|
|
12291
12325
|
break;
|
|
12292
12326
|
}
|
|
@@ -12305,8 +12339,37 @@ async function handleCmd(cmd) {
|
|
|
12305
12339
|
dlog('invoke_capability: SUCCESS');
|
|
12306
12340
|
writeResp(id, { ok: true, output: JSON.stringify(result, null, 2) });
|
|
12307
12341
|
} catch (invokeErr) {
|
|
12308
|
-
|
|
12309
|
-
|
|
12342
|
+
var invokeErrMsg = invokeErr.message || String(invokeErr);
|
|
12343
|
+
dlog('invoke_capability: ERROR ' + invokeErrMsg);
|
|
12344
|
+
// NATS fallback \u2014 if direct dial failed (NAT), retry via NATS relay
|
|
12345
|
+
if (_natsConn && _natsCodec && invokeErrMsg.includes('multiaddrs failed')) {
|
|
12346
|
+
dlog('invoke_capability: trying NATS relay fallback for ' + peerId.slice(0, 20));
|
|
12347
|
+
try {
|
|
12348
|
+
var _icNatsSubject = 'nexus.invoke.' + peerId;
|
|
12349
|
+
var _icNatsPayload = JSON.stringify({
|
|
12350
|
+
capability: capability,
|
|
12351
|
+
input: typeof input === 'string' ? { prompt: input } : input,
|
|
12352
|
+
from: nexus.peerId || '',
|
|
12353
|
+
});
|
|
12354
|
+
var _icNatsResp = await _natsConn.request(
|
|
12355
|
+
_icNatsSubject,
|
|
12356
|
+
_natsCodec.encode(_icNatsPayload),
|
|
12357
|
+
{ timeout: 240000 }
|
|
12358
|
+
);
|
|
12359
|
+
var _icNatsResult = JSON.parse(_natsCodec.decode(_icNatsResp.data));
|
|
12360
|
+
if (_icNatsResult && _icNatsResult.error) {
|
|
12361
|
+
writeResp(id, { ok: false, output: 'NATS relay error: ' + _icNatsResult.error });
|
|
12362
|
+
} else {
|
|
12363
|
+
dlog('invoke_capability: SUCCESS via NATS relay');
|
|
12364
|
+
writeResp(id, { ok: true, output: typeof _icNatsResult === 'string' ? _icNatsResult : JSON.stringify(_icNatsResult, null, 2) });
|
|
12365
|
+
}
|
|
12366
|
+
} catch (_icNatsErr) {
|
|
12367
|
+
dlog('invoke_capability: NATS fallback also failed: ' + (_icNatsErr.message || _icNatsErr));
|
|
12368
|
+
writeResp(id, { ok: false, output: 'Invoke error (libp2p + NATS fallback failed): ' + invokeErrMsg });
|
|
12369
|
+
}
|
|
12370
|
+
} else {
|
|
12371
|
+
writeResp(id, { ok: false, output: 'Invoke error: ' + invokeErrMsg });
|
|
12372
|
+
}
|
|
12310
12373
|
}
|
|
12311
12374
|
break;
|
|
12312
12375
|
}
|
|
@@ -12355,9 +12418,39 @@ async function handleCmd(cmd) {
|
|
|
12355
12418
|
var riResult = await Promise.race([riInvokeP, riTimeoutP]);
|
|
12356
12419
|
dlog('remote_infer: SUCCESS (explicit peer)');
|
|
12357
12420
|
} catch (riErr) {
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12421
|
+
var riErrMsg = riErr.message || String(riErr);
|
|
12422
|
+
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.includes('multiaddrs failed')) {
|
|
12425
|
+
dlog('remote_infer: trying NATS relay fallback for ' + riTargetPeer.slice(0, 20));
|
|
12426
|
+
try {
|
|
12427
|
+
var _riNatsSubject = 'nexus.invoke.' + riTargetPeer;
|
|
12428
|
+
var _riNatsPayload = JSON.stringify({
|
|
12429
|
+
capability: riCapName,
|
|
12430
|
+
input: riData,
|
|
12431
|
+
from: nexus.peerId || '',
|
|
12432
|
+
});
|
|
12433
|
+
var _riNatsResp = await _natsConn.request(
|
|
12434
|
+
_riNatsSubject,
|
|
12435
|
+
_natsCodec.encode(_riNatsPayload),
|
|
12436
|
+
{ timeout: 240000 }
|
|
12437
|
+
);
|
|
12438
|
+
var _riNatsResult = JSON.parse(_natsCodec.decode(_riNatsResp.data));
|
|
12439
|
+
if (_riNatsResult && _riNatsResult.error) {
|
|
12440
|
+
writeResp(id, { ok: false, output: 'Remote inference failed (NATS relay): ' + _riNatsResult.error });
|
|
12441
|
+
return;
|
|
12442
|
+
}
|
|
12443
|
+
riResult = _riNatsResult;
|
|
12444
|
+
dlog('remote_infer: SUCCESS via NATS relay');
|
|
12445
|
+
} catch (_riNatsErr) {
|
|
12446
|
+
dlog('remote_infer: NATS fallback also failed: ' + (_riNatsErr.message || _riNatsErr));
|
|
12447
|
+
writeResp(id, { ok: false, output: 'Remote inference failed (libp2p + NATS): ' + riErrMsg });
|
|
12448
|
+
return;
|
|
12449
|
+
}
|
|
12450
|
+
} else {
|
|
12451
|
+
writeResp(id, { ok: false, output: 'Remote inference failed: ' + riErrMsg });
|
|
12452
|
+
return;
|
|
12453
|
+
}
|
|
12361
12454
|
}
|
|
12362
12455
|
} else {
|
|
12363
12456
|
// Auto-discover: try speculative invoke on each 12D3KooW peer
|
|
@@ -13402,6 +13495,97 @@ process.on('unhandledRejection', (reason) => {
|
|
|
13402
13495
|
dlog('NATS subscribe failed: ' + (natsSubErr.message || natsSubErr));
|
|
13403
13496
|
}
|
|
13404
13497
|
|
|
13498
|
+
// NATS invoke relay \u2014 subscribe to nexus.invoke.<myPeerId> for cross-NAT invoke fallback.
|
|
13499
|
+
// When a remote peer can't direct-dial us (all multiaddrs are private), they retry
|
|
13500
|
+
// via NATS request/reply. We dispatch to the registered capability handler using a
|
|
13501
|
+
// mock stream interface, then reply with the result.
|
|
13502
|
+
try {
|
|
13503
|
+
var _nc = nexus.nats && nexus.nats.nc ? nexus.nats.nc : null;
|
|
13504
|
+
if (_nc) {
|
|
13505
|
+
var _nws = await import('nats.ws');
|
|
13506
|
+
_natsConn = _nc;
|
|
13507
|
+
_natsCodec = _nws.StringCodec();
|
|
13508
|
+
var _natsInvSubject = 'nexus.invoke.' + nexus.peerId;
|
|
13509
|
+
var _natsInvSub = _nc.subscribe(_natsInvSubject);
|
|
13510
|
+
dlog('NATS invoke relay listening on ' + _natsInvSubject);
|
|
13511
|
+
|
|
13512
|
+
(async function _natsInvokeLoop() {
|
|
13513
|
+
for await (var _nm of _natsInvSub) {
|
|
13514
|
+
try {
|
|
13515
|
+
var _nReq = JSON.parse(_natsCodec.decode(_nm.data));
|
|
13516
|
+
var _nCap = _nReq.capability || '';
|
|
13517
|
+
var _nInput = _nReq.input || {};
|
|
13518
|
+
var _nInputStr = typeof _nInput === 'string' ? _nInput : JSON.stringify(_nInput);
|
|
13519
|
+
dlog('NATS relay invoke: cap=' + _nCap + ' from=' + (_nReq.from || 'unknown').slice(0, 20));
|
|
13520
|
+
|
|
13521
|
+
// Look up registered handler
|
|
13522
|
+
var _nHandler = null;
|
|
13523
|
+
if (nexus.capabilityHandlers && typeof nexus.capabilityHandlers.get === 'function') {
|
|
13524
|
+
_nHandler = nexus.capabilityHandlers.get(_nCap);
|
|
13525
|
+
}
|
|
13526
|
+
if (!_nHandler) {
|
|
13527
|
+
var _nCaps = typeof nexus.getRegisteredCapabilities === 'function'
|
|
13528
|
+
? nexus.getRegisteredCapabilities() : [];
|
|
13529
|
+
_nm.respond(_natsCodec.encode(JSON.stringify({
|
|
13530
|
+
error: 'Capability not found: ' + _nCap + '. Available: ' + _nCaps.join(', ')
|
|
13531
|
+
})));
|
|
13532
|
+
continue;
|
|
13533
|
+
}
|
|
13534
|
+
|
|
13535
|
+
// Create mock stream handle that captures the handler's output
|
|
13536
|
+
var _nResults = [];
|
|
13537
|
+
var _nHandleDone = false;
|
|
13538
|
+
var _nHandle = {
|
|
13539
|
+
write: async function(msg) {
|
|
13540
|
+
if (msg && msg.type === 'invoke.event') _nResults.push(msg);
|
|
13541
|
+
if (msg && msg.type === 'invoke.done') _nHandleDone = true;
|
|
13542
|
+
},
|
|
13543
|
+
onData: function(cb) {
|
|
13544
|
+
// Deliver input data asynchronously after handler registers its listener
|
|
13545
|
+
setTimeout(function() {
|
|
13546
|
+
try {
|
|
13547
|
+
cb({ type: 'invoke.chunk', data: _nInputStr, seq: 0 });
|
|
13548
|
+
cb({ type: 'invoke.done' });
|
|
13549
|
+
} catch {}
|
|
13550
|
+
}, 5);
|
|
13551
|
+
},
|
|
13552
|
+
close: function() {},
|
|
13553
|
+
};
|
|
13554
|
+
|
|
13555
|
+
var _nRequest = {
|
|
13556
|
+
type: 'invoke.open',
|
|
13557
|
+
requestId: 'nats-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8),
|
|
13558
|
+
capability: _nCap,
|
|
13559
|
+
from: _nReq.from || 'nats-peer',
|
|
13560
|
+
};
|
|
13561
|
+
|
|
13562
|
+
await _nHandler(_nRequest, _nHandle);
|
|
13563
|
+
|
|
13564
|
+
// Extract result from captured invoke.event messages
|
|
13565
|
+
var _nResult = null;
|
|
13566
|
+
if (_nResults.length === 1) {
|
|
13567
|
+
_nResult = _nResults[0].data;
|
|
13568
|
+
} else if (_nResults.length > 1) {
|
|
13569
|
+
_nResult = _nResults.map(function(r) { return r.data; });
|
|
13570
|
+
}
|
|
13571
|
+
|
|
13572
|
+
_nm.respond(_natsCodec.encode(JSON.stringify(_nResult !== null && _nResult !== undefined ? _nResult : { ok: true })));
|
|
13573
|
+
dlog('NATS relay invoke SUCCESS: ' + _nCap);
|
|
13574
|
+
} catch (_nErr) {
|
|
13575
|
+
dlog('NATS relay invoke error: ' + (_nErr.message || _nErr));
|
|
13576
|
+
try {
|
|
13577
|
+
_nm.respond(_natsCodec.encode(JSON.stringify({ error: String(_nErr.message || _nErr) })));
|
|
13578
|
+
} catch {}
|
|
13579
|
+
}
|
|
13580
|
+
}
|
|
13581
|
+
})().catch(function(e) { dlog('NATS invoke relay loop error: ' + (e.message || e)); });
|
|
13582
|
+
} else {
|
|
13583
|
+
dlog('NATS not connected \u2014 invoke relay disabled (cross-NAT invoke will not work)');
|
|
13584
|
+
}
|
|
13585
|
+
} catch (_nSetupErr) {
|
|
13586
|
+
dlog('NATS invoke relay setup failed: ' + (_nSetupErr.message || _nSetupErr));
|
|
13587
|
+
}
|
|
13588
|
+
|
|
13405
13589
|
writeStatus();
|
|
13406
13590
|
console.log('Nexus daemon connected as ' + nexus.peerId);
|
|
13407
13591
|
} catch (err) {
|
|
@@ -47315,6 +47499,16 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
47315
47499
|
});
|
|
47316
47500
|
}
|
|
47317
47501
|
}
|
|
47502
|
+
try {
|
|
47503
|
+
const autoNexus = new NexusTool(repoRoot);
|
|
47504
|
+
autoNexus.execute({ action: "connect" }).then((r) => {
|
|
47505
|
+
if (r.success && r.output.includes("Connected")) {
|
|
47506
|
+
writeContent(() => renderInfo("Nexus P2P network connected."));
|
|
47507
|
+
}
|
|
47508
|
+
}).catch(() => {
|
|
47509
|
+
});
|
|
47510
|
+
} catch {
|
|
47511
|
+
}
|
|
47318
47512
|
try {
|
|
47319
47513
|
const oaDir = join50(repoRoot, ".oa");
|
|
47320
47514
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
package/package.json
CHANGED