open-agents-ai 0.187.534 → 0.187.536
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 +1364 -452
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7783,11 +7783,41 @@ async function handleCmd(cmd) {
|
|
|
7783
7783
|
const capability = args.capability || 'text-generation';
|
|
7784
7784
|
const input = args.input || {};
|
|
7785
7785
|
if (!peerId) { writeResp(id, { ok: false, output: 'target_peer is required' }); return; }
|
|
7786
|
-
|
|
7786
|
+
// Streaming mode: when stream_file is supplied, tee invoke events
|
|
7787
|
+
// to the file as JSONL so the caller can tail them in real time.
|
|
7788
|
+
const icStreamFile = typeof args.stream_file === 'string' ? args.stream_file : '';
|
|
7789
|
+
const icUseStream = !!icStreamFile;
|
|
7790
|
+
dlog('invoke_capability: peer=' + peerId.slice(0, 20) + ' cap=' + capability + (icUseStream ? ' [stream]' : ''));
|
|
7787
7791
|
try {
|
|
7788
|
-
// Race libp2p + NATS in parallel — whichever route works first wins
|
|
7789
7792
|
const INVOKE_TIMEOUT = 300_000;
|
|
7790
7793
|
const invokeInput = typeof input === 'string' ? { prompt: input } : input;
|
|
7794
|
+
if (icUseStream) {
|
|
7795
|
+
// Stream-mode: get an AsyncGenerator and tee each event to the file.
|
|
7796
|
+
var icStreamGen;
|
|
7797
|
+
try {
|
|
7798
|
+
icStreamGen = await nexus.invokeCapability(peerId, capability, invokeInput, { stream: true, maxDurationMs: 240000 });
|
|
7799
|
+
} catch (invokeStartErr) {
|
|
7800
|
+
writeResp(id, { ok: false, output: 'Invoke start failed: ' + (invokeStartErr.message || invokeStartErr) });
|
|
7801
|
+
break;
|
|
7802
|
+
}
|
|
7803
|
+
// Signal the caller that streaming has begun.
|
|
7804
|
+
writeResp(id, { ok: true, output: JSON.stringify({ streaming: true, stream_file: icStreamFile }) });
|
|
7805
|
+
try {
|
|
7806
|
+
for await (var icEvt of icStreamGen) {
|
|
7807
|
+
appendFileSync(icStreamFile, JSON.stringify({ type: 'event', event: icEvt.event || '', seq: icEvt.seq || 0, data: icEvt.data }) + '
|
|
7808
|
+
');
|
|
7809
|
+
}
|
|
7810
|
+
appendFileSync(icStreamFile, JSON.stringify({ type: 'done' }) + '
|
|
7811
|
+
');
|
|
7812
|
+
dlog('invoke_capability: stream complete');
|
|
7813
|
+
} catch (icStreamErr) {
|
|
7814
|
+
appendFileSync(icStreamFile, JSON.stringify({ type: 'error', error: String(icStreamErr.message || icStreamErr) }) + '
|
|
7815
|
+
');
|
|
7816
|
+
dlog('invoke_capability: stream error: ' + (icStreamErr.message || icStreamErr));
|
|
7817
|
+
}
|
|
7818
|
+
break;
|
|
7819
|
+
}
|
|
7820
|
+
// Non-stream mode: race libp2p + NATS in parallel.
|
|
7791
7821
|
const invokePromise = nexus.invokeCapability(peerId, capability, invokeInput, { stream: false, maxDurationMs: 240000 });
|
|
7792
7822
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('invoke_capability timed out after ' + (INVOKE_TIMEOUT / 1000) + 's')), INVOKE_TIMEOUT));
|
|
7793
7823
|
|
|
@@ -9427,6 +9457,158 @@ process.on('unhandledRejection', (reason) => {
|
|
|
9427
9457
|
}
|
|
9428
9458
|
connected = true;
|
|
9429
9459
|
|
|
9460
|
+
// Register this nexus dir in the global registry so the API daemon
|
|
9461
|
+
// (and any other consumer) can discover us regardless of cwd.
|
|
9462
|
+
try {
|
|
9463
|
+
var nodePath_reg = require('node:path');
|
|
9464
|
+
var nodeFs_reg = require('node:fs');
|
|
9465
|
+
var nodeOs_reg = require('node:os');
|
|
9466
|
+
var regDir = nodePath_reg.join(nodeOs_reg.homedir(), '.open-agents');
|
|
9467
|
+
if (!nodeFs_reg.existsSync(regDir)) nodeFs_reg.mkdirSync(regDir, { recursive: true });
|
|
9468
|
+
var regFile = nodePath_reg.join(regDir, 'nexus-registry.json');
|
|
9469
|
+
var existing = { dirs: [] };
|
|
9470
|
+
try {
|
|
9471
|
+
if (nodeFs_reg.existsSync(regFile)) existing = JSON.parse(nodeFs_reg.readFileSync(regFile, 'utf-8')) || { dirs: [] };
|
|
9472
|
+
if (!Array.isArray(existing.dirs)) existing.dirs = [];
|
|
9473
|
+
} catch { existing = { dirs: [] }; }
|
|
9474
|
+
// Drop entries that no longer exist on disk
|
|
9475
|
+
existing.dirs = existing.dirs.filter(function(e) {
|
|
9476
|
+
var d = typeof e === 'string' ? e : (e && e.dir);
|
|
9477
|
+
return d && nodeFs_reg.existsSync(nodePath_reg.join(d, 'status.json'));
|
|
9478
|
+
});
|
|
9479
|
+
// De-dup + prepend ourselves
|
|
9480
|
+
var meDir = nexusDir;
|
|
9481
|
+
existing.dirs = existing.dirs.filter(function(e) {
|
|
9482
|
+
var d = typeof e === 'string' ? e : (e && e.dir);
|
|
9483
|
+
return d !== meDir;
|
|
9484
|
+
});
|
|
9485
|
+
existing.dirs.unshift({
|
|
9486
|
+
dir: meDir,
|
|
9487
|
+
peerId: nexus.peerId || '',
|
|
9488
|
+
pid: process.pid,
|
|
9489
|
+
startedAt: new Date().toISOString(),
|
|
9490
|
+
});
|
|
9491
|
+
// Cap at 16 entries
|
|
9492
|
+
if (existing.dirs.length > 16) existing.dirs = existing.dirs.slice(0, 16);
|
|
9493
|
+
nodeFs_reg.writeFileSync(regFile, JSON.stringify(existing, null, 2));
|
|
9494
|
+
dlog('nexus-registry: registered ' + meDir);
|
|
9495
|
+
} catch (regErr) {
|
|
9496
|
+
dlog('nexus-registry write failed: ' + (regErr.message || regErr));
|
|
9497
|
+
}
|
|
9498
|
+
|
|
9499
|
+
// http_tunnel capability — proxies HTTP requests from remote peers
|
|
9500
|
+
// to the local OA API daemon. Auth is delegated to the API key store
|
|
9501
|
+
// (remote sends share key in Authorization header). SSE streams are
|
|
9502
|
+
// forwarded chunk-by-chunk over libp2p invoke. The local API port is
|
|
9503
|
+
// read from nexusDir/api-port.json which oa serve writes on startup.
|
|
9504
|
+
if (typeof nexus.registerCapability === 'function') {
|
|
9505
|
+
var nodePathMod = require('node:path');
|
|
9506
|
+
var apiPortHintPath = nodePathMod.join(nexusDir, 'api-port.json');
|
|
9507
|
+
nexus.registerCapability('http_tunnel', async (request, stream) => {
|
|
9508
|
+
var htClosed = false;
|
|
9509
|
+
async function htWrite(msg) {
|
|
9510
|
+
if (htClosed) return;
|
|
9511
|
+
try { await stream.write(msg); } catch { htClosed = true; }
|
|
9512
|
+
}
|
|
9513
|
+
var htChunks = [];
|
|
9514
|
+
var htInputDone = false;
|
|
9515
|
+
stream.onData(function(msg) {
|
|
9516
|
+
if (msg.type === 'invoke.chunk') {
|
|
9517
|
+
htChunks.push(typeof msg.data === 'string' ? msg.data : JSON.stringify(msg.data));
|
|
9518
|
+
}
|
|
9519
|
+
if (msg.type === 'invoke.done' || msg.type === 'invoke.end') htInputDone = true;
|
|
9520
|
+
});
|
|
9521
|
+
await htWrite({ type: 'invoke.accept', version: 1, requestId: request.requestId, accepted: true });
|
|
9522
|
+
var htWait = 0;
|
|
9523
|
+
while (!htInputDone && htWait < 5000) {
|
|
9524
|
+
await new Promise(function(r) { setTimeout(r, 20); });
|
|
9525
|
+
htWait += 20;
|
|
9526
|
+
}
|
|
9527
|
+
var htReq;
|
|
9528
|
+
try {
|
|
9529
|
+
htReq = JSON.parse(htChunks.join(''));
|
|
9530
|
+
} catch (parseErr) {
|
|
9531
|
+
await htWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'http.error', data: 'Bad request JSON: ' + (parseErr.message || parseErr) });
|
|
9532
|
+
await htWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
9533
|
+
try { stream.close(); } catch {}
|
|
9534
|
+
return;
|
|
9535
|
+
}
|
|
9536
|
+
// Resolve API endpoint from sibling api-port.json
|
|
9537
|
+
var htApiHost = '127.0.0.1';
|
|
9538
|
+
var htApiPort = 11435;
|
|
9539
|
+
var htApiScheme = 'http';
|
|
9540
|
+
try {
|
|
9541
|
+
if (existsSync(apiPortHintPath)) {
|
|
9542
|
+
var apiCfg = JSON.parse(readFileSync(apiPortHintPath, 'utf-8'));
|
|
9543
|
+
if (typeof apiCfg.port === 'number' && apiCfg.port > 0) htApiPort = apiCfg.port;
|
|
9544
|
+
if (typeof apiCfg.scheme === 'string') htApiScheme = apiCfg.scheme;
|
|
9545
|
+
if (typeof apiCfg.host === 'string' && apiCfg.host) htApiHost = apiCfg.host;
|
|
9546
|
+
} else {
|
|
9547
|
+
dlog('http_tunnel: api-port.json missing — using defaults 127.0.0.1:11435');
|
|
9548
|
+
}
|
|
9549
|
+
} catch (cfgErr) {
|
|
9550
|
+
dlog('http_tunnel: api-port.json parse failed: ' + (cfgErr.message || cfgErr));
|
|
9551
|
+
}
|
|
9552
|
+
var htPath = typeof htReq.path === 'string' ? htReq.path : '/';
|
|
9553
|
+
if (!htPath.startsWith('/')) htPath = '/' + htPath;
|
|
9554
|
+
var htUrl = htApiScheme + '://' + htApiHost + ':' + htApiPort + htPath;
|
|
9555
|
+
var htMethod = (htReq.method || 'GET').toUpperCase();
|
|
9556
|
+
var htHeaders = (htReq.headers && typeof htReq.headers === 'object') ? Object.assign({}, htReq.headers) : {};
|
|
9557
|
+
// Inject auth — share key from req.key overrides any incoming auth
|
|
9558
|
+
if (typeof htReq.key === 'string' && htReq.key) {
|
|
9559
|
+
htHeaders['authorization'] = 'Bearer ' + htReq.key;
|
|
9560
|
+
}
|
|
9561
|
+
// Strip hop-by-hop headers that don't translate
|
|
9562
|
+
delete htHeaders['host'];
|
|
9563
|
+
delete htHeaders['connection'];
|
|
9564
|
+
delete htHeaders['content-length'];
|
|
9565
|
+
var htBodyInit;
|
|
9566
|
+
if (htMethod !== 'GET' && htMethod !== 'HEAD' && htReq.body !== undefined && htReq.body !== null) {
|
|
9567
|
+
if (typeof htReq.body === 'string') htBodyInit = htReq.body;
|
|
9568
|
+
else htBodyInit = JSON.stringify(htReq.body);
|
|
9569
|
+
if (!htHeaders['content-type']) htHeaders['content-type'] = 'application/json';
|
|
9570
|
+
}
|
|
9571
|
+
dlog('http_tunnel: ' + htMethod + ' ' + htPath + ' from ' + (request.from || '?').slice(0, 16));
|
|
9572
|
+
try {
|
|
9573
|
+
var htResp = await fetch(htUrl, {
|
|
9574
|
+
method: htMethod, headers: htHeaders, body: htBodyInit,
|
|
9575
|
+
});
|
|
9576
|
+
var htRespHeaders = {};
|
|
9577
|
+
htResp.headers.forEach(function(v, k) { htRespHeaders[k] = v; });
|
|
9578
|
+
var htCT = (htRespHeaders['content-type'] || '').toLowerCase();
|
|
9579
|
+
var htIsStream = htCT.includes('text/event-stream') || htCT.includes('application/x-ndjson');
|
|
9580
|
+
await htWrite({
|
|
9581
|
+
type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0,
|
|
9582
|
+
event: 'http.head',
|
|
9583
|
+
data: JSON.stringify({ status: htResp.status, headers: htRespHeaders, streaming: htIsStream }),
|
|
9584
|
+
});
|
|
9585
|
+
var htSeq = 1;
|
|
9586
|
+
if (htIsStream && htResp.body) {
|
|
9587
|
+
var htReader = htResp.body.getReader();
|
|
9588
|
+
var htDecoder = new TextDecoder();
|
|
9589
|
+
while (true) {
|
|
9590
|
+
var htChunk = await htReader.read();
|
|
9591
|
+
if (htChunk.done) break;
|
|
9592
|
+
var htText = htDecoder.decode(htChunk.value, { stream: true });
|
|
9593
|
+
if (htText) {
|
|
9594
|
+
await htWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: htSeq++, event: 'http.chunk', data: htText });
|
|
9595
|
+
}
|
|
9596
|
+
}
|
|
9597
|
+
} else {
|
|
9598
|
+
var htBodyText = await htResp.text();
|
|
9599
|
+
await htWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: htSeq++, event: 'http.body', data: htBodyText });
|
|
9600
|
+
}
|
|
9601
|
+
await htWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
9602
|
+
} catch (htErr) {
|
|
9603
|
+
dlog('http_tunnel: fetch failed: ' + (htErr.message || htErr));
|
|
9604
|
+
await htWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'http.error', data: String(htErr.message || htErr) });
|
|
9605
|
+
await htWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: 0 } });
|
|
9606
|
+
}
|
|
9607
|
+
try { stream.close(); } catch {}
|
|
9608
|
+
});
|
|
9609
|
+
dlog('http_tunnel capability registered (api hint: ' + apiPortHintPath + ')');
|
|
9610
|
+
}
|
|
9611
|
+
|
|
9430
9612
|
// Monkey-patch node.dialProtocol AND node.dial to convert string multiaddrs
|
|
9431
9613
|
// to proper Multiaddr objects. libp2p v3 transports call .getComponents()
|
|
9432
9614
|
// on multiaddr objects, which fails on plain strings. open-agents-nexus
|
|
@@ -247683,11 +247865,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
247683
247865
|
* what was previously computed. */
|
|
247684
247866
|
async loadSessionInfo() {
|
|
247685
247867
|
try {
|
|
247686
|
-
const { readFileSync:
|
|
247868
|
+
const { readFileSync: readFileSync89, existsSync: existsSync110 } = await import("node:fs");
|
|
247687
247869
|
const sessionPath2 = join28(this.cwd, ".oa", "rlm", "session.json");
|
|
247688
|
-
if (!
|
|
247870
|
+
if (!existsSync110(sessionPath2))
|
|
247689
247871
|
return null;
|
|
247690
|
-
return JSON.parse(
|
|
247872
|
+
return JSON.parse(readFileSync89(sessionPath2, "utf8"));
|
|
247691
247873
|
} catch {
|
|
247692
247874
|
return null;
|
|
247693
247875
|
}
|
|
@@ -247864,10 +248046,10 @@ var init_memory_metabolism = __esm({
|
|
|
247864
248046
|
const trajDir = join29(this.cwd, ".oa", "rlm-trajectories");
|
|
247865
248047
|
let lessons = [];
|
|
247866
248048
|
try {
|
|
247867
|
-
const { readdirSync: readdirSync39, readFileSync:
|
|
248049
|
+
const { readdirSync: readdirSync39, readFileSync: readFileSync89 } = await import("node:fs");
|
|
247868
248050
|
const files = readdirSync39(trajDir).filter((f2) => f2.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
247869
248051
|
for (const file of files) {
|
|
247870
|
-
const lines =
|
|
248052
|
+
const lines = readFileSync89(join29(trajDir, file), "utf8").split("\n").filter((l2) => l2.trim());
|
|
247871
248053
|
for (const line of lines) {
|
|
247872
248054
|
try {
|
|
247873
248055
|
const entry = JSON.parse(line);
|
|
@@ -248251,14 +248433,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248251
248433
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
248252
248434
|
*/
|
|
248253
248435
|
getTopMemoriesSync(k = 5, taskType) {
|
|
248254
|
-
const { readFileSync:
|
|
248436
|
+
const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
|
|
248255
248437
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248256
248438
|
const storeFile = join29(metaDir, "store.json");
|
|
248257
|
-
if (!
|
|
248439
|
+
if (!existsSync110(storeFile))
|
|
248258
248440
|
return "";
|
|
248259
248441
|
let store2 = [];
|
|
248260
248442
|
try {
|
|
248261
|
-
store2 = JSON.parse(
|
|
248443
|
+
store2 = JSON.parse(readFileSync89(storeFile, "utf8"));
|
|
248262
248444
|
} catch {
|
|
248263
248445
|
return "";
|
|
248264
248446
|
}
|
|
@@ -248280,14 +248462,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248280
248462
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
248281
248463
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
248282
248464
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
248283
|
-
const { readFileSync:
|
|
248465
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync59, existsSync: existsSync110, mkdirSync: mkdirSync67 } = __require("node:fs");
|
|
248284
248466
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248285
248467
|
const storeFile = join29(metaDir, "store.json");
|
|
248286
|
-
if (!
|
|
248468
|
+
if (!existsSync110(storeFile))
|
|
248287
248469
|
return;
|
|
248288
248470
|
let store2 = [];
|
|
248289
248471
|
try {
|
|
248290
|
-
store2 = JSON.parse(
|
|
248472
|
+
store2 = JSON.parse(readFileSync89(storeFile, "utf8"));
|
|
248291
248473
|
} catch {
|
|
248292
248474
|
return;
|
|
248293
248475
|
}
|
|
@@ -248734,13 +248916,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248734
248916
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
248735
248917
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
248736
248918
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
248737
|
-
const { readFileSync:
|
|
248919
|
+
const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
|
|
248738
248920
|
const archiveFile = join31(this.cwd, ".oa", "arche", "variants.json");
|
|
248739
|
-
if (!
|
|
248921
|
+
if (!existsSync110(archiveFile))
|
|
248740
248922
|
return "";
|
|
248741
248923
|
let variants = [];
|
|
248742
248924
|
try {
|
|
248743
|
-
variants = JSON.parse(
|
|
248925
|
+
variants = JSON.parse(readFileSync89(archiveFile, "utf8"));
|
|
248744
248926
|
} catch {
|
|
248745
248927
|
return "";
|
|
248746
248928
|
}
|
|
@@ -248758,13 +248940,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248758
248940
|
}
|
|
248759
248941
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
248760
248942
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
248761
|
-
const { readFileSync:
|
|
248943
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync59, existsSync: existsSync110, mkdirSync: mkdirSync67 } = __require("node:fs");
|
|
248762
248944
|
const dir = join31(this.cwd, ".oa", "arche");
|
|
248763
248945
|
const archiveFile = join31(dir, "variants.json");
|
|
248764
248946
|
let variants = [];
|
|
248765
248947
|
try {
|
|
248766
|
-
if (
|
|
248767
|
-
variants = JSON.parse(
|
|
248948
|
+
if (existsSync110(archiveFile))
|
|
248949
|
+
variants = JSON.parse(readFileSync89(archiveFile, "utf8"));
|
|
248768
248950
|
} catch {
|
|
248769
248951
|
}
|
|
248770
248952
|
variants.push({
|
|
@@ -257044,7 +257226,7 @@ var require_util9 = __commonJS({
|
|
|
257044
257226
|
return path8;
|
|
257045
257227
|
}
|
|
257046
257228
|
exports.normalize = normalize2;
|
|
257047
|
-
function
|
|
257229
|
+
function join128(aRoot, aPath) {
|
|
257048
257230
|
if (aRoot === "") {
|
|
257049
257231
|
aRoot = ".";
|
|
257050
257232
|
}
|
|
@@ -257076,7 +257258,7 @@ var require_util9 = __commonJS({
|
|
|
257076
257258
|
}
|
|
257077
257259
|
return joined;
|
|
257078
257260
|
}
|
|
257079
|
-
exports.join =
|
|
257261
|
+
exports.join = join128;
|
|
257080
257262
|
exports.isAbsolute = function(aPath) {
|
|
257081
257263
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
257082
257264
|
};
|
|
@@ -257249,7 +257431,7 @@ var require_util9 = __commonJS({
|
|
|
257249
257431
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
257250
257432
|
}
|
|
257251
257433
|
}
|
|
257252
|
-
sourceURL =
|
|
257434
|
+
sourceURL = join128(urlGenerate(parsed), sourceURL);
|
|
257253
257435
|
}
|
|
257254
257436
|
return normalize2(sourceURL);
|
|
257255
257437
|
}
|
|
@@ -472669,7 +472851,7 @@ var require_path_browserify = __commonJS({
|
|
|
472669
472851
|
assertPath(path8);
|
|
472670
472852
|
return path8.length > 0 && path8.charCodeAt(0) === 47;
|
|
472671
472853
|
},
|
|
472672
|
-
join: function
|
|
472854
|
+
join: function join128() {
|
|
472673
472855
|
if (arguments.length === 0)
|
|
472674
472856
|
return ".";
|
|
472675
472857
|
var joined;
|
|
@@ -522783,9 +522965,9 @@ var init_reflectionBuffer = __esm({
|
|
|
522783
522965
|
this.persistPath = persistPath ?? null;
|
|
522784
522966
|
if (this.persistPath) {
|
|
522785
522967
|
try {
|
|
522786
|
-
const { readFileSync:
|
|
522787
|
-
if (
|
|
522788
|
-
this.state = JSON.parse(
|
|
522968
|
+
const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
|
|
522969
|
+
if (existsSync110(this.persistPath)) {
|
|
522970
|
+
this.state = JSON.parse(readFileSync89(this.persistPath, "utf-8"));
|
|
522789
522971
|
return;
|
|
522790
522972
|
}
|
|
522791
522973
|
} catch {
|
|
@@ -523018,10 +523200,10 @@ var init_reflectionBuffer = __esm({
|
|
|
523018
523200
|
if (!this.persistPath)
|
|
523019
523201
|
return;
|
|
523020
523202
|
try {
|
|
523021
|
-
const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67, existsSync:
|
|
523022
|
-
const { join:
|
|
523023
|
-
const dir =
|
|
523024
|
-
if (!
|
|
523203
|
+
const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67, existsSync: existsSync110 } = __require("node:fs");
|
|
523204
|
+
const { join: join128 } = __require("node:path");
|
|
523205
|
+
const dir = join128(this.persistPath, "..");
|
|
523206
|
+
if (!existsSync110(dir))
|
|
523025
523207
|
mkdirSync67(dir, { recursive: true });
|
|
523026
523208
|
writeFileSync59(this.persistPath, JSON.stringify(this.state, null, 2));
|
|
523027
523209
|
} catch {
|
|
@@ -533564,8 +533746,8 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533564
533746
|
this.emit({ type: "status", content: `Knowledge graph: ${nodes} nodes, ${edges} active edges`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
533565
533747
|
try {
|
|
533566
533748
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
|
|
533567
|
-
const { join:
|
|
533568
|
-
const contextDir =
|
|
533749
|
+
const { join: join128 } = __require("node:path");
|
|
533750
|
+
const contextDir = join128(this._workingDirectory || process.cwd(), ".oa", "context");
|
|
533569
533751
|
mkdirSync67(contextDir, { recursive: true });
|
|
533570
533752
|
const topEntities = this._temporalGraph.nodesByType("entity", 3);
|
|
533571
533753
|
const topFiles = this._temporalGraph.nodesByType("file", 3);
|
|
@@ -533606,9 +533788,9 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533606
533788
|
section("Top Files", topFiles);
|
|
533607
533789
|
section("Top Concepts", topConcepts);
|
|
533608
533790
|
lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
|
|
533609
|
-
const outPath =
|
|
533791
|
+
const outPath = join128(contextDir, `kg-summary-${this._sessionId}.md`);
|
|
533610
533792
|
writeFileSync59(outPath, lines.join("\n"), "utf-8");
|
|
533611
|
-
writeFileSync59(
|
|
533793
|
+
writeFileSync59(join128(contextDir, `kg-summary-latest.md`), lines.join("\n"), "utf-8");
|
|
533612
533794
|
} catch {
|
|
533613
533795
|
}
|
|
533614
533796
|
}
|
|
@@ -533777,10 +533959,10 @@ ${errOutput}`;
|
|
|
533777
533959
|
});
|
|
533778
533960
|
try {
|
|
533779
533961
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
|
|
533780
|
-
const { join:
|
|
533781
|
-
const resultsDir =
|
|
533962
|
+
const { join: join128 } = __require("node:path");
|
|
533963
|
+
const resultsDir = join128(process.cwd(), ".oa", "tool-results");
|
|
533782
533964
|
mkdirSync67(resultsDir, { recursive: true });
|
|
533783
|
-
writeFileSync59(
|
|
533965
|
+
writeFileSync59(join128(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
|
|
533784
533966
|
# Turn: ${turn}
|
|
533785
533967
|
# Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
533786
533968
|
# Size: ${result.output.length} chars, ${lineCount} lines
|
|
@@ -533997,8 +534179,8 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
533997
534179
|
return;
|
|
533998
534180
|
try {
|
|
533999
534181
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
|
|
534000
|
-
const { join:
|
|
534001
|
-
const sessionDir =
|
|
534182
|
+
const { join: join128 } = __require("node:path");
|
|
534183
|
+
const sessionDir = join128(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
534002
534184
|
mkdirSync67(sessionDir, { recursive: true });
|
|
534003
534185
|
const checkpoint = {
|
|
534004
534186
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -534011,7 +534193,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
534011
534193
|
memexEntryCount: this._memexArchive.size,
|
|
534012
534194
|
fileRegistrySize: this._fileRegistry.size
|
|
534013
534195
|
};
|
|
534014
|
-
writeFileSync59(
|
|
534196
|
+
writeFileSync59(join128(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
534015
534197
|
} catch {
|
|
534016
534198
|
}
|
|
534017
534199
|
}
|
|
@@ -534329,8 +534511,8 @@ System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
|
|
|
534329
534511
|
let recoveredTokens = 0;
|
|
534330
534512
|
for (const [filePath, entry] of entries) {
|
|
534331
534513
|
try {
|
|
534332
|
-
const { readFileSync:
|
|
534333
|
-
const content =
|
|
534514
|
+
const { readFileSync: readFileSync89 } = await import("node:fs");
|
|
534515
|
+
const content = readFileSync89(filePath, "utf8");
|
|
534334
534516
|
const tokenEst = Math.ceil(content.length / 4);
|
|
534335
534517
|
if (recoveredTokens + tokenEst > fileRecoveryBudget)
|
|
534336
534518
|
break;
|
|
@@ -535838,17 +536020,17 @@ ${result}`
|
|
|
535838
536020
|
let resizedBase64 = null;
|
|
535839
536021
|
try {
|
|
535840
536022
|
const { execSync: execSync59 } = await import("node:child_process");
|
|
535841
|
-
const { writeFileSync: writeFileSync59, readFileSync:
|
|
535842
|
-
const { join:
|
|
536023
|
+
const { writeFileSync: writeFileSync59, readFileSync: readFileSync89, unlinkSync: unlinkSync25 } = await import("node:fs");
|
|
536024
|
+
const { join: join128 } = await import("node:path");
|
|
535843
536025
|
const { tmpdir: tmpdir22 } = await import("node:os");
|
|
535844
|
-
const tmpIn =
|
|
535845
|
-
const tmpOut =
|
|
536026
|
+
const tmpIn = join128(tmpdir22(), `oa_img_in_${Date.now()}.png`);
|
|
536027
|
+
const tmpOut = join128(tmpdir22(), `oa_img_out_${Date.now()}.jpg`);
|
|
535846
536028
|
writeFileSync59(tmpIn, buffer2);
|
|
535847
536029
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
535848
536030
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
535849
536031
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
535850
536032
|
execSync59(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
535851
|
-
const resizedBuf =
|
|
536033
|
+
const resizedBuf = readFileSync89(tmpOut);
|
|
535852
536034
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
535853
536035
|
try {
|
|
535854
536036
|
unlinkSync25(tmpIn);
|
|
@@ -544388,25 +544570,25 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
544388
544570
|
async function fetchPeerModels(peerId, authKey) {
|
|
544389
544571
|
try {
|
|
544390
544572
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
544391
|
-
const { existsSync:
|
|
544392
|
-
const { join:
|
|
544573
|
+
const { existsSync: existsSync110, readFileSync: readFileSync89 } = await import("node:fs");
|
|
544574
|
+
const { join: join128 } = await import("node:path");
|
|
544393
544575
|
const cwd4 = process.cwd();
|
|
544394
544576
|
const nexusTool = new NexusTool2(cwd4);
|
|
544395
544577
|
const nexusDir = nexusTool.getNexusDir();
|
|
544396
544578
|
let isLocalPeer = false;
|
|
544397
544579
|
try {
|
|
544398
|
-
const statusPath =
|
|
544399
|
-
if (
|
|
544400
|
-
const status = JSON.parse(
|
|
544580
|
+
const statusPath = join128(nexusDir, "status.json");
|
|
544581
|
+
if (existsSync110(statusPath)) {
|
|
544582
|
+
const status = JSON.parse(readFileSync89(statusPath, "utf8"));
|
|
544401
544583
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
544402
544584
|
}
|
|
544403
544585
|
} catch {
|
|
544404
544586
|
}
|
|
544405
544587
|
if (isLocalPeer) {
|
|
544406
|
-
const pricingPath =
|
|
544407
|
-
if (
|
|
544588
|
+
const pricingPath = join128(nexusDir, "pricing.json");
|
|
544589
|
+
if (existsSync110(pricingPath)) {
|
|
544408
544590
|
try {
|
|
544409
|
-
const pricing = JSON.parse(
|
|
544591
|
+
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544410
544592
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
544411
544593
|
name: m2.model || "unknown",
|
|
544412
544594
|
size: m2.parameterSize || "",
|
|
@@ -544419,10 +544601,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544419
544601
|
}
|
|
544420
544602
|
}
|
|
544421
544603
|
}
|
|
544422
|
-
const cachePath =
|
|
544423
|
-
if (
|
|
544604
|
+
const cachePath = join128(nexusDir, "peer-models-cache.json");
|
|
544605
|
+
if (existsSync110(cachePath)) {
|
|
544424
544606
|
try {
|
|
544425
|
-
const cache8 = JSON.parse(
|
|
544607
|
+
const cache8 = JSON.parse(readFileSync89(cachePath, "utf8"));
|
|
544426
544608
|
if (cache8.peerId === peerId && cache8.models?.length > 0) {
|
|
544427
544609
|
const age = Date.now() - new Date(cache8.cachedAt).getTime();
|
|
544428
544610
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -544534,10 +544716,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544534
544716
|
} catch {
|
|
544535
544717
|
}
|
|
544536
544718
|
if (isLocalPeer) {
|
|
544537
|
-
const pricingPath =
|
|
544538
|
-
if (
|
|
544719
|
+
const pricingPath = join128(nexusDir, "pricing.json");
|
|
544720
|
+
if (existsSync110(pricingPath)) {
|
|
544539
544721
|
try {
|
|
544540
|
-
const pricing = JSON.parse(
|
|
544722
|
+
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544541
544723
|
return (pricing.models || []).map((m2) => ({
|
|
544542
544724
|
name: m2.model || "unknown",
|
|
544543
544725
|
size: m2.parameterSize || "",
|
|
@@ -562356,9 +562538,9 @@ async function ensureVoiceDeps(ctx3) {
|
|
|
562356
562538
|
}
|
|
562357
562539
|
if (typeof mod2.getVenvPython === "function") {
|
|
562358
562540
|
const { dirname: dirname39 } = await import("node:path");
|
|
562359
|
-
const { existsSync:
|
|
562541
|
+
const { existsSync: existsSync110 } = await import("node:fs");
|
|
562360
562542
|
const venvPy = mod2.getVenvPython();
|
|
562361
|
-
if (
|
|
562543
|
+
if (existsSync110(venvPy)) {
|
|
562362
562544
|
process.env.TRANSCRIBE_PYTHON = venvPy;
|
|
562363
562545
|
const venvBin = dirname39(venvPy);
|
|
562364
562546
|
const sep2 = process.platform === "win32" ? ";" : ":";
|
|
@@ -562676,11 +562858,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562676
562858
|
let key = process.env["OA_API_KEY"] || "";
|
|
562677
562859
|
if (!key) {
|
|
562678
562860
|
try {
|
|
562679
|
-
const { homedir:
|
|
562680
|
-
const { readFileSync:
|
|
562681
|
-
const { join:
|
|
562682
|
-
const p2 =
|
|
562683
|
-
if (
|
|
562861
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
562862
|
+
const { readFileSync: readFileSync89, existsSync: existsSync110 } = await import("node:fs");
|
|
562863
|
+
const { join: join128 } = await import("node:path");
|
|
562864
|
+
const p2 = join128(homedir46(), ".open-agents", "api.key");
|
|
562865
|
+
if (existsSync110(p2)) key = readFileSync89(p2, "utf8").trim();
|
|
562684
562866
|
} catch {
|
|
562685
562867
|
}
|
|
562686
562868
|
}
|
|
@@ -562718,14 +562900,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562718
562900
|
if (action === "new") {
|
|
562719
562901
|
try {
|
|
562720
562902
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
562721
|
-
const { homedir:
|
|
562903
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
562722
562904
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
|
|
562723
|
-
const { join:
|
|
562905
|
+
const { join: join128 } = await import("node:path");
|
|
562724
562906
|
const newKey = randomBytes25(16).toString("hex");
|
|
562725
562907
|
process.env["OA_API_KEY"] = newKey;
|
|
562726
|
-
const dir =
|
|
562908
|
+
const dir = join128(homedir46(), ".open-agents");
|
|
562727
562909
|
mkdirSync67(dir, { recursive: true });
|
|
562728
|
-
writeFileSync59(
|
|
562910
|
+
writeFileSync59(join128(dir, "api.key"), newKey + "\n", "utf8");
|
|
562729
562911
|
renderInfo2(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
562730
562912
|
renderInfo2("Restart the daemon to apply if needed. Use /access any to restart quickly.");
|
|
562731
562913
|
} catch (e2) {
|
|
@@ -562912,12 +563094,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562912
563094
|
renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
562913
563095
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
562914
563096
|
try {
|
|
562915
|
-
const { homedir:
|
|
563097
|
+
const { homedir: homedir47 } = await import("node:os");
|
|
562916
563098
|
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
562917
|
-
const { join:
|
|
562918
|
-
const dir =
|
|
563099
|
+
const { join: join129 } = await import("node:path");
|
|
563100
|
+
const dir = join129(homedir47(), ".open-agents");
|
|
562919
563101
|
mkdirSync68(dir, { recursive: true });
|
|
562920
|
-
writeFileSync60(
|
|
563102
|
+
writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
|
|
562921
563103
|
} catch {
|
|
562922
563104
|
}
|
|
562923
563105
|
}
|
|
@@ -562928,12 +563110,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562928
563110
|
}
|
|
562929
563111
|
const port2 = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
562930
563112
|
try {
|
|
562931
|
-
const { homedir:
|
|
563113
|
+
const { homedir: homedir47 } = await import("node:os");
|
|
562932
563114
|
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
562933
|
-
const { join:
|
|
562934
|
-
const dir =
|
|
563115
|
+
const { join: join129 } = await import("node:path");
|
|
563116
|
+
const dir = join129(homedir47(), ".open-agents");
|
|
562935
563117
|
mkdirSync68(dir, { recursive: true });
|
|
562936
|
-
writeFileSync60(
|
|
563118
|
+
writeFileSync60(join129(dir, "access"), `${val2}
|
|
562937
563119
|
`, "utf8");
|
|
562938
563120
|
} catch {
|
|
562939
563121
|
}
|
|
@@ -563014,12 +563196,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563014
563196
|
renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
563015
563197
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
563016
563198
|
try {
|
|
563017
|
-
const { homedir:
|
|
563199
|
+
const { homedir: homedir47 } = await import("node:os");
|
|
563018
563200
|
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
563019
|
-
const { join:
|
|
563020
|
-
const dir =
|
|
563201
|
+
const { join: join129 } = await import("node:path");
|
|
563202
|
+
const dir = join129(homedir47(), ".open-agents");
|
|
563021
563203
|
mkdirSync68(dir, { recursive: true });
|
|
563022
|
-
writeFileSync60(
|
|
563204
|
+
writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
|
|
563023
563205
|
} catch {
|
|
563024
563206
|
}
|
|
563025
563207
|
}
|
|
@@ -563029,13 +563211,13 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563029
563211
|
ctx3.saveSettings({ oaAccess: val });
|
|
563030
563212
|
}
|
|
563031
563213
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
563032
|
-
const { homedir:
|
|
563214
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
563033
563215
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
|
|
563034
|
-
const { join:
|
|
563216
|
+
const { join: join128 } = await import("node:path");
|
|
563035
563217
|
try {
|
|
563036
|
-
const dir =
|
|
563218
|
+
const dir = join128(homedir46(), ".open-agents");
|
|
563037
563219
|
mkdirSync67(dir, { recursive: true });
|
|
563038
|
-
writeFileSync59(
|
|
563220
|
+
writeFileSync59(join128(dir, "access"), `${val}
|
|
563039
563221
|
`, "utf8");
|
|
563040
563222
|
} catch (e2) {
|
|
563041
563223
|
renderWarning2(`Could not persist ~/.open-agents/access: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
@@ -563388,9 +563570,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563388
563570
|
renderInfo2("No wallet configured. Ask the agent to create one via the nexus tool.");
|
|
563389
563571
|
}
|
|
563390
563572
|
} else if (sub === "name") {
|
|
563391
|
-
const { homedir:
|
|
563573
|
+
const { homedir: homedir46 } = __require("node:os");
|
|
563392
563574
|
const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
|
|
563393
|
-
const namePath = __require("node:path").join(
|
|
563575
|
+
const namePath = __require("node:path").join(homedir46(), ".open-agents", "agent-name");
|
|
563394
563576
|
if (rest2) {
|
|
563395
563577
|
const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
|
|
563396
563578
|
if (!customName) {
|
|
@@ -565587,8 +565769,8 @@ sleep 1
|
|
|
565587
565769
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
565588
565770
|
if (!sponsorName || sponsorName.length < 2) {
|
|
565589
565771
|
try {
|
|
565590
|
-
const { homedir:
|
|
565591
|
-
const namePath = __require("path").join(
|
|
565772
|
+
const { homedir: homedir46 } = __require("os");
|
|
565773
|
+
const namePath = __require("path").join(homedir46(), ".open-agents", "agent-name");
|
|
565592
565774
|
if (existsSync83(namePath)) sponsorName = readFileSync66(namePath, "utf8").trim();
|
|
565593
565775
|
} catch {
|
|
565594
565776
|
}
|
|
@@ -567253,9 +567435,9 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
567253
567435
|
}
|
|
567254
567436
|
const { basename: basename21, join: pathJoin } = await import("node:path");
|
|
567255
567437
|
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync67, existsSync: exists2 } = await import("node:fs");
|
|
567256
|
-
const { homedir:
|
|
567438
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
567257
567439
|
const modelName = basename21(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
567258
|
-
const destDir = pathJoin(
|
|
567440
|
+
const destDir = pathJoin(homedir46(), ".open-agents", "voice", "models", modelName);
|
|
567259
567441
|
if (!exists2(destDir)) mkdirSync67(destDir, { recursive: true });
|
|
567260
567442
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
567261
567443
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
@@ -568183,8 +568365,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
568183
568365
|
if (models.length > 0) {
|
|
568184
568366
|
try {
|
|
568185
568367
|
const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67 } = await import("node:fs");
|
|
568186
|
-
const { join:
|
|
568187
|
-
const cachePath =
|
|
568368
|
+
const { join: join128, dirname: dirname39 } = await import("node:path");
|
|
568369
|
+
const cachePath = join128(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
568188
568370
|
mkdirSync67(dirname39(cachePath), { recursive: true });
|
|
568189
568371
|
writeFileSync59(cachePath, JSON.stringify({
|
|
568190
568372
|
peerId,
|
|
@@ -568755,17 +568937,17 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
568755
568937
|
try {
|
|
568756
568938
|
const { createRequire: createRequire8 } = await import("node:module");
|
|
568757
568939
|
const { fileURLToPath: fileURLToPath20 } = await import("node:url");
|
|
568758
|
-
const { dirname: dirname39, join:
|
|
568759
|
-
const { existsSync:
|
|
568940
|
+
const { dirname: dirname39, join: join128 } = await import("node:path");
|
|
568941
|
+
const { existsSync: existsSync110 } = await import("node:fs");
|
|
568760
568942
|
const req2 = createRequire8(import.meta.url);
|
|
568761
568943
|
const thisDir = dirname39(fileURLToPath20(import.meta.url));
|
|
568762
568944
|
const candidates = [
|
|
568763
|
-
|
|
568764
|
-
|
|
568765
|
-
|
|
568945
|
+
join128(thisDir, "..", "package.json"),
|
|
568946
|
+
join128(thisDir, "..", "..", "package.json"),
|
|
568947
|
+
join128(thisDir, "..", "..", "..", "package.json")
|
|
568766
568948
|
];
|
|
568767
568949
|
for (const pkgPath of candidates) {
|
|
568768
|
-
if (
|
|
568950
|
+
if (existsSync110(pkgPath)) {
|
|
568769
568951
|
const pkg = req2(pkgPath);
|
|
568770
568952
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
568771
568953
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -569912,14 +570094,14 @@ var init_commands = __esm({
|
|
|
569912
570094
|
if (val === "any" && !process.env["OA_API_KEY"]) {
|
|
569913
570095
|
try {
|
|
569914
570096
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
569915
|
-
const { homedir:
|
|
570097
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
569916
570098
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
|
|
569917
|
-
const { join:
|
|
570099
|
+
const { join: join128 } = await import("node:path");
|
|
569918
570100
|
const apiKey = randomBytes25(16).toString("hex");
|
|
569919
570101
|
process.env["OA_API_KEY"] = apiKey;
|
|
569920
|
-
const dir =
|
|
570102
|
+
const dir = join128(homedir46(), ".open-agents");
|
|
569921
570103
|
mkdirSync67(dir, { recursive: true });
|
|
569922
|
-
writeFileSync59(
|
|
570104
|
+
writeFileSync59(join128(dir, "api.key"), apiKey + "\n", "utf8");
|
|
569923
570105
|
renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
569924
570106
|
renderInfo2("Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it.");
|
|
569925
570107
|
} catch (e2) {
|
|
@@ -569933,12 +570115,12 @@ var init_commands = __esm({
|
|
|
569933
570115
|
}
|
|
569934
570116
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
569935
570117
|
try {
|
|
569936
|
-
const { homedir:
|
|
570118
|
+
const { homedir: homedir46 } = await import("node:os");
|
|
569937
570119
|
const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
|
|
569938
|
-
const { join:
|
|
569939
|
-
const dir =
|
|
570120
|
+
const { join: join128 } = await import("node:path");
|
|
570121
|
+
const dir = join128(homedir46(), ".open-agents");
|
|
569940
570122
|
mkdirSync67(dir, { recursive: true });
|
|
569941
|
-
writeFileSync59(
|
|
570123
|
+
writeFileSync59(join128(dir, "access"), `${val}
|
|
569942
570124
|
`, "utf8");
|
|
569943
570125
|
} catch {
|
|
569944
570126
|
}
|
|
@@ -585471,10 +585653,168 @@ var init_runtime_keys = __esm({
|
|
|
585471
585653
|
}
|
|
585472
585654
|
});
|
|
585473
585655
|
|
|
585474
|
-
// packages/cli/src/api/
|
|
585475
|
-
|
|
585476
|
-
|
|
585656
|
+
// packages/cli/src/api/tor-fallback.ts
|
|
585657
|
+
var tor_fallback_exports = {};
|
|
585658
|
+
__export(tor_fallback_exports, {
|
|
585659
|
+
getLocalOnion: () => getLocalOnion,
|
|
585660
|
+
torIsReachable: () => torIsReachable,
|
|
585661
|
+
tunnelViaTor: () => tunnelViaTor
|
|
585662
|
+
});
|
|
585663
|
+
import { existsSync as existsSync101, readFileSync as readFileSync82 } from "node:fs";
|
|
585477
585664
|
import { homedir as homedir39 } from "node:os";
|
|
585665
|
+
import { join as join117 } from "node:path";
|
|
585666
|
+
import { createConnection as createConnection3 } from "node:net";
|
|
585667
|
+
function getLocalOnion() {
|
|
585668
|
+
const candidates = [
|
|
585669
|
+
join117(homedir39(), "hidden_service_hostname"),
|
|
585670
|
+
join117(homedir39(), ".oa", "tor", "hostname"),
|
|
585671
|
+
"/var/lib/tor/hidden_service/hostname"
|
|
585672
|
+
];
|
|
585673
|
+
for (const p2 of candidates) {
|
|
585674
|
+
try {
|
|
585675
|
+
if (existsSync101(p2)) {
|
|
585676
|
+
const v = readFileSync82(p2, "utf-8").trim();
|
|
585677
|
+
if (v && v.endsWith(".onion")) return v;
|
|
585678
|
+
}
|
|
585679
|
+
} catch {
|
|
585680
|
+
}
|
|
585681
|
+
}
|
|
585682
|
+
return null;
|
|
585683
|
+
}
|
|
585684
|
+
async function torIsReachable() {
|
|
585685
|
+
return new Promise((resolve43) => {
|
|
585686
|
+
const sock = createConnection3({ host: DEFAULT_SOCKS_HOST, port: DEFAULT_SOCKS_PORT });
|
|
585687
|
+
let done = false;
|
|
585688
|
+
const finish = (ok2) => {
|
|
585689
|
+
if (done) return;
|
|
585690
|
+
done = true;
|
|
585691
|
+
try {
|
|
585692
|
+
sock.destroy();
|
|
585693
|
+
} catch {
|
|
585694
|
+
}
|
|
585695
|
+
resolve43(ok2);
|
|
585696
|
+
};
|
|
585697
|
+
sock.once("connect", () => finish(true));
|
|
585698
|
+
sock.once("error", () => finish(false));
|
|
585699
|
+
setTimeout(() => finish(false), 500);
|
|
585700
|
+
});
|
|
585701
|
+
}
|
|
585702
|
+
async function tunnelViaTor(req2) {
|
|
585703
|
+
const headers = { ...req2.headers || {} };
|
|
585704
|
+
if (req2.shareKey) headers["authorization"] = `Bearer ${req2.shareKey}`;
|
|
585705
|
+
if (!headers["host"]) headers["host"] = req2.onion;
|
|
585706
|
+
if (req2.body && !headers["content-length"]) headers["content-length"] = String(Buffer.byteLength(req2.body, "utf-8"));
|
|
585707
|
+
if (!headers["connection"]) headers["connection"] = "close";
|
|
585708
|
+
const lines = [`${req2.method.toUpperCase()} ${req2.path} HTTP/1.1`];
|
|
585709
|
+
for (const [k, v] of Object.entries(headers)) lines.push(`${k}: ${v}`);
|
|
585710
|
+
lines.push("");
|
|
585711
|
+
lines.push("");
|
|
585712
|
+
const reqBuf = Buffer.from(lines.join("\r\n") + (req2.body ?? ""), "utf-8");
|
|
585713
|
+
const socksSock = await openSocks5(req2.onion, 80, req2.timeoutMs ?? 6e4);
|
|
585714
|
+
socksSock.write(reqBuf);
|
|
585715
|
+
const chunks = [];
|
|
585716
|
+
for await (const ch of socksSock) chunks.push(ch);
|
|
585717
|
+
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
585718
|
+
const headerEnd = raw.indexOf("\r\n\r\n");
|
|
585719
|
+
if (headerEnd < 0) throw new Error("Tor: malformed response (no header terminator)");
|
|
585720
|
+
const headBlock = raw.slice(0, headerEnd);
|
|
585721
|
+
const bodyText = raw.slice(headerEnd + 4);
|
|
585722
|
+
const headLines = headBlock.split("\r\n");
|
|
585723
|
+
const statusLine = headLines.shift() ?? "";
|
|
585724
|
+
const m2 = statusLine.match(/^HTTP\/[\d.]+ (\d+)/);
|
|
585725
|
+
const status = m2 ? parseInt(m2[1], 10) : 0;
|
|
585726
|
+
const respHeaders = {};
|
|
585727
|
+
for (const ln of headLines) {
|
|
585728
|
+
const idx = ln.indexOf(":");
|
|
585729
|
+
if (idx <= 0) continue;
|
|
585730
|
+
respHeaders[ln.slice(0, idx).toLowerCase()] = ln.slice(idx + 1).trim();
|
|
585731
|
+
}
|
|
585732
|
+
const ct = (respHeaders["content-type"] || "").toLowerCase();
|
|
585733
|
+
const streaming = ct.includes("text/event-stream") || ct.includes("application/x-ndjson");
|
|
585734
|
+
return { status, headers: respHeaders, body: bodyText, streaming };
|
|
585735
|
+
}
|
|
585736
|
+
function openSocks5(targetHost, targetPort, timeoutMs) {
|
|
585737
|
+
return new Promise((resolve43, reject) => {
|
|
585738
|
+
const sock = createConnection3({ host: DEFAULT_SOCKS_HOST, port: DEFAULT_SOCKS_PORT });
|
|
585739
|
+
let stage = "greet";
|
|
585740
|
+
const timer = setTimeout(() => {
|
|
585741
|
+
try {
|
|
585742
|
+
sock.destroy(new Error(`Tor SOCKS5 timeout (${timeoutMs}ms)`));
|
|
585743
|
+
} catch {
|
|
585744
|
+
}
|
|
585745
|
+
reject(new Error(`Tor SOCKS5 timeout (${timeoutMs}ms)`));
|
|
585746
|
+
}, timeoutMs);
|
|
585747
|
+
sock.on("error", (e2) => {
|
|
585748
|
+
clearTimeout(timer);
|
|
585749
|
+
reject(e2);
|
|
585750
|
+
});
|
|
585751
|
+
sock.on("connect", () => {
|
|
585752
|
+
sock.write(Buffer.from([5, 1, 0]));
|
|
585753
|
+
});
|
|
585754
|
+
sock.on("data", (chunk) => {
|
|
585755
|
+
if (stage === "greet") {
|
|
585756
|
+
if (chunk.length < 2 || chunk[0] !== 5 || chunk[1] !== 0) {
|
|
585757
|
+
clearTimeout(timer);
|
|
585758
|
+
reject(new Error("Tor SOCKS5: greeting rejected (auth required?)"));
|
|
585759
|
+
try {
|
|
585760
|
+
sock.destroy();
|
|
585761
|
+
} catch {
|
|
585762
|
+
}
|
|
585763
|
+
return;
|
|
585764
|
+
}
|
|
585765
|
+
const hostBuf = Buffer.from(targetHost, "ascii");
|
|
585766
|
+
const buf = Buffer.alloc(7 + hostBuf.length);
|
|
585767
|
+
buf[0] = 5;
|
|
585768
|
+
buf[1] = 1;
|
|
585769
|
+
buf[2] = 0;
|
|
585770
|
+
buf[3] = 3;
|
|
585771
|
+
buf[4] = hostBuf.length;
|
|
585772
|
+
hostBuf.copy(buf, 5);
|
|
585773
|
+
buf.writeUInt16BE(targetPort, 5 + hostBuf.length);
|
|
585774
|
+
sock.write(buf);
|
|
585775
|
+
stage = "connect";
|
|
585776
|
+
return;
|
|
585777
|
+
}
|
|
585778
|
+
if (stage === "connect") {
|
|
585779
|
+
if (chunk.length < 2 || chunk[0] !== 5) {
|
|
585780
|
+
clearTimeout(timer);
|
|
585781
|
+
reject(new Error("Tor SOCKS5: malformed CONNECT reply"));
|
|
585782
|
+
try {
|
|
585783
|
+
sock.destroy();
|
|
585784
|
+
} catch {
|
|
585785
|
+
}
|
|
585786
|
+
return;
|
|
585787
|
+
}
|
|
585788
|
+
if (chunk[1] !== 0) {
|
|
585789
|
+
const code8 = chunk[1];
|
|
585790
|
+
clearTimeout(timer);
|
|
585791
|
+
reject(new Error(`Tor SOCKS5: CONNECT failed (code ${code8})`));
|
|
585792
|
+
try {
|
|
585793
|
+
sock.destroy();
|
|
585794
|
+
} catch {
|
|
585795
|
+
}
|
|
585796
|
+
return;
|
|
585797
|
+
}
|
|
585798
|
+
clearTimeout(timer);
|
|
585799
|
+
stage = "ready";
|
|
585800
|
+
resolve43(sock);
|
|
585801
|
+
}
|
|
585802
|
+
});
|
|
585803
|
+
});
|
|
585804
|
+
}
|
|
585805
|
+
var DEFAULT_SOCKS_PORT, DEFAULT_SOCKS_HOST;
|
|
585806
|
+
var init_tor_fallback = __esm({
|
|
585807
|
+
"packages/cli/src/api/tor-fallback.ts"() {
|
|
585808
|
+
"use strict";
|
|
585809
|
+
DEFAULT_SOCKS_PORT = parseInt(process.env["OA_TOR_SOCKS_PORT"] || "9050", 10);
|
|
585810
|
+
DEFAULT_SOCKS_HOST = process.env["OA_TOR_SOCKS_HOST"] || "127.0.0.1";
|
|
585811
|
+
}
|
|
585812
|
+
});
|
|
585813
|
+
|
|
585814
|
+
// packages/cli/src/api/routes-v1.ts
|
|
585815
|
+
import { existsSync as existsSync102, readFileSync as readFileSync83, readdirSync as readdirSync34, statSync as statSync34 } from "node:fs";
|
|
585816
|
+
import { join as join118, resolve as pathResolve2 } from "node:path";
|
|
585817
|
+
import { homedir as homedir40 } from "node:os";
|
|
585478
585818
|
async function tryRouteV1(ctx3) {
|
|
585479
585819
|
const { pathname, method } = ctx3;
|
|
585480
585820
|
if (pathname === "/v1/skills" && method === "GET") {
|
|
@@ -585557,6 +585897,7 @@ async function tryRouteV1(ctx3) {
|
|
|
585557
585897
|
if (m2 && method === "DELETE") return handleRevokeKey(ctx3, decodeURIComponent(m2[1]));
|
|
585558
585898
|
}
|
|
585559
585899
|
if (pathname === "/v1/share/generate" && method === "POST") return handleGenerateShare(ctx3);
|
|
585900
|
+
if (pathname === "/v1/remote-proxy" && method === "POST") return handleRemoteProxy(ctx3);
|
|
585560
585901
|
if (pathname === "/v1/tools" && method === "GET") {
|
|
585561
585902
|
return handleListTools(ctx3);
|
|
585562
585903
|
}
|
|
@@ -585703,11 +586044,11 @@ async function handleGetSkill(ctx3, name10) {
|
|
|
585703
586044
|
async function fallbackDiscoverSkills() {
|
|
585704
586045
|
return (_root) => {
|
|
585705
586046
|
const roots = [
|
|
585706
|
-
|
|
586047
|
+
join118(homedir40(), ".local", "share", "ai-writing-guide")
|
|
585707
586048
|
];
|
|
585708
586049
|
const out = [];
|
|
585709
586050
|
for (const root of roots) {
|
|
585710
|
-
if (!
|
|
586051
|
+
if (!existsSync102(root)) continue;
|
|
585711
586052
|
walkForSkills(root, out, 0);
|
|
585712
586053
|
}
|
|
585713
586054
|
return out;
|
|
@@ -585718,12 +586059,12 @@ function walkForSkills(dir, out, depth) {
|
|
|
585718
586059
|
try {
|
|
585719
586060
|
for (const e2 of readdirSync34(dir, { withFileTypes: true })) {
|
|
585720
586061
|
if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
|
|
585721
|
-
const p2 =
|
|
586062
|
+
const p2 = join118(dir, e2.name);
|
|
585722
586063
|
if (e2.isDirectory()) {
|
|
585723
586064
|
walkForSkills(p2, out, depth + 1);
|
|
585724
586065
|
} else if (e2.isFile() && e2.name === "SKILL.md") {
|
|
585725
586066
|
try {
|
|
585726
|
-
const content =
|
|
586067
|
+
const content = readFileSync83(p2, "utf-8").slice(0, 2e3);
|
|
585727
586068
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
585728
586069
|
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
585729
586070
|
out.push({
|
|
@@ -585907,7 +586248,7 @@ async function getMemoryStores() {
|
|
|
585907
586248
|
if (memoryInitTried) return null;
|
|
585908
586249
|
memoryInitTried = true;
|
|
585909
586250
|
try {
|
|
585910
|
-
const dbPath =
|
|
586251
|
+
const dbPath = join118(homedir40(), ".open-agents", "memory.db");
|
|
585911
586252
|
const sharedDb = initDb(dbPath);
|
|
585912
586253
|
memoryStoresCache = {
|
|
585913
586254
|
episode: new EpisodeStore(dbPath),
|
|
@@ -586165,7 +586506,7 @@ async function handleFilesRead(ctx3) {
|
|
|
586165
586506
|
}));
|
|
586166
586507
|
return true;
|
|
586167
586508
|
}
|
|
586168
|
-
if (!
|
|
586509
|
+
if (!existsSync102(resolved)) {
|
|
586169
586510
|
sendProblem(res, problemDetails({
|
|
586170
586511
|
type: P.notFound,
|
|
586171
586512
|
status: 404,
|
|
@@ -586197,7 +586538,7 @@ async function handleFilesRead(ctx3) {
|
|
|
586197
586538
|
}));
|
|
586198
586539
|
return true;
|
|
586199
586540
|
}
|
|
586200
|
-
const content =
|
|
586541
|
+
const content = readFileSync83(resolved, "utf-8");
|
|
586201
586542
|
const offset = typeof body.offset === "number" && body.offset >= 0 ? body.offset : 0;
|
|
586202
586543
|
const limit = typeof body.limit === "number" && body.limit > 0 ? body.limit : content.length;
|
|
586203
586544
|
const slice2 = content.slice(offset, offset + limit);
|
|
@@ -586430,14 +586771,14 @@ async function handleNexusStatus(ctx3) {
|
|
|
586430
586771
|
const { res, requestId } = ctx3;
|
|
586431
586772
|
try {
|
|
586432
586773
|
const statePaths = [
|
|
586433
|
-
|
|
586434
|
-
|
|
586774
|
+
join118(process.cwd(), ".oa", "nexus-peer-state.json"),
|
|
586775
|
+
join118(homedir40(), ".open-agents", "nexus-peer-cache.json")
|
|
586435
586776
|
];
|
|
586436
586777
|
const states = [];
|
|
586437
586778
|
for (const p2 of statePaths) {
|
|
586438
|
-
if (!
|
|
586779
|
+
if (!existsSync102(p2)) continue;
|
|
586439
586780
|
try {
|
|
586440
|
-
const raw =
|
|
586781
|
+
const raw = readFileSync83(p2, "utf-8");
|
|
586441
586782
|
states.push({ source: p2, data: JSON.parse(raw) });
|
|
586442
586783
|
} catch (e2) {
|
|
586443
586784
|
states.push({ source: p2, error: String(e2) });
|
|
@@ -586464,8 +586805,8 @@ async function handleNexusStatus(ctx3) {
|
|
|
586464
586805
|
}
|
|
586465
586806
|
function loadAgentName() {
|
|
586466
586807
|
try {
|
|
586467
|
-
const p2 =
|
|
586468
|
-
if (
|
|
586808
|
+
const p2 = join118(homedir40(), ".open-agents", "agent-name");
|
|
586809
|
+
if (existsSync102(p2)) return readFileSync83(p2, "utf-8").trim();
|
|
586469
586810
|
} catch {
|
|
586470
586811
|
}
|
|
586471
586812
|
return null;
|
|
@@ -586474,14 +586815,14 @@ async function handleSponsors(ctx3) {
|
|
|
586474
586815
|
const { req: req2, res, url, requestId } = ctx3;
|
|
586475
586816
|
try {
|
|
586476
586817
|
const candidates = [
|
|
586477
|
-
|
|
586478
|
-
|
|
586818
|
+
join118(homedir40(), ".open-agents", "sponsor-cache.json"),
|
|
586819
|
+
join118(homedir40(), ".open-agents", "sponsors.json")
|
|
586479
586820
|
];
|
|
586480
586821
|
let sponsors = [];
|
|
586481
586822
|
for (const p2 of candidates) {
|
|
586482
|
-
if (!
|
|
586823
|
+
if (!existsSync102(p2)) continue;
|
|
586483
586824
|
try {
|
|
586484
|
-
const raw = JSON.parse(
|
|
586825
|
+
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
586485
586826
|
if (Array.isArray(raw)) {
|
|
586486
586827
|
sponsors = raw;
|
|
586487
586828
|
break;
|
|
@@ -586550,8 +586891,8 @@ async function handleEvaluate(ctx3) {
|
|
|
586550
586891
|
}));
|
|
586551
586892
|
return true;
|
|
586552
586893
|
}
|
|
586553
|
-
const jobPath =
|
|
586554
|
-
if (!
|
|
586894
|
+
const jobPath = join118(process.cwd(), ".oa", "jobs", `${runId}.json`);
|
|
586895
|
+
if (!existsSync102(jobPath)) {
|
|
586555
586896
|
sendProblem(res, problemDetails({
|
|
586556
586897
|
type: P.notFound,
|
|
586557
586898
|
status: 404,
|
|
@@ -586561,7 +586902,7 @@ async function handleEvaluate(ctx3) {
|
|
|
586561
586902
|
}));
|
|
586562
586903
|
return true;
|
|
586563
586904
|
}
|
|
586564
|
-
const job = JSON.parse(
|
|
586905
|
+
const job = JSON.parse(readFileSync83(jobPath, "utf-8"));
|
|
586565
586906
|
sendJson(res, 200, {
|
|
586566
586907
|
run_id: runId,
|
|
586567
586908
|
task: job.task,
|
|
@@ -586698,6 +587039,74 @@ async function handleMintKey(ctx3) {
|
|
|
586698
587039
|
}
|
|
586699
587040
|
return true;
|
|
586700
587041
|
}
|
|
587042
|
+
function _readStatusFile(p2) {
|
|
587043
|
+
if (!existsSync102(p2)) return null;
|
|
587044
|
+
try {
|
|
587045
|
+
const data = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587046
|
+
if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
|
|
587047
|
+
return {
|
|
587048
|
+
peerId: data.peerId,
|
|
587049
|
+
agentName: typeof data.agentName === "string" ? data.agentName : null,
|
|
587050
|
+
source: p2
|
|
587051
|
+
};
|
|
587052
|
+
}
|
|
587053
|
+
} catch {
|
|
587054
|
+
}
|
|
587055
|
+
return null;
|
|
587056
|
+
}
|
|
587057
|
+
function resolveLocalPeerId() {
|
|
587058
|
+
const override = process.env["OA_NEXUS_DIR"];
|
|
587059
|
+
if (override) {
|
|
587060
|
+
const r2 = _readStatusFile(join118(override, "status.json"));
|
|
587061
|
+
if (r2) return r2;
|
|
587062
|
+
}
|
|
587063
|
+
try {
|
|
587064
|
+
const regPath = join118(homedir40(), ".open-agents", "nexus-registry.json");
|
|
587065
|
+
if (existsSync102(regPath)) {
|
|
587066
|
+
const reg = JSON.parse(readFileSync83(regPath, "utf-8"));
|
|
587067
|
+
const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
|
|
587068
|
+
for (const entry of entries) {
|
|
587069
|
+
const dir = typeof entry === "string" ? entry : entry?.dir;
|
|
587070
|
+
if (typeof dir === "string") {
|
|
587071
|
+
const r2 = _readStatusFile(join118(dir, "status.json"));
|
|
587072
|
+
if (r2) return r2;
|
|
587073
|
+
}
|
|
587074
|
+
}
|
|
587075
|
+
}
|
|
587076
|
+
} catch {
|
|
587077
|
+
}
|
|
587078
|
+
const candidates = [
|
|
587079
|
+
join118(process.cwd(), ".oa", "nexus", "status.json"),
|
|
587080
|
+
join118(homedir40(), ".oa", "nexus", "status.json"),
|
|
587081
|
+
join118(homedir40(), ".open-agents", "nexus", "status.json")
|
|
587082
|
+
];
|
|
587083
|
+
for (const p2 of candidates) {
|
|
587084
|
+
const r2 = _readStatusFile(p2);
|
|
587085
|
+
if (r2) return r2;
|
|
587086
|
+
}
|
|
587087
|
+
const now = Date.now();
|
|
587088
|
+
if (_peerIdScanCache && now - _peerIdScanCache.ts < 6e4) {
|
|
587089
|
+
return _peerIdScanCache.result;
|
|
587090
|
+
}
|
|
587091
|
+
let scanResult = null;
|
|
587092
|
+
try {
|
|
587093
|
+
const { execSync: execSync59 } = __require("node:child_process");
|
|
587094
|
+
const cmd = `find "${homedir40()}" -maxdepth 4 -path '*/.oa/nexus/status.json' -type f 2>/dev/null | head -50`;
|
|
587095
|
+
const out = execSync59(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
587096
|
+
for (const line of out.split("\n")) {
|
|
587097
|
+
const f2 = line.trim();
|
|
587098
|
+
if (!f2) continue;
|
|
587099
|
+
const r2 = _readStatusFile(f2);
|
|
587100
|
+
if (r2) {
|
|
587101
|
+
scanResult = r2;
|
|
587102
|
+
break;
|
|
587103
|
+
}
|
|
587104
|
+
}
|
|
587105
|
+
} catch {
|
|
587106
|
+
}
|
|
587107
|
+
_peerIdScanCache = { ts: now, result: scanResult };
|
|
587108
|
+
return scanResult;
|
|
587109
|
+
}
|
|
586701
587110
|
async function handleGenerateShare(ctx3) {
|
|
586702
587111
|
const { req: req2, res, requestId } = ctx3;
|
|
586703
587112
|
const reqAuth = req2;
|
|
@@ -586742,19 +587151,48 @@ async function handleGenerateShare(ctx3) {
|
|
|
586742
587151
|
}));
|
|
586743
587152
|
return true;
|
|
586744
587153
|
}
|
|
587154
|
+
const directOnly = body["direct"] === true;
|
|
587155
|
+
const peerInfo = directOnly ? null : resolveLocalPeerId();
|
|
586745
587156
|
const scheme = String(req2.headers["x-forwarded-proto"] || (req2.socket?.encrypted ? "https" : "http"));
|
|
586746
|
-
const
|
|
586747
|
-
const
|
|
587157
|
+
const { getLocalOnion: getLocalOnion2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587158
|
+
const onion = getLocalOnion2();
|
|
587159
|
+
let shareUrl;
|
|
587160
|
+
let mode;
|
|
587161
|
+
if (peerInfo && hostHeader) {
|
|
587162
|
+
shareUrl = `oa-share://${peerInfo.peerId}@${hostPort}#${fullKey}`;
|
|
587163
|
+
mode = "libp2p+lan";
|
|
587164
|
+
} else if (peerInfo) {
|
|
587165
|
+
shareUrl = `oa-share://${peerInfo.peerId}#${fullKey}`;
|
|
587166
|
+
mode = "libp2p";
|
|
587167
|
+
} else {
|
|
587168
|
+
shareUrl = `oa-share://${hostPort}#${fullKey}`;
|
|
587169
|
+
mode = "direct";
|
|
587170
|
+
}
|
|
587171
|
+
const plainParams = [];
|
|
587172
|
+
if (peerInfo) plainParams.push(`oa-share-peer=${encodeURIComponent(peerInfo.peerId)}`);
|
|
587173
|
+
plainParams.push(`oa-key=${encodeURIComponent(fullKey)}`);
|
|
587174
|
+
if (onion) plainParams.push(`oa-onion=${encodeURIComponent(onion)}`);
|
|
587175
|
+
plainParams.push(`oa-share-label=${encodeURIComponent(label)}`);
|
|
587176
|
+
const plainUrl = `${scheme}://${hostPort}/?${plainParams.join("&")}`;
|
|
586748
587177
|
sendJson(res, 201, {
|
|
586749
587178
|
shareUrl,
|
|
586750
587179
|
plainUrl,
|
|
587180
|
+
mode,
|
|
587181
|
+
peerId: peerInfo?.peerId || null,
|
|
587182
|
+
onion: onion || null,
|
|
587183
|
+
agentName: peerInfo?.agentName || null,
|
|
586751
587184
|
host,
|
|
586752
587185
|
port,
|
|
586753
587186
|
key: fullKey,
|
|
586754
587187
|
keyPrefix: keyPrefix2,
|
|
586755
587188
|
label,
|
|
586756
587189
|
issuedAt: rec.created || (/* @__PURE__ */ new Date()).toISOString(),
|
|
586757
|
-
|
|
587190
|
+
reach: {
|
|
587191
|
+
libp2p: !!peerInfo,
|
|
587192
|
+
tor: !!onion,
|
|
587193
|
+
direct: !peerInfo
|
|
587194
|
+
},
|
|
587195
|
+
_note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor: see scripts/tor/tor_setup.sh." : "Nexus daemon offline — URL is direct-HTTP only (LAN/VPN reach). Start nexus for global reach."
|
|
586758
587196
|
});
|
|
586759
587197
|
} catch (err) {
|
|
586760
587198
|
sendProblem(res, problemDetails({
|
|
@@ -586767,6 +587205,242 @@ async function handleGenerateShare(ctx3) {
|
|
|
586767
587205
|
}
|
|
586768
587206
|
return true;
|
|
586769
587207
|
}
|
|
587208
|
+
async function handleRemoteProxy(ctx3) {
|
|
587209
|
+
const { req: req2, res, requestId } = ctx3;
|
|
587210
|
+
const reqAuth = req2;
|
|
587211
|
+
if (reqAuth._authScope !== "admin" && reqAuth._authScope !== "run") {
|
|
587212
|
+
sendProblem(res, problemDetails({
|
|
587213
|
+
type: P.forbidden,
|
|
587214
|
+
status: 403,
|
|
587215
|
+
title: "Auth required",
|
|
587216
|
+
detail: "Remote proxy requires 'run' or 'admin' scope on the LOCAL daemon.",
|
|
587217
|
+
instance: requestId
|
|
587218
|
+
}));
|
|
587219
|
+
return true;
|
|
587220
|
+
}
|
|
587221
|
+
let body;
|
|
587222
|
+
try {
|
|
587223
|
+
body = await parseJsonBodyStrict(req2);
|
|
587224
|
+
} catch {
|
|
587225
|
+
sendProblem(res, problemDetails({
|
|
587226
|
+
type: P.invalidRequest,
|
|
587227
|
+
status: 400,
|
|
587228
|
+
title: "Invalid JSON body",
|
|
587229
|
+
detail: "Body must be JSON object with peerId, key, method, path.",
|
|
587230
|
+
instance: requestId
|
|
587231
|
+
}));
|
|
587232
|
+
return true;
|
|
587233
|
+
}
|
|
587234
|
+
const peerId = String(body?.peerId || "").trim();
|
|
587235
|
+
const onionHint = typeof body?.onion === "string" && body.onion.endsWith(".onion") ? body.onion : null;
|
|
587236
|
+
const shareKey = String(body?.key || "").trim();
|
|
587237
|
+
const method = String(body?.method || "GET").toUpperCase();
|
|
587238
|
+
const path8 = String(body?.path || "/").trim();
|
|
587239
|
+
const headers = body?.headers && typeof body.headers === "object" ? body.headers : {};
|
|
587240
|
+
const useStream = body?.stream === true;
|
|
587241
|
+
const timeoutMs = typeof body?.timeoutMs === "number" ? body.timeoutMs : 6e4;
|
|
587242
|
+
if (!peerId && !onionHint || !shareKey) {
|
|
587243
|
+
sendProblem(res, problemDetails({
|
|
587244
|
+
type: P.invalidRequest,
|
|
587245
|
+
status: 400,
|
|
587246
|
+
title: "key + (peerId or onion) required",
|
|
587247
|
+
detail: "Provide a share key and at least one of peerId (libp2p) or onion (Tor).",
|
|
587248
|
+
instance: requestId
|
|
587249
|
+
}));
|
|
587250
|
+
return true;
|
|
587251
|
+
}
|
|
587252
|
+
const nexusCandidates = [
|
|
587253
|
+
join118(process.cwd(), ".oa", "nexus"),
|
|
587254
|
+
join118(homedir40(), ".oa", "nexus"),
|
|
587255
|
+
join118(homedir40(), ".open-agents", "nexus")
|
|
587256
|
+
];
|
|
587257
|
+
let nexusDirPath = null;
|
|
587258
|
+
for (const p2 of nexusCandidates) {
|
|
587259
|
+
if (existsSync102(join118(p2, "status.json"))) {
|
|
587260
|
+
nexusDirPath = p2;
|
|
587261
|
+
break;
|
|
587262
|
+
}
|
|
587263
|
+
}
|
|
587264
|
+
let tool = null;
|
|
587265
|
+
if (peerId && nexusDirPath) {
|
|
587266
|
+
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
587267
|
+
const nexusToolRepoRoot = nexusDirPath.replace(/[\\/]\.oa[\\/]nexus$/, "");
|
|
587268
|
+
tool = new NexusTool2(nexusToolRepoRoot);
|
|
587269
|
+
}
|
|
587270
|
+
const tunnelInput = {
|
|
587271
|
+
method,
|
|
587272
|
+
path: path8,
|
|
587273
|
+
headers,
|
|
587274
|
+
body: body?.body,
|
|
587275
|
+
key: shareKey
|
|
587276
|
+
};
|
|
587277
|
+
function torEnvelope(t2) {
|
|
587278
|
+
return {
|
|
587279
|
+
event: "http.head",
|
|
587280
|
+
data: JSON.stringify({ status: t2.status, headers: t2.headers, streaming: t2.streaming }),
|
|
587281
|
+
// The browser fetch interceptor reads either `event: http.head + data` (with embedded
|
|
587282
|
+
// status/headers) or falls back to `raw`. We pass both.
|
|
587283
|
+
raw: t2.body,
|
|
587284
|
+
transport: "tor"
|
|
587285
|
+
};
|
|
587286
|
+
}
|
|
587287
|
+
if (!useStream) {
|
|
587288
|
+
let libp2pErr = null;
|
|
587289
|
+
if (tool) {
|
|
587290
|
+
try {
|
|
587291
|
+
const raw = await tool.sendCommand("invoke_capability", {
|
|
587292
|
+
target_peer: peerId,
|
|
587293
|
+
capability: "http_tunnel",
|
|
587294
|
+
input: JSON.stringify(tunnelInput)
|
|
587295
|
+
}, timeoutMs);
|
|
587296
|
+
let parsed = null;
|
|
587297
|
+
try {
|
|
587298
|
+
parsed = JSON.parse(raw);
|
|
587299
|
+
} catch {
|
|
587300
|
+
parsed = { raw };
|
|
587301
|
+
}
|
|
587302
|
+
if (parsed && typeof parsed === "object") parsed.transport = "libp2p";
|
|
587303
|
+
sendJson(res, 200, parsed);
|
|
587304
|
+
return true;
|
|
587305
|
+
} catch (e2) {
|
|
587306
|
+
libp2pErr = e2;
|
|
587307
|
+
}
|
|
587308
|
+
}
|
|
587309
|
+
if (onionHint) {
|
|
587310
|
+
try {
|
|
587311
|
+
const { tunnelViaTor: tunnelViaTor2, torIsReachable: torIsReachable2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587312
|
+
if (await torIsReachable2()) {
|
|
587313
|
+
const t2 = await tunnelViaTor2({
|
|
587314
|
+
onion: onionHint,
|
|
587315
|
+
method,
|
|
587316
|
+
path: path8,
|
|
587317
|
+
headers,
|
|
587318
|
+
body: typeof body?.body === "string" ? body.body : body?.body !== void 0 ? JSON.stringify(body.body) : void 0,
|
|
587319
|
+
shareKey,
|
|
587320
|
+
timeoutMs
|
|
587321
|
+
});
|
|
587322
|
+
sendJson(res, 200, torEnvelope(t2));
|
|
587323
|
+
return true;
|
|
587324
|
+
}
|
|
587325
|
+
} catch (torErr) {
|
|
587326
|
+
sendProblem(res, problemDetails({
|
|
587327
|
+
type: P.internalError,
|
|
587328
|
+
status: 502,
|
|
587329
|
+
title: "Both libp2p and Tor transports failed",
|
|
587330
|
+
detail: `libp2p: ${libp2pErr instanceof Error ? libp2pErr.message : String(libp2pErr || "n/a")}; tor: ${torErr instanceof Error ? torErr.message : String(torErr)}`,
|
|
587331
|
+
instance: requestId
|
|
587332
|
+
}));
|
|
587333
|
+
return true;
|
|
587334
|
+
}
|
|
587335
|
+
}
|
|
587336
|
+
sendProblem(res, problemDetails({
|
|
587337
|
+
type: P.internalError,
|
|
587338
|
+
status: 502,
|
|
587339
|
+
title: "No transport reached the remote",
|
|
587340
|
+
detail: tool ? `libp2p invoke failed: ${libp2pErr instanceof Error ? libp2pErr.message : String(libp2pErr)}${onionHint ? "; Tor SOCKS5 not reachable on 127.0.0.1:9050" : "; no .onion fallback available"}` : "Local nexus daemon is offline and no .onion fallback was provided. Start nexus with `oa connect` or include onion in the request.",
|
|
587341
|
+
instance: requestId
|
|
587342
|
+
}));
|
|
587343
|
+
return true;
|
|
587344
|
+
}
|
|
587345
|
+
if (!tool) {
|
|
587346
|
+
sendProblem(res, problemDetails({
|
|
587347
|
+
type: P.internalError,
|
|
587348
|
+
status: 503,
|
|
587349
|
+
title: "Streaming requires libp2p (nexus not running)",
|
|
587350
|
+
detail: "SSE/streaming proxy requires the local nexus daemon. Start it with `oa connect`, or use a non-streaming endpoint with the Tor fallback.",
|
|
587351
|
+
instance: requestId
|
|
587352
|
+
}));
|
|
587353
|
+
return true;
|
|
587354
|
+
}
|
|
587355
|
+
const streamFile = join118(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
|
|
587356
|
+
try {
|
|
587357
|
+
const { writeFileSync: _wfs } = await import("node:fs");
|
|
587358
|
+
_wfs(streamFile, "");
|
|
587359
|
+
} catch {
|
|
587360
|
+
}
|
|
587361
|
+
res.statusCode = 200;
|
|
587362
|
+
res.setHeader("content-type", "text/event-stream");
|
|
587363
|
+
res.setHeader("cache-control", "no-cache");
|
|
587364
|
+
res.setHeader("x-accel-buffering", "no");
|
|
587365
|
+
res.flushHeaders?.();
|
|
587366
|
+
let stopped = false;
|
|
587367
|
+
const stop2 = () => {
|
|
587368
|
+
stopped = true;
|
|
587369
|
+
};
|
|
587370
|
+
req2.on("close", stop2);
|
|
587371
|
+
req2.on("aborted", stop2);
|
|
587372
|
+
const invokeP = tool.sendCommand("invoke_capability", {
|
|
587373
|
+
target_peer: peerId,
|
|
587374
|
+
capability: "http_tunnel",
|
|
587375
|
+
input: JSON.stringify(tunnelInput),
|
|
587376
|
+
stream_file: streamFile
|
|
587377
|
+
}, timeoutMs).catch((err) => {
|
|
587378
|
+
if (!stopped) {
|
|
587379
|
+
try {
|
|
587380
|
+
res.write(`event: error
|
|
587381
|
+
data: ${JSON.stringify({ error: err instanceof Error ? err.message : String(err) })}
|
|
587382
|
+
|
|
587383
|
+
`);
|
|
587384
|
+
} catch {
|
|
587385
|
+
}
|
|
587386
|
+
}
|
|
587387
|
+
});
|
|
587388
|
+
const { readFileSync: _rfs, existsSync: _exists } = await import("node:fs");
|
|
587389
|
+
let lastSize = 0;
|
|
587390
|
+
let leftover = "";
|
|
587391
|
+
while (!stopped) {
|
|
587392
|
+
try {
|
|
587393
|
+
if (_exists(streamFile)) {
|
|
587394
|
+
const stat5 = (await import("node:fs")).statSync(streamFile);
|
|
587395
|
+
if (stat5.size > lastSize) {
|
|
587396
|
+
const fd = (await import("node:fs")).openSync(streamFile, "r");
|
|
587397
|
+
const len = stat5.size - lastSize;
|
|
587398
|
+
const buf = Buffer.alloc(len);
|
|
587399
|
+
(await import("node:fs")).readSync(fd, buf, 0, len, lastSize);
|
|
587400
|
+
(await import("node:fs")).closeSync(fd);
|
|
587401
|
+
lastSize = stat5.size;
|
|
587402
|
+
const txt = leftover + buf.toString("utf-8");
|
|
587403
|
+
const parts = txt.split("\n");
|
|
587404
|
+
leftover = parts.pop() ?? "";
|
|
587405
|
+
for (const ln of parts) {
|
|
587406
|
+
if (!ln.trim()) continue;
|
|
587407
|
+
let parsed;
|
|
587408
|
+
try {
|
|
587409
|
+
parsed = JSON.parse(ln);
|
|
587410
|
+
} catch {
|
|
587411
|
+
continue;
|
|
587412
|
+
}
|
|
587413
|
+
const eventName = parsed.type === "event" ? parsed.event || "data" : parsed.type;
|
|
587414
|
+
res.write(`event: ${eventName}
|
|
587415
|
+
`);
|
|
587416
|
+
res.write(`data: ${JSON.stringify(parsed)}
|
|
587417
|
+
|
|
587418
|
+
`);
|
|
587419
|
+
if (parsed.type === "done" || parsed.type === "error") {
|
|
587420
|
+
stopped = true;
|
|
587421
|
+
break;
|
|
587422
|
+
}
|
|
587423
|
+
}
|
|
587424
|
+
}
|
|
587425
|
+
}
|
|
587426
|
+
} catch {
|
|
587427
|
+
}
|
|
587428
|
+
if (stopped) break;
|
|
587429
|
+
await new Promise((r2) => setTimeout(r2, 30));
|
|
587430
|
+
}
|
|
587431
|
+
await invokeP.catch(() => {
|
|
587432
|
+
});
|
|
587433
|
+
try {
|
|
587434
|
+
res.end();
|
|
587435
|
+
} catch {
|
|
587436
|
+
}
|
|
587437
|
+
try {
|
|
587438
|
+
const { unlinkSync: _unl } = await import("node:fs");
|
|
587439
|
+
_unl(streamFile);
|
|
587440
|
+
} catch {
|
|
587441
|
+
}
|
|
587442
|
+
return true;
|
|
587443
|
+
}
|
|
586770
587444
|
async function handleRevokeKey(ctx3, prefix) {
|
|
586771
587445
|
const { req: req2, res, requestId } = ctx3;
|
|
586772
587446
|
const reqAuth = req2;
|
|
@@ -587118,17 +587792,17 @@ async function handleListAgentTypes(ctx3) {
|
|
|
587118
587792
|
}
|
|
587119
587793
|
async function handleListEngines(ctx3) {
|
|
587120
587794
|
const { res } = ctx3;
|
|
587121
|
-
const home =
|
|
587795
|
+
const home = homedir40();
|
|
587122
587796
|
sendJson(res, 200, {
|
|
587123
587797
|
engines: [
|
|
587124
|
-
{ name: "dream", state_file:
|
|
587125
|
-
{ name: "bless", state_file:
|
|
587126
|
-
{ name: "call", state_file:
|
|
587127
|
-
{ name: "listen", state_file:
|
|
587128
|
-
{ name: "telegram", state_file:
|
|
587129
|
-
{ name: "expose", state_file:
|
|
587130
|
-
{ name: "nexus", state_file:
|
|
587131
|
-
{ name: "ipfs", state_file:
|
|
587798
|
+
{ name: "dream", state_file: join118(process.cwd(), ".oa", "dreams"), controllable_via: "SSE + slash commands" },
|
|
587799
|
+
{ name: "bless", state_file: join118(process.cwd(), ".oa", "bless-state.json"), controllable_via: "slash commands" },
|
|
587800
|
+
{ name: "call", state_file: join118(process.cwd(), ".oa", "call-state.json"), controllable_via: "slash commands" },
|
|
587801
|
+
{ name: "listen", state_file: join118(process.cwd(), ".oa", "listen-state.json"), controllable_via: "slash commands" },
|
|
587802
|
+
{ name: "telegram", state_file: join118(home, ".open-agents", "telegram-state.json"), controllable_via: "slash commands" },
|
|
587803
|
+
{ name: "expose", state_file: join118(process.cwd(), ".oa", "expose-state.json"), controllable_via: "/expose commands" },
|
|
587804
|
+
{ name: "nexus", state_file: join118(home, ".open-agents", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
|
|
587805
|
+
{ name: "ipfs", state_file: join118(process.cwd(), ".oa", "ipfs"), controllable_via: "slash commands" }
|
|
587132
587806
|
],
|
|
587133
587807
|
note: "Engine instrumentation lives in the running TUI process. Full status + control requires the daemon↔TUI bridge (PT-07). See parity audit WO-PARITY-04."
|
|
587134
587808
|
});
|
|
@@ -587211,12 +587885,12 @@ async function tryAimsRoute(ctx3) {
|
|
|
587211
587885
|
return false;
|
|
587212
587886
|
}
|
|
587213
587887
|
function aimsDir() {
|
|
587214
|
-
return
|
|
587888
|
+
return join118(homedir40(), ".open-agents", "aims");
|
|
587215
587889
|
}
|
|
587216
587890
|
function readAimsFile(name10, fallback) {
|
|
587217
587891
|
try {
|
|
587218
|
-
const p2 =
|
|
587219
|
-
if (
|
|
587892
|
+
const p2 = join118(aimsDir(), name10);
|
|
587893
|
+
if (existsSync102(p2)) return JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587220
587894
|
} catch {
|
|
587221
587895
|
}
|
|
587222
587896
|
return fallback;
|
|
@@ -587225,7 +587899,7 @@ function writeAimsFile(name10, data) {
|
|
|
587225
587899
|
const dir = aimsDir();
|
|
587226
587900
|
const { mkdirSync: mkdirSync67, writeFileSync: wf, renameSync: rn } = __require("node:fs");
|
|
587227
587901
|
mkdirSync67(dir, { recursive: true });
|
|
587228
|
-
const finalPath =
|
|
587902
|
+
const finalPath = join118(dir, name10);
|
|
587229
587903
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
587230
587904
|
try {
|
|
587231
587905
|
wf(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
@@ -587555,12 +588229,12 @@ async function handleAimsSuppliers(ctx3) {
|
|
|
587555
588229
|
}
|
|
587556
588230
|
];
|
|
587557
588231
|
const sponsorPaths = [
|
|
587558
|
-
|
|
588232
|
+
join118(homedir40(), ".open-agents", "sponsor-cache.json")
|
|
587559
588233
|
];
|
|
587560
588234
|
for (const p2 of sponsorPaths) {
|
|
587561
|
-
if (!
|
|
588235
|
+
if (!existsSync102(p2)) continue;
|
|
587562
588236
|
try {
|
|
587563
|
-
const raw = JSON.parse(
|
|
588237
|
+
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587564
588238
|
const list = Array.isArray(raw) ? raw : raw?.sponsors ?? [];
|
|
587565
588239
|
for (const s2 of list) {
|
|
587566
588240
|
suppliers.push({
|
|
@@ -587702,7 +588376,7 @@ async function handleAimsConfigHistory(ctx3) {
|
|
|
587702
588376
|
return true;
|
|
587703
588377
|
}
|
|
587704
588378
|
}
|
|
587705
|
-
var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _aimsLocks;
|
|
588379
|
+
var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _peerIdScanCache, _aimsLocks;
|
|
587706
588380
|
var init_routes_v1 = __esm({
|
|
587707
588381
|
"packages/cli/src/api/routes-v1.ts"() {
|
|
587708
588382
|
"use strict";
|
|
@@ -587728,6 +588402,7 @@ var init_routes_v1 = __esm({
|
|
|
587728
588402
|
memoryStoresCache = null;
|
|
587729
588403
|
memoryInitTried = false;
|
|
587730
588404
|
FILE_READ_MAX_BYTES = 2 * 1024 * 1024;
|
|
588405
|
+
_peerIdScanCache = null;
|
|
587731
588406
|
_aimsLocks = /* @__PURE__ */ new Map();
|
|
587732
588407
|
}
|
|
587733
588408
|
});
|
|
@@ -590881,35 +591556,173 @@ document.getElementById('key-btn').onclick = () => {
|
|
|
590881
591556
|
};
|
|
590882
591557
|
function saveKey() {
|
|
590883
591558
|
const raw = document.getElementById('key-input').value || '';
|
|
590884
|
-
// SHARE: detect oa-share://host:port#key OR http(s)://host:port/?oa-key=...
|
|
590885
591559
|
const parsed = parseShareInput(raw);
|
|
590886
591560
|
if (parsed) {
|
|
590887
|
-
//
|
|
590888
|
-
|
|
590889
|
-
|
|
590890
|
-
|
|
590891
|
-
|
|
590892
|
-
|
|
590893
|
-
|
|
590894
|
-
}
|
|
590895
|
-
|
|
590896
|
-
|
|
590897
|
-
|
|
590898
|
-
|
|
590899
|
-
|
|
590900
|
-
|
|
590901
|
-
|
|
590902
|
-
|
|
591561
|
+
// Save into recent-keys for autocomplete
|
|
591562
|
+
const recLabel = parsed.label || (parsed.peerId
|
|
591563
|
+
? ('remote ' + (parsed.peerId.slice(0, 12) + '…'))
|
|
591564
|
+
: ('remote ' + parsed.host));
|
|
591565
|
+
saveRecentKey({
|
|
591566
|
+
key: parsed.key, peerId: parsed.peerId, onion: parsed.onion || null,
|
|
591567
|
+
host: parsed.host, label: recLabel,
|
|
591568
|
+
});
|
|
591569
|
+
if (parsed.peerId || parsed.onion) {
|
|
591570
|
+
// ─── REMOTE MODE: libp2p (primary) + Tor (fallback) ──────────────
|
|
591571
|
+
// Stay on this page; route /v1/... calls through this daemon's
|
|
591572
|
+
// /v1/remote-proxy. The local daemon will try libp2p invoke first
|
|
591573
|
+
// (when peerId is set); if that fails (or peerId missing) it
|
|
591574
|
+
// falls back to Tor SOCKS5 → onion (when onion is set).
|
|
591575
|
+
try {
|
|
591576
|
+
localStorage.setItem('oa.activeRemoteShare', JSON.stringify({
|
|
591577
|
+
peerId: parsed.peerId,
|
|
591578
|
+
onion: parsed.onion || null,
|
|
591579
|
+
key: parsed.key,
|
|
591580
|
+
host: parsed.host || null,
|
|
591581
|
+
label: recLabel,
|
|
591582
|
+
activatedAt: new Date().toISOString(),
|
|
591583
|
+
}));
|
|
591584
|
+
} catch {}
|
|
591585
|
+
installRemoteFetchProxy();
|
|
591586
|
+
closeKeyModal();
|
|
591587
|
+
try { location.reload(); } catch { loadModels(); }
|
|
591588
|
+
return;
|
|
591589
|
+
}
|
|
591590
|
+
if (parsed.host) {
|
|
591591
|
+
// Legacy direct-HTTP — open the remote origin in a new tab.
|
|
591592
|
+
const remoteUrl = (parsed.scheme || 'http') + '://' + parsed.host + '/?oa-key=' + encodeURIComponent(parsed.key) + '&oa-share-label=' + encodeURIComponent(parsed.label || '');
|
|
591593
|
+
window.open(remoteUrl, '_blank');
|
|
591594
|
+
closeKeyModal();
|
|
591595
|
+
return;
|
|
591596
|
+
}
|
|
590903
591597
|
}
|
|
590904
591598
|
apiKey = raw;
|
|
590905
591599
|
localStorage.setItem('oa-api-key', apiKey);
|
|
590906
|
-
// Track this key in the recent-keys list so future paste autocompletes it.
|
|
590907
591600
|
if (apiKey) {
|
|
590908
591601
|
saveRecentKey({ key: apiKey, host: location.host, label: 'local ' + location.host });
|
|
590909
591602
|
}
|
|
590910
591603
|
closeKeyModal();
|
|
590911
591604
|
loadModels();
|
|
590912
591605
|
}
|
|
591606
|
+
|
|
591607
|
+
// ─── Remote-mode fetch proxy ─────────────────────────────────────────────
|
|
591608
|
+
// When 'oa.activeRemoteShare' is set, intercept window.fetch so any
|
|
591609
|
+
// /v1/... call gets re-routed via POST /v1/remote-proxy to be tunneled
|
|
591610
|
+
// through libp2p to the remote peer. SSE streams keep their text/event-
|
|
591611
|
+
// stream shape end-to-end.
|
|
591612
|
+
let _oaRemoteFetchInstalled = false;
|
|
591613
|
+
function getActiveRemoteShare() {
|
|
591614
|
+
try {
|
|
591615
|
+
const raw = localStorage.getItem('oa.activeRemoteShare');
|
|
591616
|
+
if (!raw) return null;
|
|
591617
|
+
const obj = JSON.parse(raw);
|
|
591618
|
+
if (!obj || !obj.peerId || !obj.key) return null;
|
|
591619
|
+
return obj;
|
|
591620
|
+
} catch { return null; }
|
|
591621
|
+
}
|
|
591622
|
+
function clearActiveRemoteShare() {
|
|
591623
|
+
try { localStorage.removeItem('oa.activeRemoteShare'); } catch {}
|
|
591624
|
+
}
|
|
591625
|
+
function installRemoteFetchProxy() {
|
|
591626
|
+
if (_oaRemoteFetchInstalled) return;
|
|
591627
|
+
_oaRemoteFetchInstalled = true;
|
|
591628
|
+
const _origFetch = window.fetch.bind(window);
|
|
591629
|
+
window.fetch = async function(input, init) {
|
|
591630
|
+
const share = getActiveRemoteShare();
|
|
591631
|
+
if (!share) return _origFetch(input, init);
|
|
591632
|
+
let urlStr = '';
|
|
591633
|
+
if (typeof input === 'string') urlStr = input;
|
|
591634
|
+
else if (input && input.url) urlStr = input.url;
|
|
591635
|
+
else return _origFetch(input, init);
|
|
591636
|
+
let pathOnly;
|
|
591637
|
+
try {
|
|
591638
|
+
const u = new URL(urlStr, location.href);
|
|
591639
|
+
// Don't proxy:
|
|
591640
|
+
// - cross-origin (already remote)
|
|
591641
|
+
// - the proxy endpoint itself (infinite loop)
|
|
591642
|
+
// - non-/v1/* routes (e.g. /assets, /openapi.json)
|
|
591643
|
+
if (u.origin !== location.origin) return _origFetch(input, init);
|
|
591644
|
+
if (u.pathname === '/v1/remote-proxy') return _origFetch(input, init);
|
|
591645
|
+
if (!u.pathname.startsWith('/v1/')) return _origFetch(input, init);
|
|
591646
|
+
pathOnly = u.pathname + u.search;
|
|
591647
|
+
} catch { return _origFetch(input, init); }
|
|
591648
|
+
|
|
591649
|
+
const method = ((init && init.method) || (input && input.method) || 'GET').toUpperCase();
|
|
591650
|
+
const headersIn = {};
|
|
591651
|
+
if (init && init.headers) {
|
|
591652
|
+
const h = init.headers;
|
|
591653
|
+
if (h instanceof Headers) h.forEach((v, k) => { headersIn[k] = v; });
|
|
591654
|
+
else if (Array.isArray(h)) h.forEach(([k, v]) => { headersIn[k] = v; });
|
|
591655
|
+
else Object.assign(headersIn, h);
|
|
591656
|
+
}
|
|
591657
|
+
let bodyOut;
|
|
591658
|
+
if (init && init.body !== undefined && init.body !== null) {
|
|
591659
|
+
if (typeof init.body === 'string') bodyOut = init.body;
|
|
591660
|
+
else if (init.body instanceof FormData) {
|
|
591661
|
+
const obj = {}; init.body.forEach((v, k) => { obj[k] = v; });
|
|
591662
|
+
bodyOut = obj;
|
|
591663
|
+
} else bodyOut = init.body;
|
|
591664
|
+
}
|
|
591665
|
+
// Heuristic: SSE if Accept includes text/event-stream OR the path is
|
|
591666
|
+
// a known streaming endpoint. We open the proxy in stream mode and
|
|
591667
|
+
// surface a Response with text/event-stream.
|
|
591668
|
+
const acceptHdr = (headersIn['accept'] || headersIn['Accept'] || '').toLowerCase();
|
|
591669
|
+
const wantsStream = acceptHdr.includes('text/event-stream')
|
|
591670
|
+
|| pathOnly.includes('/v1/chat/completions')
|
|
591671
|
+
|| pathOnly.includes('/v1/events');
|
|
591672
|
+
|
|
591673
|
+
const proxyBody = JSON.stringify({
|
|
591674
|
+
peerId: share.peerId || null,
|
|
591675
|
+
onion: share.onion || null,
|
|
591676
|
+
key: share.key,
|
|
591677
|
+
method, path: pathOnly, headers: headersIn, body: bodyOut,
|
|
591678
|
+
stream: wantsStream, timeoutMs: 120000,
|
|
591679
|
+
});
|
|
591680
|
+
if (wantsStream) {
|
|
591681
|
+
// Pass through as-is — receiver returns text/event-stream.
|
|
591682
|
+
return _origFetch('/v1/remote-proxy', {
|
|
591683
|
+
method: 'POST',
|
|
591684
|
+
headers: { 'content-type': 'application/json', 'accept': 'text/event-stream' },
|
|
591685
|
+
body: proxyBody,
|
|
591686
|
+
});
|
|
591687
|
+
}
|
|
591688
|
+
// Non-stream: receiver returns a JSON envelope { status, headers, body }.
|
|
591689
|
+
// Synthesize a Response that mimics the original remote response.
|
|
591690
|
+
const proxyResp = await _origFetch('/v1/remote-proxy', {
|
|
591691
|
+
method: 'POST',
|
|
591692
|
+
headers: { 'content-type': 'application/json' },
|
|
591693
|
+
body: proxyBody,
|
|
591694
|
+
});
|
|
591695
|
+
if (!proxyResp.ok) return proxyResp;
|
|
591696
|
+
let env = null;
|
|
591697
|
+
try { env = await proxyResp.json(); } catch {}
|
|
591698
|
+
if (!env || typeof env !== 'object') {
|
|
591699
|
+
return new Response('', { status: 502, statusText: 'Empty proxy response' });
|
|
591700
|
+
}
|
|
591701
|
+
// The non-stream envelope is the http_tunnel handler last event,
|
|
591702
|
+
// with its body JSON-stringified inside the data field. Unwrap it.
|
|
591703
|
+
let status = 200;
|
|
591704
|
+
let headersOut = new Headers();
|
|
591705
|
+
let bodyText = '';
|
|
591706
|
+
if (typeof env.raw === 'string') {
|
|
591707
|
+
// Single-shot result from the http_tunnel head+body events combined
|
|
591708
|
+
bodyText = env.raw;
|
|
591709
|
+
} else if (env.event === 'http.body' || env.event === 'http.head') {
|
|
591710
|
+
try {
|
|
591711
|
+
const inner = JSON.parse(env.data);
|
|
591712
|
+
if (inner.status) status = inner.status;
|
|
591713
|
+
if (inner.headers) Object.entries(inner.headers).forEach(([k, v]) => headersOut.set(k, String(v)));
|
|
591714
|
+
} catch {}
|
|
591715
|
+
bodyText = String(env.data || '');
|
|
591716
|
+
} else {
|
|
591717
|
+
bodyText = JSON.stringify(env);
|
|
591718
|
+
}
|
|
591719
|
+
return new Response(bodyText, { status, headers: headersOut });
|
|
591720
|
+
};
|
|
591721
|
+
}
|
|
591722
|
+
// Auto-install on every load if a remote share is active.
|
|
591723
|
+
try {
|
|
591724
|
+
if (getActiveRemoteShare()) installRemoteFetchProxy();
|
|
591725
|
+
} catch {}
|
|
590913
591726
|
function clearKey() {
|
|
590914
591727
|
apiKey = '';
|
|
590915
591728
|
localStorage.removeItem('oa-api-key');
|
|
@@ -590930,14 +591743,23 @@ function openKeyModal() {
|
|
|
590930
591743
|
window.openKeyModal = openKeyModal;
|
|
590931
591744
|
|
|
590932
591745
|
// ─── Share URL parsing ─────────────────────────────────────────────────
|
|
590933
|
-
// Accepts
|
|
590934
|
-
// oa-share
|
|
590935
|
-
//
|
|
590936
|
-
//
|
|
591746
|
+
// Accepts:
|
|
591747
|
+
// oa-share://<peerId>#<key> (libp2p, global)
|
|
591748
|
+
// oa-share://<peerId>@<host:port>#<key> (libp2p w/ LAN hint)
|
|
591749
|
+
// oa-share://<host:port>#<key> (legacy direct-HTTP)
|
|
591750
|
+
// http(s)://host:port/?oa-key=KEY[&oa-share-peer=PID&oa-share-label=L]
|
|
591751
|
+
// Returns { peerId?, host?, key, scheme?, label? } or null when the input
|
|
591752
|
+
// is a plain key. peerId is a libp2p PeerID (starts with 12D3KooW or Qm).
|
|
591753
|
+
function _looksLikePeerId(s) {
|
|
591754
|
+
if (!s || typeof s !== 'string') return false;
|
|
591755
|
+
// libp2p PeerIDs are base58-encoded multihashes, typically starting with
|
|
591756
|
+
// 12D3KooW (Ed25519) or Qm (RSA). Length ~46-52 chars, no dots or colons.
|
|
591757
|
+
return /^(12D3KooW|Qm)[1-9A-HJ-NP-Za-km-z]{30,}$/.test(s);
|
|
591758
|
+
}
|
|
590937
591759
|
function parseShareInput(raw) {
|
|
590938
591760
|
const v = String(raw || '').trim();
|
|
590939
591761
|
if (!v) return null;
|
|
590940
|
-
// oa-share scheme —
|
|
591762
|
+
// oa-share scheme — custom parser since URL() doesn't always honor it.
|
|
590941
591763
|
if (v.toLowerCase().startsWith('oa-share://')) {
|
|
590942
591764
|
const after = v.slice('oa-share://'.length);
|
|
590943
591765
|
const hashIdx = after.indexOf('#');
|
|
@@ -590945,19 +591767,36 @@ function parseShareInput(raw) {
|
|
|
590945
591767
|
const hostPart = after.slice(0, hashIdx);
|
|
590946
591768
|
const key = after.slice(hashIdx + 1);
|
|
590947
591769
|
if (!hostPart || !key) return null;
|
|
590948
|
-
//
|
|
591770
|
+
// Three shapes:
|
|
591771
|
+
// peerId@host:port → libp2p+LAN
|
|
591772
|
+
// peerId → libp2p only (no host)
|
|
591773
|
+
// host:port → legacy direct
|
|
590949
591774
|
const atIdx = hostPart.indexOf('@');
|
|
590950
|
-
|
|
590951
|
-
|
|
591775
|
+
if (atIdx >= 0) {
|
|
591776
|
+
const peerId = hostPart.slice(0, atIdx);
|
|
591777
|
+
const host = hostPart.slice(atIdx + 1);
|
|
591778
|
+
return { peerId: _looksLikePeerId(peerId) ? peerId : null, host, key, scheme: 'http' };
|
|
591779
|
+
}
|
|
591780
|
+
if (_looksLikePeerId(hostPart)) {
|
|
591781
|
+
return { peerId: hostPart, host: null, key, scheme: 'libp2p' };
|
|
591782
|
+
}
|
|
591783
|
+
return { peerId: null, host: hostPart, key, scheme: 'http' };
|
|
590952
591784
|
}
|
|
590953
|
-
// http(s) URL with ?oa-key
|
|
591785
|
+
// http(s) URL with ?oa-key=, optional ?oa-share-peer=, optional ?oa-onion=
|
|
590954
591786
|
if (/^https?:\\/\\//i.test(v)) {
|
|
590955
591787
|
try {
|
|
590956
591788
|
const u = new URL(v);
|
|
590957
591789
|
const k = u.searchParams.get('oa-key');
|
|
590958
591790
|
if (!k) return null;
|
|
591791
|
+
const peerIdQ = u.searchParams.get('oa-share-peer') || null;
|
|
591792
|
+
const onionQ = u.searchParams.get('oa-onion') || null;
|
|
590959
591793
|
const label = u.searchParams.get('oa-share-label') || '';
|
|
590960
|
-
return {
|
|
591794
|
+
return {
|
|
591795
|
+
peerId: _looksLikePeerId(peerIdQ) ? peerIdQ : null,
|
|
591796
|
+
onion: (onionQ && onionQ.endsWith('.onion')) ? onionQ : null,
|
|
591797
|
+
host: u.host, key: k,
|
|
591798
|
+
scheme: u.protocol.replace(':', ''), label,
|
|
591799
|
+
};
|
|
590961
591800
|
} catch { return null; }
|
|
590962
591801
|
}
|
|
590963
591802
|
return null;
|
|
@@ -591133,17 +591972,32 @@ window.copyShareUrl = copyShareUrl;
|
|
|
591133
591972
|
// inline with a "close connection" button that severs and shuffles the
|
|
591134
591973
|
// key into recents.
|
|
591135
591974
|
function refreshKeyModalRemoteState() {
|
|
591136
|
-
|
|
591975
|
+
// Two remote modes coexist:
|
|
591976
|
+
// 1. libp2p — oa.activeRemoteShare = {peerId, key, host?, label}
|
|
591977
|
+
// 2. direct — oa.remoteHost (legacy, set by ?oa-key= pickup)
|
|
591978
|
+
const active = getActiveRemoteShare();
|
|
591979
|
+
const directHost = (function() {
|
|
591137
591980
|
try { return localStorage.getItem('oa.remoteHost') || ''; } catch { return ''; }
|
|
591138
591981
|
})();
|
|
591982
|
+
const isRemote = !!active || !!directHost;
|
|
591983
|
+
let remoteLabel;
|
|
591984
|
+
if (active) {
|
|
591985
|
+
const parts = [];
|
|
591986
|
+
if (active.peerId) parts.push('libp2p ' + active.peerId.slice(0, 12) + '…');
|
|
591987
|
+
if (active.onion) parts.push('tor ' + active.onion.slice(0, 16) + '…');
|
|
591988
|
+
if (active.host) parts.push(active.host);
|
|
591989
|
+
remoteLabel = parts.join(' / ') || 'remote';
|
|
591990
|
+
} else {
|
|
591991
|
+
remoteLabel = directHost;
|
|
591992
|
+
}
|
|
591139
591993
|
const stateBox = document.getElementById('remote-state');
|
|
591140
591994
|
const btn = document.getElementById('sidebar-key-btn');
|
|
591141
|
-
if (
|
|
591995
|
+
if (isRemote && btn) {
|
|
591142
591996
|
btn.textContent = 'remote';
|
|
591143
591997
|
btn.style.background = 'var(--color-accent)';
|
|
591144
591998
|
btn.style.color = '#fff';
|
|
591145
591999
|
btn.style.borderColor = 'var(--color-accent)';
|
|
591146
|
-
btn.title = 'connected to
|
|
592000
|
+
btn.title = 'connected to ' + remoteLabel + ' — click to view / disconnect';
|
|
591147
592001
|
} else if (btn) {
|
|
591148
592002
|
btn.textContent = 'key';
|
|
591149
592003
|
btn.style.background = 'transparent';
|
|
@@ -591152,27 +592006,43 @@ function refreshKeyModalRemoteState() {
|
|
|
591152
592006
|
btn.title = 'set API key / share access';
|
|
591153
592007
|
}
|
|
591154
592008
|
if (!stateBox) return;
|
|
591155
|
-
if (
|
|
591156
|
-
const
|
|
592009
|
+
if (isRemote) {
|
|
592010
|
+
const safe = escapeHtml(remoteLabel);
|
|
592011
|
+
let mode;
|
|
592012
|
+
if (active) {
|
|
592013
|
+
const tiers = [];
|
|
592014
|
+
if (active.peerId) tiers.push('libp2p');
|
|
592015
|
+
if (active.onion) tiers.push('tor');
|
|
592016
|
+
mode = tiers.join(' + ') + ' (global)';
|
|
592017
|
+
} else {
|
|
592018
|
+
mode = 'direct (LAN/VPN)';
|
|
592019
|
+
}
|
|
591157
592020
|
stateBox.style.display = 'block';
|
|
591158
592021
|
stateBox.innerHTML =
|
|
591159
592022
|
'<div style="font-weight:500;color:var(--color-accent)">REMOTE connection active</div>' +
|
|
591160
|
-
'<div style="margin-top:4px;font-size:0.74rem">
|
|
592023
|
+
'<div style="margin-top:4px;font-size:0.74rem">mode <code>' + escapeHtml(mode) + '</code></div>' +
|
|
592024
|
+
'<div style="margin-top:2px;font-size:0.74rem">target <code>' + safe + '</code></div>' +
|
|
591161
592025
|
'<div style="margin-top:8px"><button type="button" onclick="closeRemoteConnection()" style="background:var(--color-error);color:#fff;border:none;padding:4px 10px;border-radius:var(--radius-sm);cursor:pointer;font-size:0.74rem">close connection</button></div>';
|
|
591162
592026
|
} else {
|
|
591163
592027
|
stateBox.style.display = 'none';
|
|
591164
592028
|
}
|
|
591165
592029
|
}
|
|
591166
592030
|
function closeRemoteConnection() {
|
|
591167
|
-
//
|
|
591168
|
-
|
|
591169
|
-
|
|
591170
|
-
|
|
591171
|
-
|
|
591172
|
-
|
|
591173
|
-
|
|
591174
|
-
|
|
591175
|
-
|
|
592031
|
+
// Save the active remote into recents before clearing.
|
|
592032
|
+
const active = getActiveRemoteShare();
|
|
592033
|
+
if (active) {
|
|
592034
|
+
saveRecentKey({
|
|
592035
|
+
key: active.key, peerId: active.peerId, host: active.host,
|
|
592036
|
+
label: 'recent ' + (active.label || ('remote ' + (active.peerId || '').slice(0, 12) + '…')),
|
|
592037
|
+
});
|
|
592038
|
+
clearActiveRemoteShare();
|
|
592039
|
+
} else {
|
|
592040
|
+
let savedKey = ''; let savedHost = '';
|
|
592041
|
+
try {
|
|
592042
|
+
savedKey = localStorage.getItem('oa-api-key') || '';
|
|
592043
|
+
savedHost = localStorage.getItem('oa.remoteHost') || '';
|
|
592044
|
+
} catch {}
|
|
592045
|
+
if (savedKey) saveRecentKey({ key: savedKey, host: savedHost, label: 'recent remote ' + savedHost });
|
|
591176
592046
|
}
|
|
591177
592047
|
try {
|
|
591178
592048
|
localStorage.removeItem('oa.remoteHost');
|
|
@@ -591181,7 +592051,6 @@ function closeRemoteConnection() {
|
|
|
591181
592051
|
} catch {}
|
|
591182
592052
|
apiKey = '';
|
|
591183
592053
|
refreshKeyModalRemoteState();
|
|
591184
|
-
// Reload to drop any cached state from the remote target.
|
|
591185
592054
|
location.reload();
|
|
591186
592055
|
}
|
|
591187
592056
|
window.closeRemoteConnection = closeRemoteConnection;
|
|
@@ -595973,15 +596842,15 @@ var init_auth_oidc = __esm({
|
|
|
595973
596842
|
});
|
|
595974
596843
|
|
|
595975
596844
|
// packages/cli/src/api/usage-tracker.ts
|
|
595976
|
-
import { mkdirSync as mkdirSync60, readFileSync as
|
|
595977
|
-
import { join as
|
|
596845
|
+
import { mkdirSync as mkdirSync60, readFileSync as readFileSync84, writeFileSync as writeFileSync52, existsSync as existsSync103 } from "node:fs";
|
|
596846
|
+
import { join as join119 } from "node:path";
|
|
595978
596847
|
function initUsageTracker(oaDir) {
|
|
595979
|
-
const dir =
|
|
596848
|
+
const dir = join119(oaDir, "usage");
|
|
595980
596849
|
mkdirSync60(dir, { recursive: true });
|
|
595981
|
-
usageFile =
|
|
596850
|
+
usageFile = join119(dir, "token-usage.json");
|
|
595982
596851
|
try {
|
|
595983
|
-
if (
|
|
595984
|
-
store = JSON.parse(
|
|
596852
|
+
if (existsSync103(usageFile)) {
|
|
596853
|
+
store = JSON.parse(readFileSync84(usageFile, "utf-8"));
|
|
595985
596854
|
}
|
|
595986
596855
|
} catch {
|
|
595987
596856
|
store = { providers: {}, lastSaved: "" };
|
|
@@ -596045,24 +596914,24 @@ var init_usage_tracker = __esm({
|
|
|
596045
596914
|
});
|
|
596046
596915
|
|
|
596047
596916
|
// packages/cli/src/api/profiles.ts
|
|
596048
|
-
import { existsSync as
|
|
596049
|
-
import { join as
|
|
596050
|
-
import { homedir as
|
|
596917
|
+
import { existsSync as existsSync104, readFileSync as readFileSync85, writeFileSync as writeFileSync53, mkdirSync as mkdirSync61, readdirSync as readdirSync35, unlinkSync as unlinkSync23 } from "node:fs";
|
|
596918
|
+
import { join as join120 } from "node:path";
|
|
596919
|
+
import { homedir as homedir41 } from "node:os";
|
|
596051
596920
|
import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes22, scryptSync as scryptSync3 } from "node:crypto";
|
|
596052
596921
|
function globalProfileDir() {
|
|
596053
|
-
return
|
|
596922
|
+
return join120(homedir41(), ".open-agents", "profiles");
|
|
596054
596923
|
}
|
|
596055
596924
|
function projectProfileDir(projectDir2) {
|
|
596056
|
-
return
|
|
596925
|
+
return join120(projectDir2 || process.cwd(), ".oa", "profiles");
|
|
596057
596926
|
}
|
|
596058
596927
|
function listProfiles(projectDir2) {
|
|
596059
596928
|
const result = [];
|
|
596060
596929
|
const seen = /* @__PURE__ */ new Set();
|
|
596061
596930
|
const projDir = projectProfileDir(projectDir2);
|
|
596062
|
-
if (
|
|
596931
|
+
if (existsSync104(projDir)) {
|
|
596063
596932
|
for (const f2 of readdirSync35(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596064
596933
|
try {
|
|
596065
|
-
const raw = JSON.parse(
|
|
596934
|
+
const raw = JSON.parse(readFileSync85(join120(projDir, f2), "utf8"));
|
|
596066
596935
|
const name10 = f2.replace(".json", "");
|
|
596067
596936
|
seen.add(name10);
|
|
596068
596937
|
result.push({
|
|
@@ -596076,12 +596945,12 @@ function listProfiles(projectDir2) {
|
|
|
596076
596945
|
}
|
|
596077
596946
|
}
|
|
596078
596947
|
const globDir = globalProfileDir();
|
|
596079
|
-
if (
|
|
596948
|
+
if (existsSync104(globDir)) {
|
|
596080
596949
|
for (const f2 of readdirSync35(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596081
596950
|
const name10 = f2.replace(".json", "");
|
|
596082
596951
|
if (seen.has(name10)) continue;
|
|
596083
596952
|
try {
|
|
596084
|
-
const raw = JSON.parse(
|
|
596953
|
+
const raw = JSON.parse(readFileSync85(join120(globDir, f2), "utf8"));
|
|
596085
596954
|
result.push({
|
|
596086
596955
|
name: name10,
|
|
596087
596956
|
description: raw.description || "",
|
|
@@ -596096,11 +596965,11 @@ function listProfiles(projectDir2) {
|
|
|
596096
596965
|
}
|
|
596097
596966
|
function loadProfile(name10, password, projectDir2) {
|
|
596098
596967
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596099
|
-
const projPath =
|
|
596100
|
-
const globPath =
|
|
596101
|
-
const filePath =
|
|
596968
|
+
const projPath = join120(projectProfileDir(projectDir2), `${sanitized}.json`);
|
|
596969
|
+
const globPath = join120(globalProfileDir(), `${sanitized}.json`);
|
|
596970
|
+
const filePath = existsSync104(projPath) ? projPath : existsSync104(globPath) ? globPath : null;
|
|
596102
596971
|
if (!filePath) return null;
|
|
596103
|
-
const raw = JSON.parse(
|
|
596972
|
+
const raw = JSON.parse(readFileSync85(filePath, "utf8"));
|
|
596104
596973
|
if (raw.encrypted === true) {
|
|
596105
596974
|
if (!password) return null;
|
|
596106
596975
|
return decryptProfile(raw, password);
|
|
@@ -596111,7 +596980,7 @@ function saveProfile(profile, password, scope = "global", projectDir2) {
|
|
|
596111
596980
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596112
596981
|
mkdirSync61(dir, { recursive: true });
|
|
596113
596982
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596114
|
-
const filePath =
|
|
596983
|
+
const filePath = join120(dir, `${sanitized}.json`);
|
|
596115
596984
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
596116
596985
|
if (password) {
|
|
596117
596986
|
const encrypted = encryptProfile(profile, password);
|
|
@@ -596124,8 +596993,8 @@ function saveProfile(profile, password, scope = "global", projectDir2) {
|
|
|
596124
596993
|
function deleteProfile(name10, scope = "global", projectDir2) {
|
|
596125
596994
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596126
596995
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596127
|
-
const filePath =
|
|
596128
|
-
if (
|
|
596996
|
+
const filePath = join120(dir, `${sanitized}.json`);
|
|
596997
|
+
if (existsSync104(filePath)) {
|
|
596129
596998
|
unlinkSync23(filePath);
|
|
596130
596999
|
return true;
|
|
596131
597000
|
}
|
|
@@ -596240,23 +597109,23 @@ var init_profiles = __esm({
|
|
|
596240
597109
|
|
|
596241
597110
|
// packages/cli/src/docker.ts
|
|
596242
597111
|
import { execSync as execSync56, spawn as spawn24 } from "node:child_process";
|
|
596243
|
-
import { existsSync as
|
|
596244
|
-
import { join as
|
|
596245
|
-
import { homedir as
|
|
597112
|
+
import { existsSync as existsSync105, mkdirSync as mkdirSync62, writeFileSync as writeFileSync54 } from "node:fs";
|
|
597113
|
+
import { join as join121, resolve as resolve37, dirname as dirname35 } from "node:path";
|
|
597114
|
+
import { homedir as homedir42 } from "node:os";
|
|
596246
597115
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
596247
597116
|
function getDockerDir() {
|
|
596248
597117
|
try {
|
|
596249
597118
|
if (typeof __dirname !== "undefined") {
|
|
596250
|
-
return
|
|
597119
|
+
return join121(__dirname, "..", "..", "..", "docker");
|
|
596251
597120
|
}
|
|
596252
597121
|
} catch {
|
|
596253
597122
|
}
|
|
596254
597123
|
try {
|
|
596255
597124
|
const thisDir = dirname35(fileURLToPath16(import.meta.url));
|
|
596256
|
-
return
|
|
597125
|
+
return join121(thisDir, "..", "..", "..", "docker");
|
|
596257
597126
|
} catch {
|
|
596258
597127
|
}
|
|
596259
|
-
return
|
|
597128
|
+
return join121(process.cwd(), "docker");
|
|
596260
597129
|
}
|
|
596261
597130
|
function isDockerAvailable() {
|
|
596262
597131
|
try {
|
|
@@ -596387,10 +597256,10 @@ async function ensureOaImage(force = false) {
|
|
|
596387
597256
|
}
|
|
596388
597257
|
let buildContext;
|
|
596389
597258
|
const dockerDir = getDockerDir();
|
|
596390
|
-
if (
|
|
597259
|
+
if (existsSync105(join121(dockerDir, "Dockerfile"))) {
|
|
596391
597260
|
buildContext = dockerDir;
|
|
596392
597261
|
} else {
|
|
596393
|
-
buildContext =
|
|
597262
|
+
buildContext = join121(homedir42(), ".oa", "docker-build");
|
|
596394
597263
|
mkdirSync62(buildContext, { recursive: true });
|
|
596395
597264
|
writeDockerfiles(buildContext);
|
|
596396
597265
|
}
|
|
@@ -596465,8 +597334,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
|
|
|
596465
597334
|
if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
|
|
596466
597335
|
exec "$@"
|
|
596467
597336
|
`;
|
|
596468
|
-
writeFileSync54(
|
|
596469
|
-
writeFileSync54(
|
|
597337
|
+
writeFileSync54(join121(dir, "Dockerfile"), dockerfile);
|
|
597338
|
+
writeFileSync54(join121(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
596470
597339
|
}
|
|
596471
597340
|
function hasNvidiaGpu() {
|
|
596472
597341
|
try {
|
|
@@ -596719,23 +597588,23 @@ import * as http5 from "node:http";
|
|
|
596719
597588
|
import * as https3 from "node:https";
|
|
596720
597589
|
import { createRequire as createRequire5 } from "node:module";
|
|
596721
597590
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
596722
|
-
import { dirname as dirname36, join as
|
|
596723
|
-
import { homedir as
|
|
597591
|
+
import { dirname as dirname36, join as join122, resolve as resolve38 } from "node:path";
|
|
597592
|
+
import { homedir as homedir43 } from "node:os";
|
|
596724
597593
|
import { spawn as spawn25, execSync as execSync57 } from "node:child_process";
|
|
596725
|
-
import { mkdirSync as mkdirSync63, writeFileSync as writeFileSync55, readFileSync as
|
|
597594
|
+
import { mkdirSync as mkdirSync63, writeFileSync as writeFileSync55, readFileSync as readFileSync86, readdirSync as readdirSync36, existsSync as existsSync106, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
|
|
596726
597595
|
import { randomBytes as randomBytes23, randomUUID as randomUUID16 } from "node:crypto";
|
|
596727
597596
|
import { createHash as createHash19 } from "node:crypto";
|
|
596728
597597
|
function getVersion3() {
|
|
596729
597598
|
try {
|
|
596730
597599
|
const thisDir = dirname36(fileURLToPath17(import.meta.url));
|
|
596731
597600
|
const candidates = [
|
|
596732
|
-
|
|
596733
|
-
|
|
596734
|
-
|
|
597601
|
+
join122(thisDir, "..", "package.json"),
|
|
597602
|
+
join122(thisDir, "..", "..", "package.json"),
|
|
597603
|
+
join122(thisDir, "..", "..", "..", "package.json")
|
|
596735
597604
|
];
|
|
596736
597605
|
for (const pkgPath of candidates) {
|
|
596737
597606
|
try {
|
|
596738
|
-
if (!
|
|
597607
|
+
if (!existsSync106(pkgPath)) continue;
|
|
596739
597608
|
const pkg = require3(pkgPath);
|
|
596740
597609
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
596741
597610
|
return pkg.version ?? "0.0.0";
|
|
@@ -596937,9 +597806,9 @@ function isOriginAllowed(origin) {
|
|
|
596937
597806
|
if (!origin) return true;
|
|
596938
597807
|
let accessMode = (process.env["OA_ACCESS"] || "").toLowerCase().trim();
|
|
596939
597808
|
try {
|
|
596940
|
-
const accessFile =
|
|
596941
|
-
if (
|
|
596942
|
-
const persisted =
|
|
597809
|
+
const accessFile = join122(homedir43(), ".open-agents", "access");
|
|
597810
|
+
if (existsSync106(accessFile)) {
|
|
597811
|
+
const persisted = readFileSync86(accessFile, "utf8").trim().toLowerCase();
|
|
596943
597812
|
if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
|
|
596944
597813
|
accessMode = persisted;
|
|
596945
597814
|
}
|
|
@@ -596999,7 +597868,7 @@ async function retrieveMemoryContext(userMessage, sessionId, maxEpisodes = 5) {
|
|
|
596999
597868
|
if (!memMod || !memMod.EpisodeStore) {
|
|
597000
597869
|
return { contextBlock: "", retrieved: [] };
|
|
597001
597870
|
}
|
|
597002
|
-
const dbPath =
|
|
597871
|
+
const dbPath = join122(homedir43(), ".open-agents", "memory.db");
|
|
597003
597872
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597004
597873
|
const recent = store2.search({ limit: 30, sessionId: void 0 }) ?? [];
|
|
597005
597874
|
const qLower = userMessage.toLowerCase();
|
|
@@ -597042,7 +597911,7 @@ async function writeMemoryEpisodes(sessionId, userMessage, assistantContent, too
|
|
|
597042
597911
|
try {
|
|
597043
597912
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2)).catch(() => null);
|
|
597044
597913
|
if (!memMod || !memMod.EpisodeStore) return 0;
|
|
597045
|
-
const dbPath =
|
|
597914
|
+
const dbPath = join122(homedir43(), ".open-agents", "memory.db");
|
|
597046
597915
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597047
597916
|
let written = 0;
|
|
597048
597917
|
try {
|
|
@@ -597364,27 +598233,27 @@ function ollamaStream(ollamaUrl, path8, method, body, onData, onEnd, onError, ti
|
|
|
597364
598233
|
}
|
|
597365
598234
|
function jobsDir() {
|
|
597366
598235
|
const root = resolve38(process.cwd());
|
|
597367
|
-
const dir =
|
|
598236
|
+
const dir = join122(root, ".oa", "jobs");
|
|
597368
598237
|
mkdirSync63(dir, { recursive: true });
|
|
597369
598238
|
return dir;
|
|
597370
598239
|
}
|
|
597371
598240
|
function loadJob(id) {
|
|
597372
|
-
const file =
|
|
597373
|
-
if (!
|
|
598241
|
+
const file = join122(jobsDir(), `${id}.json`);
|
|
598242
|
+
if (!existsSync106(file)) return null;
|
|
597374
598243
|
try {
|
|
597375
|
-
return JSON.parse(
|
|
598244
|
+
return JSON.parse(readFileSync86(file, "utf-8"));
|
|
597376
598245
|
} catch {
|
|
597377
598246
|
return null;
|
|
597378
598247
|
}
|
|
597379
598248
|
}
|
|
597380
598249
|
function listJobs() {
|
|
597381
598250
|
const dir = jobsDir();
|
|
597382
|
-
if (!
|
|
598251
|
+
if (!existsSync106(dir)) return [];
|
|
597383
598252
|
const files = readdirSync36(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
597384
598253
|
const jobs = [];
|
|
597385
598254
|
for (const file of files) {
|
|
597386
598255
|
try {
|
|
597387
|
-
jobs.push(JSON.parse(
|
|
598256
|
+
jobs.push(JSON.parse(readFileSync86(join122(dir, file), "utf-8")));
|
|
597388
598257
|
} catch {
|
|
597389
598258
|
}
|
|
597390
598259
|
}
|
|
@@ -597394,14 +598263,14 @@ function pruneOldJobs() {
|
|
|
597394
598263
|
const retentionH = parseFloat(process.env["OA_RUN_RETENTION_H"] || "24");
|
|
597395
598264
|
const cutoffMs = Date.now() - (Number.isFinite(retentionH) && retentionH > 0 ? retentionH : 24) * 36e5;
|
|
597396
598265
|
const dir = jobsDir();
|
|
597397
|
-
if (!
|
|
598266
|
+
if (!existsSync106(dir)) return { pruned: 0, kept: 0 };
|
|
597398
598267
|
let pruned = 0;
|
|
597399
598268
|
let kept = 0;
|
|
597400
598269
|
for (const file of readdirSync36(dir)) {
|
|
597401
598270
|
if (!file.endsWith(".json")) continue;
|
|
597402
|
-
const path8 =
|
|
598271
|
+
const path8 = join122(dir, file);
|
|
597403
598272
|
try {
|
|
597404
|
-
const job = JSON.parse(
|
|
598273
|
+
const job = JSON.parse(readFileSync86(path8, "utf-8"));
|
|
597405
598274
|
if (job.status === "running") {
|
|
597406
598275
|
kept++;
|
|
597407
598276
|
continue;
|
|
@@ -597414,7 +598283,7 @@ function pruneOldJobs() {
|
|
|
597414
598283
|
} catch {
|
|
597415
598284
|
}
|
|
597416
598285
|
const outFile = path8.replace(/\.json$/, ".output");
|
|
597417
|
-
if (
|
|
598286
|
+
if (existsSync106(outFile)) {
|
|
597418
598287
|
try {
|
|
597419
598288
|
unlinkSync24(outFile);
|
|
597420
598289
|
} catch {
|
|
@@ -597707,7 +598576,7 @@ function autoSeedTodosFromPrompt(prompt) {
|
|
|
597707
598576
|
return [];
|
|
597708
598577
|
}
|
|
597709
598578
|
function atomicJobWrite(dir, id, job) {
|
|
597710
|
-
const finalPath =
|
|
598579
|
+
const finalPath = join122(dir, `${id}.json`);
|
|
597711
598580
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
597712
598581
|
try {
|
|
597713
598582
|
writeFileSync55(tmpPath, JSON.stringify(job, null, 2), "utf-8");
|
|
@@ -599133,23 +600002,23 @@ ${task}` : task;
|
|
|
599133
600002
|
});
|
|
599134
600003
|
}
|
|
599135
600004
|
function updateStateFile() {
|
|
599136
|
-
return
|
|
600005
|
+
return join122(homedir43(), ".open-agents", "update-state.json");
|
|
599137
600006
|
}
|
|
599138
600007
|
function updateLogPath() {
|
|
599139
|
-
return
|
|
600008
|
+
return join122(homedir43(), ".open-agents", "update.log");
|
|
599140
600009
|
}
|
|
599141
600010
|
function readUpdateState() {
|
|
599142
600011
|
try {
|
|
599143
600012
|
const p2 = updateStateFile();
|
|
599144
|
-
if (!
|
|
599145
|
-
return JSON.parse(
|
|
600013
|
+
if (!existsSync106(p2)) return null;
|
|
600014
|
+
return JSON.parse(readFileSync86(p2, "utf-8"));
|
|
599146
600015
|
} catch {
|
|
599147
600016
|
return null;
|
|
599148
600017
|
}
|
|
599149
600018
|
}
|
|
599150
600019
|
function writeUpdateState(state) {
|
|
599151
600020
|
try {
|
|
599152
|
-
const dir =
|
|
600021
|
+
const dir = join122(homedir43(), ".open-agents");
|
|
599153
600022
|
mkdirSync63(dir, { recursive: true });
|
|
599154
600023
|
const finalPath = updateStateFile();
|
|
599155
600024
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
@@ -599197,15 +600066,15 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
599197
600066
|
const { execSync: es } = require3("node:child_process");
|
|
599198
600067
|
const isWin2 = process.platform === "win32";
|
|
599199
600068
|
let npmBin = "";
|
|
599200
|
-
for (const candidate of isWin2 ? [
|
|
599201
|
-
if (
|
|
600069
|
+
for (const candidate of isWin2 ? [join122(nodeDir, "npm.cmd"), join122(nodeDir, "npm")] : [join122(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
|
|
600070
|
+
if (existsSync106(candidate)) {
|
|
599202
600071
|
npmBin = candidate;
|
|
599203
600072
|
break;
|
|
599204
600073
|
}
|
|
599205
600074
|
}
|
|
599206
600075
|
if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
|
|
599207
600076
|
const pkgSpec = `open-agents-ai@${targetVersion}`;
|
|
599208
|
-
const dir =
|
|
600077
|
+
const dir = join122(homedir43(), ".open-agents");
|
|
599209
600078
|
fs7.mkdirSync(dir, { recursive: true });
|
|
599210
600079
|
const logFd = fs7.openSync(logPath3, "w");
|
|
599211
600080
|
const npmPrefix = dirname36(nodeDir);
|
|
@@ -599215,13 +600084,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
599215
600084
|
globalBinDir = es(`${npmBin} bin -g`, { encoding: "utf8", timeout: 5e3, stdio: "pipe" }).trim();
|
|
599216
600085
|
} else {
|
|
599217
600086
|
const npmCliCandidates = [
|
|
599218
|
-
|
|
599219
|
-
|
|
600087
|
+
join122(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600088
|
+
join122(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
599220
600089
|
];
|
|
599221
600090
|
let npmCli = "";
|
|
599222
600091
|
for (const c9 of npmCliCandidates) {
|
|
599223
600092
|
try {
|
|
599224
|
-
if (
|
|
600093
|
+
if (existsSync106(c9)) {
|
|
599225
600094
|
npmCli = c9;
|
|
599226
600095
|
break;
|
|
599227
600096
|
}
|
|
@@ -599253,13 +600122,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
599253
600122
|
});
|
|
599254
600123
|
} else {
|
|
599255
600124
|
const npmCliCandidates = [
|
|
599256
|
-
|
|
599257
|
-
|
|
600125
|
+
join122(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600126
|
+
join122(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
599258
600127
|
];
|
|
599259
600128
|
let npmCli = "";
|
|
599260
600129
|
for (const c9 of npmCliCandidates) {
|
|
599261
600130
|
try {
|
|
599262
|
-
if (
|
|
600131
|
+
if (existsSync106(c9)) {
|
|
599263
600132
|
npmCli = c9;
|
|
599264
600133
|
break;
|
|
599265
600134
|
}
|
|
@@ -599356,8 +600225,8 @@ function handleV1UpdateStatus(res) {
|
|
|
599356
600225
|
let logTail = "";
|
|
599357
600226
|
let exitCode = null;
|
|
599358
600227
|
try {
|
|
599359
|
-
if (
|
|
599360
|
-
const raw =
|
|
600228
|
+
if (existsSync106(logPath3)) {
|
|
600229
|
+
const raw = readFileSync86(logPath3, "utf-8");
|
|
599361
600230
|
const m2 = raw.match(/__EXIT_CODE=(\d+)/);
|
|
599362
600231
|
if (m2) exitCode = parseInt(m2[1], 10);
|
|
599363
600232
|
logTail = raw.slice(-2e3);
|
|
@@ -599453,7 +600322,7 @@ async function handleV1Run(req2, res) {
|
|
|
599453
600322
|
if (workingDir) {
|
|
599454
600323
|
cwd4 = resolve38(workingDir);
|
|
599455
600324
|
} else if (isolate) {
|
|
599456
|
-
const wsDir =
|
|
600325
|
+
const wsDir = join122(dir, "..", "workspaces", id);
|
|
599457
600326
|
mkdirSync63(wsDir, { recursive: true });
|
|
599458
600327
|
cwd4 = wsDir;
|
|
599459
600328
|
} else {
|
|
@@ -599640,7 +600509,7 @@ async function handleV1Run(req2, res) {
|
|
|
599640
600509
|
let output = "";
|
|
599641
600510
|
let tailBytes = 0;
|
|
599642
600511
|
const TAIL_BUDGET = 1048576;
|
|
599643
|
-
const outputWriter = new DiskTaskOutput(
|
|
600512
|
+
const outputWriter = new DiskTaskOutput(join122(dir, `${id}.output`));
|
|
599644
600513
|
job.outputFile = outputWriter.path;
|
|
599645
600514
|
atomicJobWrite(dir, id, job);
|
|
599646
600515
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -602214,7 +603083,7 @@ ${steering}`;
|
|
|
602214
603083
|
function getScheduleRoots() {
|
|
602215
603084
|
const rootsEnv = process.env["OA_SCHEDULE_ROOTS"] || "";
|
|
602216
603085
|
const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
|
|
602217
|
-
const defaults3 = [process.cwd(),
|
|
603086
|
+
const defaults3 = [process.cwd(), join122(homedir43(), "Documents")];
|
|
602218
603087
|
const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
|
|
602219
603088
|
return [...set];
|
|
602220
603089
|
}
|
|
@@ -602226,10 +603095,10 @@ function listScheduledTasks() {
|
|
|
602226
603095
|
for (const root of roots) {
|
|
602227
603096
|
try {
|
|
602228
603097
|
walk(root, 0, (dir) => {
|
|
602229
|
-
if (dir.endsWith(`${
|
|
602230
|
-
const file =
|
|
603098
|
+
if (dir.endsWith(`${join122(".oa", "scheduled")}`) || dir.includes(`${join122(".oa", "scheduled")}`)) {
|
|
603099
|
+
const file = join122(dir, "tasks.json");
|
|
602231
603100
|
try {
|
|
602232
|
-
const raw =
|
|
603101
|
+
const raw = readFileSync86(file, "utf-8");
|
|
602233
603102
|
const json = JSON.parse(raw);
|
|
602234
603103
|
const tasks = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
|
|
602235
603104
|
tasks.forEach((t2, i2) => {
|
|
@@ -602294,7 +603163,7 @@ function walk(dir, depth, onDir, maxDepth) {
|
|
|
602294
603163
|
if (e2.name === "node_modules" || e2.name.startsWith(".")) {
|
|
602295
603164
|
if (e2.name !== ".oa") continue;
|
|
602296
603165
|
}
|
|
602297
|
-
const child =
|
|
603166
|
+
const child = join122(dir, e2.name);
|
|
602298
603167
|
walk(child, depth + 1, onDir, maxDepth);
|
|
602299
603168
|
}
|
|
602300
603169
|
}
|
|
@@ -602303,7 +603172,7 @@ function setScheduledEnabled(id, enabled2) {
|
|
|
602303
603172
|
const target = tasks.find((t2) => t2.id === id);
|
|
602304
603173
|
if (!target) return false;
|
|
602305
603174
|
try {
|
|
602306
|
-
const raw =
|
|
603175
|
+
const raw = readFileSync86(target.file, "utf-8");
|
|
602307
603176
|
const json = JSON.parse(raw);
|
|
602308
603177
|
const arr = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
|
|
602309
603178
|
if (!arr[target.index]) return false;
|
|
@@ -602336,7 +603205,7 @@ function deleteScheduledById(id) {
|
|
|
602336
603205
|
const target = tasks.find((t2) => t2.id === id);
|
|
602337
603206
|
if (!target) return false;
|
|
602338
603207
|
try {
|
|
602339
|
-
const raw =
|
|
603208
|
+
const raw = readFileSync86(target.file, "utf-8");
|
|
602340
603209
|
const json = JSON.parse(raw);
|
|
602341
603210
|
const arr = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
|
|
602342
603211
|
if (!arr[target.index]) return false;
|
|
@@ -602601,11 +603470,11 @@ function reconcileScheduledTasks(apply) {
|
|
|
602601
603470
|
const errors = [];
|
|
602602
603471
|
for (const f2 of found) {
|
|
602603
603472
|
const wdir = f2.workingDir || process.cwd();
|
|
602604
|
-
const file =
|
|
603473
|
+
const file = join122(wdir, ".oa", "scheduled", "tasks.json");
|
|
602605
603474
|
try {
|
|
602606
603475
|
let json = { tasks: [] };
|
|
602607
603476
|
try {
|
|
602608
|
-
const raw =
|
|
603477
|
+
const raw = readFileSync86(file, "utf-8");
|
|
602609
603478
|
json = JSON.parse(raw);
|
|
602610
603479
|
} catch {
|
|
602611
603480
|
}
|
|
@@ -602616,8 +603485,8 @@ function reconcileScheduledTasks(apply) {
|
|
|
602616
603485
|
const entry = { task: f2.task || `legacy ${f2.id}`, schedule: f2.cron, enabled: true };
|
|
602617
603486
|
arr.push(entry);
|
|
602618
603487
|
const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
|
|
602619
|
-
mkdirSync63(
|
|
602620
|
-
mkdirSync63(
|
|
603488
|
+
mkdirSync63(join122(wdir, ".oa", "scheduled"), { recursive: true });
|
|
603489
|
+
mkdirSync63(join122(wdir, ".oa", "scheduled", "logs"), { recursive: true });
|
|
602621
603490
|
writeFileSync55(file, JSON.stringify(toWrite, null, 2));
|
|
602622
603491
|
adopted.push({ file, index: arr.length - 1 });
|
|
602623
603492
|
}
|
|
@@ -602662,32 +603531,32 @@ function writeCrontabLines(lines) {
|
|
|
602662
603531
|
}
|
|
602663
603532
|
function canonicalCronLine(rec) {
|
|
602664
603533
|
const oaBin = findOaBinary4();
|
|
602665
|
-
const logDir =
|
|
602666
|
-
const logFile =
|
|
602667
|
-
const storeFile =
|
|
603534
|
+
const logDir = join122(rec.workingDir, ".oa", "scheduled", "logs");
|
|
603535
|
+
const logFile = join122(logDir, `${rec.id}.log`);
|
|
603536
|
+
const storeFile = join122(rec.workingDir, ".oa", "scheduled", "tasks.json");
|
|
602668
603537
|
const taskEsc = rec.task.replace(/'/g, "'\\''");
|
|
602669
|
-
const lockDir =
|
|
602670
|
-
const lockPath =
|
|
603538
|
+
const lockDir = join122(rec.workingDir, ".oa", "run");
|
|
603539
|
+
const lockPath = join122(lockDir, `${rec.id}.lock`);
|
|
602671
603540
|
const wrapper = [
|
|
602672
603541
|
`cd ${JSON.stringify(rec.workingDir)}`,
|
|
602673
603542
|
`mkdir -p ${JSON.stringify(logDir)}`,
|
|
602674
603543
|
`mkdir -p ${JSON.stringify(lockDir)}`,
|
|
602675
603544
|
`if mkdir ${JSON.stringify(lockPath)} 2>/dev/null; then`,
|
|
602676
|
-
` echo $$ > ${JSON.stringify(
|
|
603545
|
+
` echo $$ > ${JSON.stringify(join122(lockPath, "pid"))}`,
|
|
602677
603546
|
` trap 'rm -rf ${lockPath}' EXIT`,
|
|
602678
603547
|
`else`,
|
|
602679
|
-
` if [ -f ${JSON.stringify(
|
|
602680
|
-
` oldpid=$(cat ${JSON.stringify(
|
|
603548
|
+
` if [ -f ${JSON.stringify(join122(lockPath, "pid"))} ]; then`,
|
|
603549
|
+
` oldpid=$(cat ${JSON.stringify(join122(lockPath, "pid"))} 2>/dev/null || echo)`,
|
|
602681
603550
|
` if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then`,
|
|
602682
603551
|
` echo "[oa-scheduler] ${rec.id} already running as PID $oldpid; skipping" >> ${JSON.stringify(logFile)}`,
|
|
602683
603552
|
` exit 0`,
|
|
602684
603553
|
` else`,
|
|
602685
603554
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
602686
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603555
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join122(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
602687
603556
|
` fi`,
|
|
602688
603557
|
` else`,
|
|
602689
603558
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
602690
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603559
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join122(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
602691
603560
|
` fi`,
|
|
602692
603561
|
`fi`,
|
|
602693
603562
|
`${oaBin} '${taskEsc}' >> ${JSON.stringify(logFile)} 2>&1; _oa_exit=$?`,
|
|
@@ -602719,9 +603588,9 @@ function fixupOrMigrateScheduled(mode, dryRun) {
|
|
|
602719
603588
|
try {
|
|
602720
603589
|
if (!f2.workingDir || !f2.task) continue;
|
|
602721
603590
|
const unitBase = `oa-${f2.id}`;
|
|
602722
|
-
const unitDir =
|
|
602723
|
-
const svc =
|
|
602724
|
-
const tim =
|
|
603591
|
+
const unitDir = join122(homedir43(), ".config", "systemd", "user");
|
|
603592
|
+
const svc = join122(unitDir, `${unitBase}.service`);
|
|
603593
|
+
const tim = join122(unitDir, `${unitBase}.timer`);
|
|
602725
603594
|
const oaBin = findOaBinary4();
|
|
602726
603595
|
const rec = { id: f2.id, cron: f2.cron, workingDir: f2.workingDir, task: f2.task };
|
|
602727
603596
|
const cmd = canonicalCronLine(rec).split(" ").slice(5).join(" ");
|
|
@@ -602847,8 +603716,8 @@ function startApiServer(options2 = {}) {
|
|
|
602847
603716
|
const config = loadConfig();
|
|
602848
603717
|
const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
|
|
602849
603718
|
const cwd4 = process.cwd();
|
|
602850
|
-
initAuditLog(
|
|
602851
|
-
initUsageTracker(
|
|
603719
|
+
initAuditLog(join122(cwd4, ".oa"));
|
|
603720
|
+
initUsageTracker(join122(cwd4, ".oa"));
|
|
602852
603721
|
try {
|
|
602853
603722
|
const taskMgr = getSharedTaskManager();
|
|
602854
603723
|
taskMgr.setEventPublisher((type, data, opts) => {
|
|
@@ -602899,7 +603768,7 @@ function startApiServer(options2 = {}) {
|
|
|
602899
603768
|
if (!f2.endsWith(".json") || f2.includes(".tmp.")) continue;
|
|
602900
603769
|
const sid = f2.replace(/\.json$/, "");
|
|
602901
603770
|
try {
|
|
602902
|
-
const items = JSON.parse(
|
|
603771
|
+
const items = JSON.parse(readFileSync86(join122(dir, f2), "utf-8"));
|
|
602903
603772
|
if (Array.isArray(items)) {
|
|
602904
603773
|
cache8.set(sid, new Map(items.map((t2) => [t2.id, t2])));
|
|
602905
603774
|
}
|
|
@@ -602911,10 +603780,10 @@ function startApiServer(options2 = {}) {
|
|
|
602911
603780
|
const watcher = fsWatch3(dir, (_evt, fname) => {
|
|
602912
603781
|
if (!fname || !fname.endsWith(".json") || fname.includes(".tmp.")) return;
|
|
602913
603782
|
const sid = fname.replace(/\.json$/, "");
|
|
602914
|
-
const fp =
|
|
603783
|
+
const fp = join122(dir, fname);
|
|
602915
603784
|
let next = [];
|
|
602916
603785
|
try {
|
|
602917
|
-
if (!
|
|
603786
|
+
if (!existsSync106(fp)) {
|
|
602918
603787
|
const old = cache8.get(sid);
|
|
602919
603788
|
if (old) {
|
|
602920
603789
|
for (const t2 of old.values()) {
|
|
@@ -602927,7 +603796,7 @@ function startApiServer(options2 = {}) {
|
|
|
602927
603796
|
}
|
|
602928
603797
|
return;
|
|
602929
603798
|
}
|
|
602930
|
-
next = JSON.parse(
|
|
603799
|
+
next = JSON.parse(readFileSync86(fp, "utf-8"));
|
|
602931
603800
|
if (!Array.isArray(next)) return;
|
|
602932
603801
|
} catch {
|
|
602933
603802
|
return;
|
|
@@ -602966,14 +603835,14 @@ function startApiServer(options2 = {}) {
|
|
|
602966
603835
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
602967
603836
|
if (retentionDays > 0) {
|
|
602968
603837
|
try {
|
|
602969
|
-
const jobsDir3 =
|
|
602970
|
-
if (
|
|
603838
|
+
const jobsDir3 = join122(cwd4, ".oa", "jobs");
|
|
603839
|
+
if (existsSync106(jobsDir3)) {
|
|
602971
603840
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
602972
603841
|
for (const f2 of readdirSync36(jobsDir3)) {
|
|
602973
603842
|
if (!f2.endsWith(".json")) continue;
|
|
602974
603843
|
try {
|
|
602975
|
-
const jobPath =
|
|
602976
|
-
const job = JSON.parse(
|
|
603844
|
+
const jobPath = join122(jobsDir3, f2);
|
|
603845
|
+
const job = JSON.parse(readFileSync86(jobPath, "utf-8"));
|
|
602977
603846
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
602978
603847
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
602979
603848
|
const { unlinkSync: unlinkSync25 } = require3("node:fs");
|
|
@@ -602993,8 +603862,8 @@ function startApiServer(options2 = {}) {
|
|
|
602993
603862
|
if (useTls) {
|
|
602994
603863
|
try {
|
|
602995
603864
|
tlsOpts = {
|
|
602996
|
-
cert:
|
|
602997
|
-
key:
|
|
603865
|
+
cert: readFileSync86(resolve38(tlsCert)),
|
|
603866
|
+
key: readFileSync86(resolve38(tlsKey))
|
|
602998
603867
|
};
|
|
602999
603868
|
} catch (e2) {
|
|
603000
603869
|
log22(`
|
|
@@ -603005,9 +603874,9 @@ function startApiServer(options2 = {}) {
|
|
|
603005
603874
|
}
|
|
603006
603875
|
let runtimeAccessMode = resolveAccessMode(process.env["OA_ACCESS"], host);
|
|
603007
603876
|
try {
|
|
603008
|
-
const accessFile =
|
|
603009
|
-
if (
|
|
603010
|
-
const persisted =
|
|
603877
|
+
const accessFile = join122(homedir43(), ".open-agents", "access");
|
|
603878
|
+
if (existsSync106(accessFile)) {
|
|
603879
|
+
const persisted = readFileSync86(accessFile, "utf8").trim();
|
|
603011
603880
|
const resolved = resolveAccessMode(persisted, host);
|
|
603012
603881
|
if (resolved) runtimeAccessMode = resolved;
|
|
603013
603882
|
}
|
|
@@ -603060,9 +603929,9 @@ function startApiServer(options2 = {}) {
|
|
|
603060
603929
|
const previous = runtimeAccessMode;
|
|
603061
603930
|
runtimeAccessMode = requested;
|
|
603062
603931
|
try {
|
|
603063
|
-
const dir =
|
|
603932
|
+
const dir = join122(homedir43(), ".open-agents");
|
|
603064
603933
|
mkdirSync63(dir, { recursive: true });
|
|
603065
|
-
writeFileSync55(
|
|
603934
|
+
writeFileSync55(join122(dir, "access"), `${runtimeAccessMode}
|
|
603066
603935
|
`, "utf8");
|
|
603067
603936
|
} catch {
|
|
603068
603937
|
}
|
|
@@ -603275,9 +604144,9 @@ function startApiServer(options2 = {}) {
|
|
|
603275
604144
|
try {
|
|
603276
604145
|
const { startEmbeddingWorkers: startEmbeddingWorkers2 } = await Promise.resolve().then(() => (init_embedding_workers(), embedding_workers_exports));
|
|
603277
604146
|
const { ensureEmbedDeps: ensureEmbedDeps2, runEmbedImage: runEmbedImage2, runEmbedAudio: runEmbedAudio2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
|
|
603278
|
-
const dbBase =
|
|
603279
|
-
const epStore = new mem.EpisodeStore(
|
|
603280
|
-
const kg = new mem.TemporalGraph(
|
|
604147
|
+
const dbBase = join122(cwd4, ".oa");
|
|
604148
|
+
const epStore = new mem.EpisodeStore(join122(dbBase, "memory.db"));
|
|
604149
|
+
const kg = new mem.TemporalGraph(join122(dbBase, "kg.db"));
|
|
603281
604150
|
try {
|
|
603282
604151
|
ensureEmbedDeps2();
|
|
603283
604152
|
} catch {
|
|
@@ -603354,6 +604223,49 @@ function startApiServer(options2 = {}) {
|
|
|
603354
604223
|
`);
|
|
603355
604224
|
log22(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
|
|
603356
604225
|
`);
|
|
604226
|
+
try {
|
|
604227
|
+
const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67, existsSync: _exists, readFileSync: _rfs } = require3("node:fs");
|
|
604228
|
+
const { join: _join } = require3("node:path");
|
|
604229
|
+
const { homedir: _homedir } = require3("node:os");
|
|
604230
|
+
const apiHint = JSON.stringify({
|
|
604231
|
+
port,
|
|
604232
|
+
host: host === "0.0.0.0" ? "127.0.0.1" : host,
|
|
604233
|
+
scheme: proto,
|
|
604234
|
+
pid: process.pid,
|
|
604235
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
604236
|
+
version: version4
|
|
604237
|
+
}, null, 2);
|
|
604238
|
+
const dirSet = /* @__PURE__ */ new Set();
|
|
604239
|
+
try {
|
|
604240
|
+
const regPath = _join(_homedir(), ".open-agents", "nexus-registry.json");
|
|
604241
|
+
if (_exists(regPath)) {
|
|
604242
|
+
const reg = JSON.parse(_rfs(regPath, "utf-8"));
|
|
604243
|
+
for (const e2 of reg?.dirs || []) {
|
|
604244
|
+
const d2 = typeof e2 === "string" ? e2 : e2?.dir;
|
|
604245
|
+
if (typeof d2 === "string") dirSet.add(d2);
|
|
604246
|
+
}
|
|
604247
|
+
}
|
|
604248
|
+
} catch {
|
|
604249
|
+
}
|
|
604250
|
+
if (process.env["OA_NEXUS_DIR"]) dirSet.add(process.env["OA_NEXUS_DIR"]);
|
|
604251
|
+
dirSet.add(_join(process.cwd(), ".oa", "nexus"));
|
|
604252
|
+
dirSet.add(_join(_homedir(), ".oa", "nexus"));
|
|
604253
|
+
dirSet.add(_join(_homedir(), ".open-agents", "nexus"));
|
|
604254
|
+
let written = 0;
|
|
604255
|
+
for (const dir of dirSet) {
|
|
604256
|
+
try {
|
|
604257
|
+
if (!_exists(dir)) mkdirSync67(dir, { recursive: true });
|
|
604258
|
+
writeFileSync59(_join(dir, "api-port.json"), apiHint);
|
|
604259
|
+
written++;
|
|
604260
|
+
} catch {
|
|
604261
|
+
}
|
|
604262
|
+
}
|
|
604263
|
+
if (written > 0) log22(` api-port hint: wrote to ${written} nexus dir(s)
|
|
604264
|
+
`);
|
|
604265
|
+
} catch (e2) {
|
|
604266
|
+
log22(` WARN: api-port hint write failed: ${e2.message}
|
|
604267
|
+
`);
|
|
604268
|
+
}
|
|
603357
604269
|
try {
|
|
603358
604270
|
adoptHandoffRuns();
|
|
603359
604271
|
} catch (e2) {
|
|
@@ -603587,10 +604499,10 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
603587
604499
|
const labels = Array.isArray(b.labels) ? b.labels : [];
|
|
603588
604500
|
const mediaPath = typeof b.media_path === "string" ? b.media_path : void 0;
|
|
603589
604501
|
const cwd4 = process.cwd();
|
|
603590
|
-
const dbBase =
|
|
604502
|
+
const dbBase = join122(cwd4, ".oa");
|
|
603591
604503
|
const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
603592
|
-
const epStore = new EpisodeStore3(
|
|
603593
|
-
const kg = new TemporalGraph3(
|
|
604504
|
+
const epStore = new EpisodeStore3(join122(dbBase, "memory.db"));
|
|
604505
|
+
const kg = new TemporalGraph3(join122(dbBase, "kg.db"));
|
|
603594
604506
|
const meta = {};
|
|
603595
604507
|
if (mediaPath) meta.media_path = mediaPath;
|
|
603596
604508
|
const epId = epStore.insert({ modality, content: content || (mediaPath || ""), metadata: meta, toolName: "memory_ingest" });
|
|
@@ -603657,7 +604569,7 @@ async function handleEntitiesList(req2, res) {
|
|
|
603657
604569
|
const type = url.searchParams.get("type") || "person";
|
|
603658
604570
|
const limit = Math.max(1, Math.min(1e3, parseInt(url.searchParams.get("limit") || "100", 10)));
|
|
603659
604571
|
const { TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
603660
|
-
const kg = new TemporalGraph3(
|
|
604572
|
+
const kg = new TemporalGraph3(join122(process.cwd(), ".oa", "kg.db"));
|
|
603661
604573
|
const nodes = kg.nodesByType(type, limit).map((n2) => ({ id: n2.id, text: n2.text, mentionCount: n2.mentionCount, firstSeen: n2.firstSeen, lastSeen: n2.lastSeen }));
|
|
603662
604574
|
jsonResponse(res, 200, { object: "list", data: nodes });
|
|
603663
604575
|
} catch (err) {
|
|
@@ -603679,7 +604591,7 @@ async function handleMemorySearch2(req2, res) {
|
|
|
603679
604591
|
const wLex = typeof b.lexical_weight === "number" ? b.lexical_weight : 1;
|
|
603680
604592
|
const wEmb = typeof b.embedding_weight === "number" ? b.embedding_weight : 1;
|
|
603681
604593
|
const { EpisodeStore: EpisodeStore3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
603682
|
-
const epStore = new EpisodeStore3(
|
|
604594
|
+
const epStore = new EpisodeStore3(join122(process.cwd(), ".oa", "memory.db"));
|
|
603683
604595
|
const results = epStore.search({ query, modality, limit }, { queryEmbedding: qEmb, lexicalWeight: wLex, embeddingWeight: wEmb });
|
|
603684
604596
|
jsonResponse(res, 200, { object: "list", data: results.map((e2) => ({ id: e2.id, modality: e2.modality, content: e2.content, timestamp: e2.timestamp })) });
|
|
603685
604597
|
} catch (err) {
|
|
@@ -603796,13 +604708,13 @@ var init_serve = __esm({
|
|
|
603796
604708
|
|
|
603797
604709
|
// packages/cli/src/tui/interactive.ts
|
|
603798
604710
|
import { cwd } from "node:process";
|
|
603799
|
-
import { resolve as resolve39, join as
|
|
604711
|
+
import { resolve as resolve39, join as join123, dirname as dirname37, extname as extname12 } from "node:path";
|
|
603800
604712
|
import { createRequire as createRequire6 } from "node:module";
|
|
603801
604713
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
603802
|
-
import { readFileSync as
|
|
603803
|
-
import { existsSync as
|
|
604714
|
+
import { readFileSync as readFileSync87, writeFileSync as writeFileSync56, appendFileSync as appendFileSync8, rmSync as rmSync5, readdirSync as readdirSync37, mkdirSync as mkdirSync64 } from "node:fs";
|
|
604715
|
+
import { existsSync as existsSync107 } from "node:fs";
|
|
603804
604716
|
import { execSync as execSync58 } from "node:child_process";
|
|
603805
|
-
import { homedir as
|
|
604717
|
+
import { homedir as homedir44 } from "node:os";
|
|
603806
604718
|
function formatTimeAgo2(date) {
|
|
603807
604719
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
603808
604720
|
if (seconds < 60) return "just now";
|
|
@@ -603818,12 +604730,12 @@ function getVersion4() {
|
|
|
603818
604730
|
const require4 = createRequire6(import.meta.url);
|
|
603819
604731
|
const thisDir = dirname37(fileURLToPath18(import.meta.url));
|
|
603820
604732
|
const candidates = [
|
|
603821
|
-
|
|
603822
|
-
|
|
603823
|
-
|
|
604733
|
+
join123(thisDir, "..", "package.json"),
|
|
604734
|
+
join123(thisDir, "..", "..", "package.json"),
|
|
604735
|
+
join123(thisDir, "..", "..", "..", "package.json")
|
|
603824
604736
|
];
|
|
603825
604737
|
for (const pkgPath of candidates) {
|
|
603826
|
-
if (
|
|
604738
|
+
if (existsSync107(pkgPath)) {
|
|
603827
604739
|
const pkg = require4(pkgPath);
|
|
603828
604740
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
603829
604741
|
return pkg.version ?? "0.0.0";
|
|
@@ -604629,14 +605541,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
|
|
|
604629
605541
|
function gatherMemorySnippets(root) {
|
|
604630
605542
|
const snippets = [];
|
|
604631
605543
|
const dirs = [
|
|
604632
|
-
|
|
604633
|
-
|
|
605544
|
+
join123(root, ".oa", "memory"),
|
|
605545
|
+
join123(root, ".open-agents", "memory")
|
|
604634
605546
|
];
|
|
604635
605547
|
for (const dir of dirs) {
|
|
604636
|
-
if (!
|
|
605548
|
+
if (!existsSync107(dir)) continue;
|
|
604637
605549
|
try {
|
|
604638
605550
|
for (const f2 of readdirSync37(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
604639
|
-
const data = JSON.parse(
|
|
605551
|
+
const data = JSON.parse(readFileSync87(join123(dir, f2), "utf-8"));
|
|
604640
605552
|
for (const val of Object.values(data)) {
|
|
604641
605553
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
604642
605554
|
if (v.length > 10) snippets.push(v);
|
|
@@ -604790,9 +605702,9 @@ ${metabolismMemories}
|
|
|
604790
605702
|
} catch {
|
|
604791
605703
|
}
|
|
604792
605704
|
try {
|
|
604793
|
-
const archeFile =
|
|
604794
|
-
if (
|
|
604795
|
-
const variants = JSON.parse(
|
|
605705
|
+
const archeFile = join123(repoRoot, ".oa", "arche", "variants.json");
|
|
605706
|
+
if (existsSync107(archeFile)) {
|
|
605707
|
+
const variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
604796
605708
|
if (variants.length > 0) {
|
|
604797
605709
|
let filtered = variants;
|
|
604798
605710
|
if (taskType) {
|
|
@@ -604964,9 +605876,9 @@ RULES:
|
|
|
604964
605876
|
const compactionThreshold = Number.isFinite(envOverride) && envOverride > 0 ? envOverride : modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
604965
605877
|
let identityInjection = "";
|
|
604966
605878
|
try {
|
|
604967
|
-
const ikStateFile =
|
|
604968
|
-
if (
|
|
604969
|
-
const selfState = JSON.parse(
|
|
605879
|
+
const ikStateFile = join123(repoRoot, ".oa", "identity", "self-state.json");
|
|
605880
|
+
if (existsSync107(ikStateFile)) {
|
|
605881
|
+
const selfState = JSON.parse(readFileSync87(ikStateFile, "utf8"));
|
|
604970
605882
|
const lines = [
|
|
604971
605883
|
`[Identity State v${selfState.version}]`,
|
|
604972
605884
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -605828,11 +606740,11 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
605828
606740
|
});
|
|
605829
606741
|
}
|
|
605830
606742
|
try {
|
|
605831
|
-
const ikDir =
|
|
605832
|
-
const ikFile =
|
|
606743
|
+
const ikDir = join123(repoRoot, ".oa", "identity");
|
|
606744
|
+
const ikFile = join123(ikDir, "self-state.json");
|
|
605833
606745
|
let ikState;
|
|
605834
|
-
if (
|
|
605835
|
-
ikState = JSON.parse(
|
|
606746
|
+
if (existsSync107(ikFile)) {
|
|
606747
|
+
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
605836
606748
|
} else {
|
|
605837
606749
|
mkdirSync64(ikDir, { recursive: true });
|
|
605838
606750
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
@@ -605909,9 +606821,9 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
605909
606821
|
} else {
|
|
605910
606822
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
605911
606823
|
try {
|
|
605912
|
-
const ikFile =
|
|
605913
|
-
if (
|
|
605914
|
-
const ikState = JSON.parse(
|
|
606824
|
+
const ikFile = join123(repoRoot, ".oa", "identity", "self-state.json");
|
|
606825
|
+
if (existsSync107(ikFile)) {
|
|
606826
|
+
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
605915
606827
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
605916
606828
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
605917
606829
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.03);
|
|
@@ -606167,10 +607079,10 @@ async function startInteractive(config, repoPath) {
|
|
|
606167
607079
|
process.stdin.pause();
|
|
606168
607080
|
}
|
|
606169
607081
|
try {
|
|
606170
|
-
const oaDir =
|
|
606171
|
-
const nexusPidFile =
|
|
606172
|
-
if (
|
|
606173
|
-
const pid = parseInt(
|
|
607082
|
+
const oaDir = join123(repoRoot, ".oa");
|
|
607083
|
+
const nexusPidFile = join123(oaDir, "nexus", "daemon.pid");
|
|
607084
|
+
if (existsSync107(nexusPidFile)) {
|
|
607085
|
+
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
606174
607086
|
if (pid > 0) {
|
|
606175
607087
|
try {
|
|
606176
607088
|
process.kill(pid, 0);
|
|
@@ -606830,7 +607742,7 @@ ${result.summary}`
|
|
|
606830
607742
|
let p2pGateway = null;
|
|
606831
607743
|
let peerMesh = null;
|
|
606832
607744
|
let inferenceRouter = null;
|
|
606833
|
-
const secretVault = new SecretVault(
|
|
607745
|
+
const secretVault = new SecretVault(join123(repoRoot, ".oa", "vault.enc"));
|
|
606834
607746
|
let adminSessionKey = null;
|
|
606835
607747
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
606836
607748
|
const streamRenderer = new StreamRenderer();
|
|
@@ -607061,13 +607973,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607061
607973
|
const hits = allCompletions.filter((c9) => c9.toLowerCase().startsWith(lower));
|
|
607062
607974
|
return [hits, line];
|
|
607063
607975
|
}
|
|
607064
|
-
const HISTORY_DIR =
|
|
607065
|
-
const HISTORY_FILE =
|
|
607976
|
+
const HISTORY_DIR = join123(homedir44(), ".open-agents");
|
|
607977
|
+
const HISTORY_FILE = join123(HISTORY_DIR, "repl-history");
|
|
607066
607978
|
const MAX_HISTORY_LINES = 500;
|
|
607067
607979
|
let savedHistory = [];
|
|
607068
607980
|
try {
|
|
607069
|
-
if (
|
|
607070
|
-
const raw =
|
|
607981
|
+
if (existsSync107(HISTORY_FILE)) {
|
|
607982
|
+
const raw = readFileSync87(HISTORY_FILE, "utf8").trim();
|
|
607071
607983
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
607072
607984
|
}
|
|
607073
607985
|
} catch {
|
|
@@ -607217,7 +608129,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607217
608129
|
mkdirSync64(HISTORY_DIR, { recursive: true });
|
|
607218
608130
|
appendFileSync8(HISTORY_FILE, line + "\n", "utf8");
|
|
607219
608131
|
if (Math.random() < 0.02) {
|
|
607220
|
-
const all2 =
|
|
608132
|
+
const all2 = readFileSync87(HISTORY_FILE, "utf8").trim().split("\n");
|
|
607221
608133
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
607222
608134
|
writeFileSync56(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
607223
608135
|
}
|
|
@@ -607404,10 +608316,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607404
608316
|
const { unlinkSync: _rmStale } = await import("node:fs");
|
|
607405
608317
|
const { homedir: _hdir } = await import("node:os");
|
|
607406
608318
|
for (const dp of [
|
|
607407
|
-
|
|
607408
|
-
|
|
608319
|
+
join123(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
608320
|
+
join123(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
607409
608321
|
]) {
|
|
607410
|
-
if (
|
|
608322
|
+
if (existsSync107(dp)) try {
|
|
607411
608323
|
_rmStale(dp);
|
|
607412
608324
|
} catch {
|
|
607413
608325
|
}
|
|
@@ -607418,9 +608330,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607418
608330
|
const autoNexus = new NexusTool(repoRoot);
|
|
607419
608331
|
const _registerNexusDaemon = () => {
|
|
607420
608332
|
try {
|
|
607421
|
-
const nexusPidFile =
|
|
607422
|
-
if (
|
|
607423
|
-
const nPid = parseInt(
|
|
608333
|
+
const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
608334
|
+
if (existsSync107(nexusPidFile)) {
|
|
608335
|
+
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
607424
608336
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
607425
608337
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
607426
608338
|
statusBar.ensureMonitorTimer();
|
|
@@ -607477,7 +608389,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607477
608389
|
} catch {
|
|
607478
608390
|
}
|
|
607479
608391
|
try {
|
|
607480
|
-
const oaDir =
|
|
608392
|
+
const oaDir = join123(repoRoot, ".oa");
|
|
607481
608393
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
607482
608394
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
607483
608395
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -607509,7 +608421,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607509
608421
|
} catch {
|
|
607510
608422
|
}
|
|
607511
608423
|
try {
|
|
607512
|
-
const oaDir =
|
|
608424
|
+
const oaDir = join123(repoRoot, ".oa");
|
|
607513
608425
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
607514
608426
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
607515
608427
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -607550,10 +608462,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607550
608462
|
}
|
|
607551
608463
|
try {
|
|
607552
608464
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
607553
|
-
const globalNamePath =
|
|
608465
|
+
const globalNamePath = join123(_hd(), ".open-agents", "agent-name");
|
|
607554
608466
|
let agName = "";
|
|
607555
608467
|
try {
|
|
607556
|
-
if (
|
|
608468
|
+
if (existsSync107(globalNamePath)) agName = readFileSync87(globalNamePath, "utf8").trim();
|
|
607557
608469
|
} catch {
|
|
607558
608470
|
}
|
|
607559
608471
|
if (!agName) {
|
|
@@ -607582,11 +608494,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607582
608494
|
}
|
|
607583
608495
|
if (!ollamaAlive) {
|
|
607584
608496
|
try {
|
|
607585
|
-
const savedSponsorsPath =
|
|
608497
|
+
const savedSponsorsPath = join123(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
607586
608498
|
let savedSponsors = [];
|
|
607587
608499
|
try {
|
|
607588
|
-
if (
|
|
607589
|
-
savedSponsors = JSON.parse(
|
|
608500
|
+
if (existsSync107(savedSponsorsPath)) {
|
|
608501
|
+
savedSponsors = JSON.parse(readFileSync87(savedSponsorsPath, "utf8"));
|
|
607590
608502
|
const oneHourAgo = Date.now() - 36e5;
|
|
607591
608503
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
607592
608504
|
}
|
|
@@ -608678,10 +609590,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
608678
609590
|
if (name10 === "voice_list_files") {
|
|
608679
609591
|
const baseDir = String(args?.dir ?? ".");
|
|
608680
609592
|
const { readdirSync: readdirSync39, statSync: statSync36 } = __require("node:fs");
|
|
608681
|
-
const { join:
|
|
608682
|
-
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(
|
|
609593
|
+
const { join: join128, resolve: resolve43 } = __require("node:path");
|
|
609594
|
+
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(join128(repoRoot, baseDir));
|
|
608683
609595
|
const items = readdirSync39(base3).slice(0, 200).map((f2) => {
|
|
608684
|
-
const s2 = statSync36(
|
|
609596
|
+
const s2 = statSync36(join128(base3, f2));
|
|
608685
609597
|
return { name: f2, dir: s2.isDirectory(), size: s2.size };
|
|
608686
609598
|
});
|
|
608687
609599
|
return JSON.stringify({ dir: base3, items }, null, 2);
|
|
@@ -608769,7 +609681,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
608769
609681
|
kind,
|
|
608770
609682
|
targetUrl,
|
|
608771
609683
|
authKey,
|
|
608772
|
-
stateDir:
|
|
609684
|
+
stateDir: join123(repoRoot, ".oa"),
|
|
608773
609685
|
passthrough: passthrough ?? false,
|
|
608774
609686
|
loadbalance: loadbalance ?? false,
|
|
608775
609687
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -608815,7 +609727,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
608815
609727
|
await tunnelGateway.stop();
|
|
608816
609728
|
tunnelGateway = null;
|
|
608817
609729
|
}
|
|
608818
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
609730
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join123(repoRoot, ".oa") });
|
|
608819
609731
|
newTunnel.on("stats", (stats) => {
|
|
608820
609732
|
statusBar.setExposeStatus({
|
|
608821
609733
|
status: stats.status,
|
|
@@ -608902,9 +609814,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
608902
609814
|
});
|
|
608903
609815
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
608904
609816
|
try {
|
|
608905
|
-
const nexusPidFile =
|
|
608906
|
-
if (
|
|
608907
|
-
const pid = parseInt(
|
|
609817
|
+
const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
609818
|
+
if (existsSync107(nexusPidFile)) {
|
|
609819
|
+
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
608908
609820
|
if (pid > 0) {
|
|
608909
609821
|
registry2.register({
|
|
608910
609822
|
name: "Nexus",
|
|
@@ -609092,10 +610004,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609092
610004
|
writeContent(() => renderInfo2(`Killed ${bgKilled} background task(s).`));
|
|
609093
610005
|
}
|
|
609094
610006
|
try {
|
|
609095
|
-
const nexusDir =
|
|
609096
|
-
const pidFile =
|
|
609097
|
-
if (
|
|
609098
|
-
const pid = parseInt(
|
|
610007
|
+
const nexusDir = join123(repoRoot, OA_DIR, "nexus");
|
|
610008
|
+
const pidFile = join123(nexusDir, "daemon.pid");
|
|
610009
|
+
if (existsSync107(pidFile)) {
|
|
610010
|
+
const pid = parseInt(readFileSync87(pidFile, "utf8").trim(), 10);
|
|
609099
610011
|
if (pid > 0) {
|
|
609100
610012
|
try {
|
|
609101
610013
|
if (process.platform === "win32") {
|
|
@@ -609117,13 +610029,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609117
610029
|
} catch {
|
|
609118
610030
|
}
|
|
609119
610031
|
try {
|
|
609120
|
-
const voiceDir2 =
|
|
610032
|
+
const voiceDir2 = join123(homedir44(), ".open-agents", "voice");
|
|
609121
610033
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
609122
610034
|
for (const pf of voicePidFiles) {
|
|
609123
|
-
const pidPath =
|
|
609124
|
-
if (
|
|
610035
|
+
const pidPath = join123(voiceDir2, pf);
|
|
610036
|
+
if (existsSync107(pidPath)) {
|
|
609125
610037
|
try {
|
|
609126
|
-
const pid = parseInt(
|
|
610038
|
+
const pid = parseInt(readFileSync87(pidPath, "utf8").trim(), 10);
|
|
609127
610039
|
if (pid > 0) {
|
|
609128
610040
|
if (process.platform === "win32") {
|
|
609129
610041
|
try {
|
|
@@ -609147,8 +610059,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609147
610059
|
execSync58(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
609148
610060
|
} catch {
|
|
609149
610061
|
}
|
|
609150
|
-
const oaPath =
|
|
609151
|
-
if (
|
|
610062
|
+
const oaPath = join123(repoRoot, OA_DIR);
|
|
610063
|
+
if (existsSync107(oaPath)) {
|
|
609152
610064
|
let deleted = false;
|
|
609153
610065
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
609154
610066
|
try {
|
|
@@ -609232,19 +610144,19 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609232
610144
|
try {
|
|
609233
610145
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
609234
610146
|
if (isPersonaPlexRunning2()) {
|
|
609235
|
-
const ppPidFile =
|
|
609236
|
-
const ppPortFile =
|
|
609237
|
-
if (
|
|
609238
|
-
const ppPid = parseInt(
|
|
609239
|
-
const ppPort =
|
|
610147
|
+
const ppPidFile = join123(homedir44(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
610148
|
+
const ppPortFile = join123(homedir44(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
610149
|
+
if (existsSync107(ppPidFile)) {
|
|
610150
|
+
const ppPid = parseInt(readFileSync87(ppPidFile, "utf8").trim(), 10);
|
|
610151
|
+
const ppPort = existsSync107(ppPortFile) ? parseInt(readFileSync87(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
609240
610152
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
609241
610153
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
609242
610154
|
}
|
|
609243
610155
|
}
|
|
609244
610156
|
}
|
|
609245
|
-
const nexusPidFile =
|
|
609246
|
-
if (
|
|
609247
|
-
const nPid = parseInt(
|
|
610157
|
+
const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
610158
|
+
if (existsSync107(nexusPidFile)) {
|
|
610159
|
+
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
609248
610160
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
609249
610161
|
try {
|
|
609250
610162
|
process.kill(nPid, 0);
|
|
@@ -609611,9 +610523,9 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
609611
610523
|
}
|
|
609612
610524
|
}
|
|
609613
610525
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
609614
|
-
const isImage = isImagePath(cleanPath) &&
|
|
609615
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
609616
|
-
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) &&
|
|
610526
|
+
const isImage = isImagePath(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
|
|
610527
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
|
|
610528
|
+
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
|
|
609617
610529
|
if (activeTask) {
|
|
609618
610530
|
if (activeTask.runner.isPaused) {
|
|
609619
610531
|
activeTask.runner.resume();
|
|
@@ -609622,7 +610534,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
609622
610534
|
if (isImage) {
|
|
609623
610535
|
try {
|
|
609624
610536
|
const imgPath = resolve39(repoRoot, cleanPath);
|
|
609625
|
-
const imgBuffer =
|
|
610537
|
+
const imgBuffer = readFileSync87(imgPath);
|
|
609626
610538
|
const base642 = imgBuffer.toString("base64");
|
|
609627
610539
|
const ext = extname12(cleanPath).toLowerCase();
|
|
609628
610540
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -609778,7 +610690,7 @@ ${result.text}`;
|
|
|
609778
610690
|
if (isMarkdown && fullInput === input) {
|
|
609779
610691
|
try {
|
|
609780
610692
|
const mdPath = resolve39(repoRoot, cleanPath);
|
|
609781
|
-
const mdContent =
|
|
610693
|
+
const mdContent = readFileSync87(mdPath, "utf8");
|
|
609782
610694
|
const { parseMcpMarkdown: parseMcpMarkdown2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
609783
610695
|
const result = parseMcpMarkdown2(mdContent);
|
|
609784
610696
|
if (result.servers.length > 0) {
|
|
@@ -610200,11 +611112,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
610200
611112
|
const handle2 = startTask(task, config, repoRoot);
|
|
610201
611113
|
await handle2.promise;
|
|
610202
611114
|
try {
|
|
610203
|
-
const ikDir =
|
|
610204
|
-
const ikFile =
|
|
611115
|
+
const ikDir = join123(repoRoot, ".oa", "identity");
|
|
611116
|
+
const ikFile = join123(ikDir, "self-state.json");
|
|
610205
611117
|
let ikState;
|
|
610206
|
-
if (
|
|
610207
|
-
ikState = JSON.parse(
|
|
611118
|
+
if (existsSync107(ikFile)) {
|
|
611119
|
+
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
610208
611120
|
} else {
|
|
610209
611121
|
mkdirSync64(ikDir, { recursive: true });
|
|
610210
611122
|
ikState = {
|
|
@@ -610241,11 +611153,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
610241
611153
|
);
|
|
610242
611154
|
} catch {
|
|
610243
611155
|
try {
|
|
610244
|
-
const archeDir =
|
|
610245
|
-
const archeFile =
|
|
611156
|
+
const archeDir = join123(repoRoot, ".oa", "arche");
|
|
611157
|
+
const archeFile = join123(archeDir, "variants.json");
|
|
610246
611158
|
let variants = [];
|
|
610247
611159
|
try {
|
|
610248
|
-
if (
|
|
611160
|
+
if (existsSync107(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
610249
611161
|
} catch {
|
|
610250
611162
|
}
|
|
610251
611163
|
variants.push({
|
|
@@ -610265,9 +611177,9 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
610265
611177
|
}
|
|
610266
611178
|
}
|
|
610267
611179
|
try {
|
|
610268
|
-
const metaFile =
|
|
610269
|
-
if (
|
|
610270
|
-
const store2 = JSON.parse(
|
|
611180
|
+
const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611181
|
+
if (existsSync107(metaFile)) {
|
|
611182
|
+
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
610271
611183
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
610272
611184
|
let updated = false;
|
|
610273
611185
|
for (const item of surfaced) {
|
|
@@ -610331,9 +611243,9 @@ Rules:
|
|
|
610331
611243
|
try {
|
|
610332
611244
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
610333
611245
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
610334
|
-
const dbDir =
|
|
611246
|
+
const dbDir = join123(repoRoot, ".oa", "memory");
|
|
610335
611247
|
mkdirSync64(dbDir, { recursive: true });
|
|
610336
|
-
const db = initDb2(
|
|
611248
|
+
const db = initDb2(join123(dbDir, "structured.db"));
|
|
610337
611249
|
const memStore = new ProceduralMemoryStore2(db);
|
|
610338
611250
|
memStore.createWithEmbedding({
|
|
610339
611251
|
content: content.slice(0, 600),
|
|
@@ -610348,11 +611260,11 @@ Rules:
|
|
|
610348
611260
|
db.close();
|
|
610349
611261
|
} catch {
|
|
610350
611262
|
}
|
|
610351
|
-
const metaDir =
|
|
610352
|
-
const storeFile =
|
|
611263
|
+
const metaDir = join123(repoRoot, ".oa", "memory", "metabolism");
|
|
611264
|
+
const storeFile = join123(metaDir, "store.json");
|
|
610353
611265
|
let store2 = [];
|
|
610354
611266
|
try {
|
|
610355
|
-
if (
|
|
611267
|
+
if (existsSync107(storeFile)) store2 = JSON.parse(readFileSync87(storeFile, "utf8"));
|
|
610356
611268
|
} catch {
|
|
610357
611269
|
}
|
|
610358
611270
|
store2.push({
|
|
@@ -610374,19 +611286,19 @@ Rules:
|
|
|
610374
611286
|
} catch {
|
|
610375
611287
|
}
|
|
610376
611288
|
try {
|
|
610377
|
-
const cohereSettingsFile =
|
|
611289
|
+
const cohereSettingsFile = join123(repoRoot, ".oa", "settings.json");
|
|
610378
611290
|
let cohereActive = false;
|
|
610379
611291
|
try {
|
|
610380
|
-
if (
|
|
610381
|
-
const settings = JSON.parse(
|
|
611292
|
+
if (existsSync107(cohereSettingsFile)) {
|
|
611293
|
+
const settings = JSON.parse(readFileSync87(cohereSettingsFile, "utf8"));
|
|
610382
611294
|
cohereActive = settings.cohere === true;
|
|
610383
611295
|
}
|
|
610384
611296
|
} catch {
|
|
610385
611297
|
}
|
|
610386
611298
|
if (cohereActive) {
|
|
610387
|
-
const metaFile =
|
|
610388
|
-
if (
|
|
610389
|
-
const store2 = JSON.parse(
|
|
611299
|
+
const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611300
|
+
if (existsSync107(metaFile)) {
|
|
611301
|
+
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
610390
611302
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
610391
611303
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
610392
611304
|
try {
|
|
@@ -610411,18 +611323,18 @@ Rules:
|
|
|
610411
611323
|
}
|
|
610412
611324
|
} catch (err) {
|
|
610413
611325
|
try {
|
|
610414
|
-
const ikFile =
|
|
610415
|
-
if (
|
|
610416
|
-
const ikState = JSON.parse(
|
|
611326
|
+
const ikFile = join123(repoRoot, ".oa", "identity", "self-state.json");
|
|
611327
|
+
if (existsSync107(ikFile)) {
|
|
611328
|
+
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
610417
611329
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
610418
611330
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
610419
611331
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
610420
611332
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
610421
611333
|
writeFileSync56(ikFile, JSON.stringify(ikState, null, 2));
|
|
610422
611334
|
}
|
|
610423
|
-
const metaFile =
|
|
610424
|
-
if (
|
|
610425
|
-
const store2 = JSON.parse(
|
|
611335
|
+
const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611336
|
+
if (existsSync107(metaFile)) {
|
|
611337
|
+
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
610426
611338
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
610427
611339
|
for (const item of surfaced) {
|
|
610428
611340
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -610433,11 +611345,11 @@ Rules:
|
|
|
610433
611345
|
writeFileSync56(metaFile, JSON.stringify(store2, null, 2));
|
|
610434
611346
|
}
|
|
610435
611347
|
try {
|
|
610436
|
-
const archeDir =
|
|
610437
|
-
const archeFile =
|
|
611348
|
+
const archeDir = join123(repoRoot, ".oa", "arche");
|
|
611349
|
+
const archeFile = join123(archeDir, "variants.json");
|
|
610438
611350
|
let variants = [];
|
|
610439
611351
|
try {
|
|
610440
|
-
if (
|
|
611352
|
+
if (existsSync107(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
610441
611353
|
} catch {
|
|
610442
611354
|
}
|
|
610443
611355
|
variants.push({
|
|
@@ -610541,12 +611453,12 @@ __export(run_exports, {
|
|
|
610541
611453
|
});
|
|
610542
611454
|
import { resolve as resolve40 } from "node:path";
|
|
610543
611455
|
import { spawn as spawn26 } from "node:child_process";
|
|
610544
|
-
import { mkdirSync as mkdirSync65, writeFileSync as writeFileSync57, readFileSync as
|
|
611456
|
+
import { mkdirSync as mkdirSync65, writeFileSync as writeFileSync57, readFileSync as readFileSync88, readdirSync as readdirSync38, existsSync as existsSync108 } from "node:fs";
|
|
610545
611457
|
import { randomBytes as randomBytes24 } from "node:crypto";
|
|
610546
|
-
import { join as
|
|
611458
|
+
import { join as join124 } from "node:path";
|
|
610547
611459
|
function jobsDir2(repoPath) {
|
|
610548
611460
|
const root = resolve40(repoPath ?? process.cwd());
|
|
610549
|
-
const dir =
|
|
611461
|
+
const dir = join124(root, ".oa", "jobs");
|
|
610550
611462
|
mkdirSync65(dir, { recursive: true });
|
|
610551
611463
|
return dir;
|
|
610552
611464
|
}
|
|
@@ -610669,7 +611581,7 @@ async function runBackground(task, config, opts) {
|
|
|
610669
611581
|
}
|
|
610670
611582
|
});
|
|
610671
611583
|
job.pid = child.pid ?? 0;
|
|
610672
|
-
writeFileSync57(
|
|
611584
|
+
writeFileSync57(join124(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
610673
611585
|
let output = "";
|
|
610674
611586
|
child.stdout?.on("data", (chunk) => {
|
|
610675
611587
|
output += chunk.toString();
|
|
@@ -610685,7 +611597,7 @@ async function runBackground(task, config, opts) {
|
|
|
610685
611597
|
job.summary = result.summary;
|
|
610686
611598
|
job.durationMs = result.durationMs;
|
|
610687
611599
|
job.error = result.error;
|
|
610688
|
-
writeFileSync57(
|
|
611600
|
+
writeFileSync57(join124(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
610689
611601
|
} catch {
|
|
610690
611602
|
}
|
|
610691
611603
|
});
|
|
@@ -610701,13 +611613,13 @@ async function runBackground(task, config, opts) {
|
|
|
610701
611613
|
}
|
|
610702
611614
|
function statusCommand(jobId, repoPath) {
|
|
610703
611615
|
const dir = jobsDir2(repoPath);
|
|
610704
|
-
const file =
|
|
610705
|
-
if (!
|
|
611616
|
+
const file = join124(dir, `${jobId}.json`);
|
|
611617
|
+
if (!existsSync108(file)) {
|
|
610706
611618
|
console.error(`Job not found: ${jobId}`);
|
|
610707
611619
|
console.log(`Available jobs: oa jobs`);
|
|
610708
611620
|
process.exit(1);
|
|
610709
611621
|
}
|
|
610710
|
-
const job = JSON.parse(
|
|
611622
|
+
const job = JSON.parse(readFileSync88(file, "utf-8"));
|
|
610711
611623
|
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
610712
611624
|
const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
|
|
610713
611625
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -610728,7 +611640,7 @@ function jobsCommand(repoPath) {
|
|
|
610728
611640
|
console.log("Jobs:");
|
|
610729
611641
|
for (const file of files) {
|
|
610730
611642
|
try {
|
|
610731
|
-
const job = JSON.parse(
|
|
611643
|
+
const job = JSON.parse(readFileSync88(join124(dir, file), "utf-8"));
|
|
610732
611644
|
const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
|
|
610733
611645
|
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
610734
611646
|
const cleanListTask = cleanForStorage(job.task) || job.task;
|
|
@@ -610752,13 +611664,13 @@ __export(index_repo_exports, {
|
|
|
610752
611664
|
indexRepoCommand: () => indexRepoCommand
|
|
610753
611665
|
});
|
|
610754
611666
|
import { resolve as resolve41 } from "node:path";
|
|
610755
|
-
import { existsSync as
|
|
611667
|
+
import { existsSync as existsSync109, statSync as statSync35 } from "node:fs";
|
|
610756
611668
|
import { cwd as cwd2 } from "node:process";
|
|
610757
611669
|
async function indexRepoCommand(opts, _config3) {
|
|
610758
611670
|
const repoRoot = resolve41(opts.repoPath ?? cwd2());
|
|
610759
611671
|
printHeader("Index Repository");
|
|
610760
611672
|
printInfo(`Indexing: ${repoRoot}`);
|
|
610761
|
-
if (!
|
|
611673
|
+
if (!existsSync109(repoRoot)) {
|
|
610762
611674
|
printError(`Path does not exist: ${repoRoot}`);
|
|
610763
611675
|
process.exit(1);
|
|
610764
611676
|
}
|
|
@@ -611010,8 +611922,8 @@ var config_exports2 = {};
|
|
|
611010
611922
|
__export(config_exports2, {
|
|
611011
611923
|
configCommand: () => configCommand
|
|
611012
611924
|
});
|
|
611013
|
-
import { join as
|
|
611014
|
-
import { homedir as
|
|
611925
|
+
import { join as join125, resolve as resolve42 } from "node:path";
|
|
611926
|
+
import { homedir as homedir45 } from "node:os";
|
|
611015
611927
|
import { cwd as cwd3 } from "node:process";
|
|
611016
611928
|
function redactIfSensitive(key, value2) {
|
|
611017
611929
|
if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
|
|
@@ -611092,7 +612004,7 @@ function handleShow(opts, config) {
|
|
|
611092
612004
|
}
|
|
611093
612005
|
}
|
|
611094
612006
|
printSection("Config File");
|
|
611095
|
-
printInfo(`~/.open-agents/config.json (${
|
|
612007
|
+
printInfo(`~/.open-agents/config.json (${join125(homedir45(), ".open-agents", "config.json")})`);
|
|
611096
612008
|
printSection("Priority Chain");
|
|
611097
612009
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
611098
612010
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -611131,7 +612043,7 @@ function handleSet(opts, _config3) {
|
|
|
611131
612043
|
const coerced = coerceForSettings(key, value2);
|
|
611132
612044
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
611133
612045
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
|
|
611134
|
-
printInfo(`Saved to ${
|
|
612046
|
+
printInfo(`Saved to ${join125(repoRoot, ".oa", "settings.json")}`);
|
|
611135
612047
|
printInfo("This override applies only when running in this workspace.");
|
|
611136
612048
|
} catch (err) {
|
|
611137
612049
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -611316,7 +612228,7 @@ __export(eval_exports, {
|
|
|
611316
612228
|
});
|
|
611317
612229
|
import { tmpdir as tmpdir21 } from "node:os";
|
|
611318
612230
|
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58 } from "node:fs";
|
|
611319
|
-
import { join as
|
|
612231
|
+
import { join as join126 } from "node:path";
|
|
611320
612232
|
async function evalCommand(opts, config) {
|
|
611321
612233
|
const suiteName = opts.suite ?? "basic";
|
|
611322
612234
|
const suite = SUITES[suiteName];
|
|
@@ -611445,10 +612357,10 @@ async function evalCommand(opts, config) {
|
|
|
611445
612357
|
process.exit(failed > 0 ? 1 : 0);
|
|
611446
612358
|
}
|
|
611447
612359
|
function createTempEvalRepo() {
|
|
611448
|
-
const dir =
|
|
612360
|
+
const dir = join126(tmpdir21(), `open-agents-eval-${Date.now()}`);
|
|
611449
612361
|
mkdirSync66(dir, { recursive: true });
|
|
611450
612362
|
writeFileSync58(
|
|
611451
|
-
|
|
612363
|
+
join126(dir, "package.json"),
|
|
611452
612364
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
611453
612365
|
"utf8"
|
|
611454
612366
|
);
|
|
@@ -611512,7 +612424,7 @@ init_typed_node_events();
|
|
|
611512
612424
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
611513
612425
|
import { createRequire as createRequire7 } from "node:module";
|
|
611514
612426
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
611515
|
-
import { dirname as dirname38, join as
|
|
612427
|
+
import { dirname as dirname38, join as join127 } from "node:path";
|
|
611516
612428
|
|
|
611517
612429
|
// packages/cli/src/cli.ts
|
|
611518
612430
|
init_typed_node_events();
|
|
@@ -611652,7 +612564,7 @@ init_output();
|
|
|
611652
612564
|
function getVersion5() {
|
|
611653
612565
|
try {
|
|
611654
612566
|
const require4 = createRequire7(import.meta.url);
|
|
611655
|
-
const pkgPath =
|
|
612567
|
+
const pkgPath = join127(dirname38(fileURLToPath19(import.meta.url)), "..", "package.json");
|
|
611656
612568
|
const pkg = require4(pkgPath);
|
|
611657
612569
|
return pkg.version;
|
|
611658
612570
|
} catch {
|
|
@@ -611967,11 +612879,11 @@ function crashLog(label, err) {
|
|
|
611967
612879
|
`;
|
|
611968
612880
|
try {
|
|
611969
612881
|
const { appendFileSync: appendFileSync9, mkdirSync: mkdirSync67 } = __require("node:fs");
|
|
611970
|
-
const { join:
|
|
611971
|
-
const { homedir:
|
|
611972
|
-
const logDir =
|
|
612882
|
+
const { join: join128 } = __require("node:path");
|
|
612883
|
+
const { homedir: homedir46 } = __require("node:os");
|
|
612884
|
+
const logDir = join128(homedir46(), ".open-agents");
|
|
611973
612885
|
mkdirSync67(logDir, { recursive: true });
|
|
611974
|
-
appendFileSync9(
|
|
612886
|
+
appendFileSync9(join128(logDir, "crash.log"), logLine);
|
|
611975
612887
|
} catch {
|
|
611976
612888
|
}
|
|
611977
612889
|
try {
|