open-agents-ai 0.187.535 → 0.187.537
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 +1001 -484
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9457,6 +9457,45 @@ process.on('unhandledRejection', (reason) => {
|
|
|
9457
9457
|
}
|
|
9458
9458
|
connected = true;
|
|
9459
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
|
+
|
|
9460
9499
|
// http_tunnel capability — proxies HTTP requests from remote peers
|
|
9461
9500
|
// to the local OA API daemon. Auth is delegated to the API key store
|
|
9462
9501
|
// (remote sends share key in Authorization header). SSE streams are
|
|
@@ -247788,9 +247827,9 @@ print("${sentinel}")
|
|
|
247788
247827
|
if (!this.proc || this.proc.killed) {
|
|
247789
247828
|
return { success: false, path: "" };
|
|
247790
247829
|
}
|
|
247791
|
-
const { mkdirSync:
|
|
247830
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
247792
247831
|
const sessionDir = join28(this.cwd, ".oa", "rlm");
|
|
247793
|
-
|
|
247832
|
+
mkdirSync68(sessionDir, { recursive: true });
|
|
247794
247833
|
const sessionPath2 = join28(sessionDir, "session.json");
|
|
247795
247834
|
try {
|
|
247796
247835
|
const inspectCode = `
|
|
@@ -247814,7 +247853,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
247814
247853
|
trajectoryCount: this.trajectory.length,
|
|
247815
247854
|
subCallCount: this.subCallCount
|
|
247816
247855
|
};
|
|
247817
|
-
|
|
247856
|
+
writeFileSync60(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
|
|
247818
247857
|
return { success: true, path: sessionPath2 };
|
|
247819
247858
|
}
|
|
247820
247859
|
} catch {
|
|
@@ -247826,9 +247865,9 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
247826
247865
|
* what was previously computed. */
|
|
247827
247866
|
async loadSessionInfo() {
|
|
247828
247867
|
try {
|
|
247829
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
247868
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
|
|
247830
247869
|
const sessionPath2 = join28(this.cwd, ".oa", "rlm", "session.json");
|
|
247831
|
-
if (!
|
|
247870
|
+
if (!existsSync111(sessionPath2))
|
|
247832
247871
|
return null;
|
|
247833
247872
|
return JSON.parse(readFileSync89(sessionPath2, "utf8"));
|
|
247834
247873
|
} catch {
|
|
@@ -248394,10 +248433,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248394
248433
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
248395
248434
|
*/
|
|
248396
248435
|
getTopMemoriesSync(k = 5, taskType) {
|
|
248397
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
248436
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
248398
248437
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248399
248438
|
const storeFile = join29(metaDir, "store.json");
|
|
248400
|
-
if (!
|
|
248439
|
+
if (!existsSync111(storeFile))
|
|
248401
248440
|
return "";
|
|
248402
248441
|
let store2 = [];
|
|
248403
248442
|
try {
|
|
@@ -248423,10 +248462,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248423
248462
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
248424
248463
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
248425
248464
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
248426
|
-
const { readFileSync: readFileSync89, writeFileSync:
|
|
248465
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
248427
248466
|
const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
|
|
248428
248467
|
const storeFile = join29(metaDir, "store.json");
|
|
248429
|
-
if (!
|
|
248468
|
+
if (!existsSync111(storeFile))
|
|
248430
248469
|
return;
|
|
248431
248470
|
let store2 = [];
|
|
248432
248471
|
try {
|
|
@@ -248454,8 +248493,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
248454
248493
|
updated = true;
|
|
248455
248494
|
}
|
|
248456
248495
|
if (updated) {
|
|
248457
|
-
|
|
248458
|
-
|
|
248496
|
+
mkdirSync68(metaDir, { recursive: true });
|
|
248497
|
+
writeFileSync60(storeFile, JSON.stringify(store2, null, 2));
|
|
248459
248498
|
}
|
|
248460
248499
|
}
|
|
248461
248500
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -248877,9 +248916,9 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248877
248916
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
248878
248917
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
248879
248918
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
248880
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
248919
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
248881
248920
|
const archiveFile = join31(this.cwd, ".oa", "arche", "variants.json");
|
|
248882
|
-
if (!
|
|
248921
|
+
if (!existsSync111(archiveFile))
|
|
248883
248922
|
return "";
|
|
248884
248923
|
let variants = [];
|
|
248885
248924
|
try {
|
|
@@ -248901,12 +248940,12 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248901
248940
|
}
|
|
248902
248941
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
248903
248942
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
248904
|
-
const { readFileSync: readFileSync89, writeFileSync:
|
|
248943
|
+
const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
248905
248944
|
const dir = join31(this.cwd, ".oa", "arche");
|
|
248906
248945
|
const archiveFile = join31(dir, "variants.json");
|
|
248907
248946
|
let variants = [];
|
|
248908
248947
|
try {
|
|
248909
|
-
if (
|
|
248948
|
+
if (existsSync111(archiveFile))
|
|
248910
248949
|
variants = JSON.parse(readFileSync89(archiveFile, "utf8"));
|
|
248911
248950
|
} catch {
|
|
248912
248951
|
}
|
|
@@ -248922,8 +248961,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
248922
248961
|
});
|
|
248923
248962
|
if (variants.length > 50)
|
|
248924
248963
|
variants = variants.slice(-50);
|
|
248925
|
-
|
|
248926
|
-
|
|
248964
|
+
mkdirSync68(dir, { recursive: true });
|
|
248965
|
+
writeFileSync60(archiveFile, JSON.stringify(variants, null, 2));
|
|
248927
248966
|
}
|
|
248928
248967
|
async saveArchive(variants) {
|
|
248929
248968
|
const dir = join31(this.cwd, ".oa", "arche");
|
|
@@ -257187,7 +257226,7 @@ var require_util9 = __commonJS({
|
|
|
257187
257226
|
return path8;
|
|
257188
257227
|
}
|
|
257189
257228
|
exports.normalize = normalize2;
|
|
257190
|
-
function
|
|
257229
|
+
function join129(aRoot, aPath) {
|
|
257191
257230
|
if (aRoot === "") {
|
|
257192
257231
|
aRoot = ".";
|
|
257193
257232
|
}
|
|
@@ -257219,7 +257258,7 @@ var require_util9 = __commonJS({
|
|
|
257219
257258
|
}
|
|
257220
257259
|
return joined;
|
|
257221
257260
|
}
|
|
257222
|
-
exports.join =
|
|
257261
|
+
exports.join = join129;
|
|
257223
257262
|
exports.isAbsolute = function(aPath) {
|
|
257224
257263
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
257225
257264
|
};
|
|
@@ -257392,7 +257431,7 @@ var require_util9 = __commonJS({
|
|
|
257392
257431
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
257393
257432
|
}
|
|
257394
257433
|
}
|
|
257395
|
-
sourceURL =
|
|
257434
|
+
sourceURL = join129(urlGenerate(parsed), sourceURL);
|
|
257396
257435
|
}
|
|
257397
257436
|
return normalize2(sourceURL);
|
|
257398
257437
|
}
|
|
@@ -472295,10 +472334,10 @@ var require_commonjs3 = __commonJS({
|
|
|
472295
472334
|
let ai = 0;
|
|
472296
472335
|
let bi = 0;
|
|
472297
472336
|
let result = [];
|
|
472298
|
-
let
|
|
472337
|
+
let which2 = "";
|
|
472299
472338
|
while (ai < a2.length && bi < b.length) {
|
|
472300
472339
|
if (a2[ai] === b[bi]) {
|
|
472301
|
-
result.push(
|
|
472340
|
+
result.push(which2 === "b" ? b[bi] : a2[ai]);
|
|
472302
472341
|
ai++;
|
|
472303
472342
|
bi++;
|
|
472304
472343
|
} else if (emptyGSMatch && a2[ai] === "**" && b[bi] === a2[ai + 1]) {
|
|
@@ -472308,16 +472347,16 @@ var require_commonjs3 = __commonJS({
|
|
|
472308
472347
|
result.push(b[bi]);
|
|
472309
472348
|
bi++;
|
|
472310
472349
|
} else if (a2[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
|
|
472311
|
-
if (
|
|
472350
|
+
if (which2 === "b")
|
|
472312
472351
|
return false;
|
|
472313
|
-
|
|
472352
|
+
which2 = "a";
|
|
472314
472353
|
result.push(a2[ai]);
|
|
472315
472354
|
ai++;
|
|
472316
472355
|
bi++;
|
|
472317
472356
|
} else if (b[bi] === "*" && a2[ai] && (this.options.dot || !a2[ai].startsWith(".")) && a2[ai] !== "**") {
|
|
472318
|
-
if (
|
|
472357
|
+
if (which2 === "a")
|
|
472319
472358
|
return false;
|
|
472320
|
-
|
|
472359
|
+
which2 = "b";
|
|
472321
472360
|
result.push(b[bi]);
|
|
472322
472361
|
ai++;
|
|
472323
472362
|
bi++;
|
|
@@ -472812,7 +472851,7 @@ var require_path_browserify = __commonJS({
|
|
|
472812
472851
|
assertPath(path8);
|
|
472813
472852
|
return path8.length > 0 && path8.charCodeAt(0) === 47;
|
|
472814
472853
|
},
|
|
472815
|
-
join: function
|
|
472854
|
+
join: function join129() {
|
|
472816
472855
|
if (arguments.length === 0)
|
|
472817
472856
|
return ".";
|
|
472818
472857
|
var joined;
|
|
@@ -507800,7 +507839,7 @@ var init_agent_tool = __esm({
|
|
|
507800
507839
|
})();
|
|
507801
507840
|
if (isolation === "worktree") {
|
|
507802
507841
|
this.callbacks.onViewRegister?.(agentId, label);
|
|
507803
|
-
const
|
|
507842
|
+
const spawn28 = this.callbacks.spawnSubprocess({
|
|
507804
507843
|
id: agentId,
|
|
507805
507844
|
task: composedPrompt,
|
|
507806
507845
|
model,
|
|
@@ -507810,7 +507849,7 @@ var init_agent_tool = __esm({
|
|
|
507810
507849
|
success: true,
|
|
507811
507850
|
output: `Agent spawned (subprocess, worktree): ${agentId}
|
|
507812
507851
|
Type: ${subagentType}
|
|
507813
|
-
PID: ${
|
|
507852
|
+
PID: ${spawn28.pid}
|
|
507814
507853
|
Task: ${prompt.slice(0, 100)}
|
|
507815
507854
|
Use task_status("${agentId}") to check progress.`,
|
|
507816
507855
|
durationMs: performance.now() - start2
|
|
@@ -522926,8 +522965,8 @@ var init_reflectionBuffer = __esm({
|
|
|
522926
522965
|
this.persistPath = persistPath ?? null;
|
|
522927
522966
|
if (this.persistPath) {
|
|
522928
522967
|
try {
|
|
522929
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
522930
|
-
if (
|
|
522968
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
|
|
522969
|
+
if (existsSync111(this.persistPath)) {
|
|
522931
522970
|
this.state = JSON.parse(readFileSync89(this.persistPath, "utf-8"));
|
|
522932
522971
|
return;
|
|
522933
522972
|
}
|
|
@@ -523161,12 +523200,12 @@ var init_reflectionBuffer = __esm({
|
|
|
523161
523200
|
if (!this.persistPath)
|
|
523162
523201
|
return;
|
|
523163
523202
|
try {
|
|
523164
|
-
const { writeFileSync:
|
|
523165
|
-
const { join:
|
|
523166
|
-
const dir =
|
|
523167
|
-
if (!
|
|
523168
|
-
|
|
523169
|
-
|
|
523203
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: existsSync111 } = __require("node:fs");
|
|
523204
|
+
const { join: join129 } = __require("node:path");
|
|
523205
|
+
const dir = join129(this.persistPath, "..");
|
|
523206
|
+
if (!existsSync111(dir))
|
|
523207
|
+
mkdirSync68(dir, { recursive: true });
|
|
523208
|
+
writeFileSync60(this.persistPath, JSON.stringify(this.state, null, 2));
|
|
523170
523209
|
} catch {
|
|
523171
523210
|
}
|
|
523172
523211
|
}
|
|
@@ -533706,10 +533745,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533706
533745
|
if (nodes > 0) {
|
|
533707
533746
|
this.emit({ type: "status", content: `Knowledge graph: ${nodes} nodes, ${edges} active edges`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
533708
533747
|
try {
|
|
533709
|
-
const { mkdirSync:
|
|
533710
|
-
const { join:
|
|
533711
|
-
const contextDir =
|
|
533712
|
-
|
|
533748
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
533749
|
+
const { join: join129 } = __require("node:path");
|
|
533750
|
+
const contextDir = join129(this._workingDirectory || process.cwd(), ".oa", "context");
|
|
533751
|
+
mkdirSync68(contextDir, { recursive: true });
|
|
533713
533752
|
const topEntities = this._temporalGraph.nodesByType("entity", 3);
|
|
533714
533753
|
const topFiles = this._temporalGraph.nodesByType("file", 3);
|
|
533715
533754
|
const topConcepts = this._temporalGraph.nodesByType("concept", 3);
|
|
@@ -533749,9 +533788,9 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
533749
533788
|
section("Top Files", topFiles);
|
|
533750
533789
|
section("Top Concepts", topConcepts);
|
|
533751
533790
|
lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
|
|
533752
|
-
const outPath =
|
|
533753
|
-
|
|
533754
|
-
|
|
533791
|
+
const outPath = join129(contextDir, `kg-summary-${this._sessionId}.md`);
|
|
533792
|
+
writeFileSync60(outPath, lines.join("\n"), "utf-8");
|
|
533793
|
+
writeFileSync60(join129(contextDir, `kg-summary-latest.md`), lines.join("\n"), "utf-8");
|
|
533755
533794
|
} catch {
|
|
533756
533795
|
}
|
|
533757
533796
|
}
|
|
@@ -533919,11 +533958,11 @@ ${errOutput}`;
|
|
|
533919
533958
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
533920
533959
|
});
|
|
533921
533960
|
try {
|
|
533922
|
-
const { mkdirSync:
|
|
533923
|
-
const { join:
|
|
533924
|
-
const resultsDir =
|
|
533925
|
-
|
|
533926
|
-
|
|
533961
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
533962
|
+
const { join: join129 } = __require("node:path");
|
|
533963
|
+
const resultsDir = join129(process.cwd(), ".oa", "tool-results");
|
|
533964
|
+
mkdirSync68(resultsDir, { recursive: true });
|
|
533965
|
+
writeFileSync60(join129(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
|
|
533927
533966
|
# Turn: ${turn}
|
|
533928
533967
|
# Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
533929
533968
|
# Size: ${result.output.length} chars, ${lineCount} lines
|
|
@@ -534139,10 +534178,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
534139
534178
|
if (!this._workingDirectory)
|
|
534140
534179
|
return;
|
|
534141
534180
|
try {
|
|
534142
|
-
const { mkdirSync:
|
|
534143
|
-
const { join:
|
|
534144
|
-
const sessionDir =
|
|
534145
|
-
|
|
534181
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
534182
|
+
const { join: join129 } = __require("node:path");
|
|
534183
|
+
const sessionDir = join129(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
534184
|
+
mkdirSync68(sessionDir, { recursive: true });
|
|
534146
534185
|
const checkpoint = {
|
|
534147
534186
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
534148
534187
|
sessionId: this._sessionId,
|
|
@@ -534154,7 +534193,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
534154
534193
|
memexEntryCount: this._memexArchive.size,
|
|
534155
534194
|
fileRegistrySize: this._fileRegistry.size
|
|
534156
534195
|
};
|
|
534157
|
-
|
|
534196
|
+
writeFileSync60(join129(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
534158
534197
|
} catch {
|
|
534159
534198
|
}
|
|
534160
534199
|
}
|
|
@@ -535981,12 +536020,12 @@ ${result}`
|
|
|
535981
536020
|
let resizedBase64 = null;
|
|
535982
536021
|
try {
|
|
535983
536022
|
const { execSync: execSync59 } = await import("node:child_process");
|
|
535984
|
-
const { writeFileSync:
|
|
535985
|
-
const { join:
|
|
535986
|
-
const { tmpdir:
|
|
535987
|
-
const tmpIn =
|
|
535988
|
-
const tmpOut =
|
|
535989
|
-
|
|
536023
|
+
const { writeFileSync: writeFileSync60, readFileSync: readFileSync89, unlinkSync: unlinkSync25 } = await import("node:fs");
|
|
536024
|
+
const { join: join129 } = await import("node:path");
|
|
536025
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
536026
|
+
const tmpIn = join129(tmpdir23(), `oa_img_in_${Date.now()}.png`);
|
|
536027
|
+
const tmpOut = join129(tmpdir23(), `oa_img_out_${Date.now()}.jpg`);
|
|
536028
|
+
writeFileSync60(tmpIn, buffer2);
|
|
535990
536029
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
535991
536030
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
535992
536031
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
@@ -544531,23 +544570,23 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
544531
544570
|
async function fetchPeerModels(peerId, authKey) {
|
|
544532
544571
|
try {
|
|
544533
544572
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
544534
|
-
const { existsSync:
|
|
544535
|
-
const { join:
|
|
544573
|
+
const { existsSync: existsSync111, readFileSync: readFileSync89 } = await import("node:fs");
|
|
544574
|
+
const { join: join129 } = await import("node:path");
|
|
544536
544575
|
const cwd4 = process.cwd();
|
|
544537
544576
|
const nexusTool = new NexusTool2(cwd4);
|
|
544538
544577
|
const nexusDir = nexusTool.getNexusDir();
|
|
544539
544578
|
let isLocalPeer = false;
|
|
544540
544579
|
try {
|
|
544541
|
-
const statusPath =
|
|
544542
|
-
if (
|
|
544580
|
+
const statusPath = join129(nexusDir, "status.json");
|
|
544581
|
+
if (existsSync111(statusPath)) {
|
|
544543
544582
|
const status = JSON.parse(readFileSync89(statusPath, "utf8"));
|
|
544544
544583
|
if (status.peerId === peerId) isLocalPeer = true;
|
|
544545
544584
|
}
|
|
544546
544585
|
} catch {
|
|
544547
544586
|
}
|
|
544548
544587
|
if (isLocalPeer) {
|
|
544549
|
-
const pricingPath =
|
|
544550
|
-
if (
|
|
544588
|
+
const pricingPath = join129(nexusDir, "pricing.json");
|
|
544589
|
+
if (existsSync111(pricingPath)) {
|
|
544551
544590
|
try {
|
|
544552
544591
|
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544553
544592
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
@@ -544562,8 +544601,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544562
544601
|
}
|
|
544563
544602
|
}
|
|
544564
544603
|
}
|
|
544565
|
-
const cachePath =
|
|
544566
|
-
if (
|
|
544604
|
+
const cachePath = join129(nexusDir, "peer-models-cache.json");
|
|
544605
|
+
if (existsSync111(cachePath)) {
|
|
544567
544606
|
try {
|
|
544568
544607
|
const cache8 = JSON.parse(readFileSync89(cachePath, "utf8"));
|
|
544569
544608
|
if (cache8.peerId === peerId && cache8.models?.length > 0) {
|
|
@@ -544677,8 +544716,8 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
544677
544716
|
} catch {
|
|
544678
544717
|
}
|
|
544679
544718
|
if (isLocalPeer) {
|
|
544680
|
-
const pricingPath =
|
|
544681
|
-
if (
|
|
544719
|
+
const pricingPath = join129(nexusDir, "pricing.json");
|
|
544720
|
+
if (existsSync111(pricingPath)) {
|
|
544682
544721
|
try {
|
|
544683
544722
|
const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
|
|
544684
544723
|
return (pricing.models || []).map((m2) => ({
|
|
@@ -562459,13 +562498,13 @@ async function runSudoScript(ctx3, script) {
|
|
|
562459
562498
|
} catch {
|
|
562460
562499
|
}
|
|
562461
562500
|
try {
|
|
562462
|
-
const { spawn:
|
|
562501
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
562463
562502
|
const full = `set -e; ${script}`;
|
|
562464
562503
|
await new Promise((resolve43) => {
|
|
562465
562504
|
const usePkexec = process.platform === "linux";
|
|
562466
562505
|
const cmd = usePkexec ? "pkexec" : "sudo";
|
|
562467
562506
|
const args = usePkexec ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
|
|
562468
|
-
const child =
|
|
562507
|
+
const child = spawn28(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
562469
562508
|
let stdout = "";
|
|
562470
562509
|
let stderr = "";
|
|
562471
562510
|
child.stdout?.on("data", (data) => {
|
|
@@ -562499,9 +562538,9 @@ async function ensureVoiceDeps(ctx3) {
|
|
|
562499
562538
|
}
|
|
562500
562539
|
if (typeof mod2.getVenvPython === "function") {
|
|
562501
562540
|
const { dirname: dirname39 } = await import("node:path");
|
|
562502
|
-
const { existsSync:
|
|
562541
|
+
const { existsSync: existsSync111 } = await import("node:fs");
|
|
562503
562542
|
const venvPy = mod2.getVenvPython();
|
|
562504
|
-
if (
|
|
562543
|
+
if (existsSync111(venvPy)) {
|
|
562505
562544
|
process.env.TRANSCRIBE_PYTHON = venvPy;
|
|
562506
562545
|
const venvBin = dirname39(venvPy);
|
|
562507
562546
|
const sep2 = process.platform === "win32" ? ";" : ":";
|
|
@@ -562820,10 +562859,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562820
562859
|
if (!key) {
|
|
562821
562860
|
try {
|
|
562822
562861
|
const { homedir: homedir46 } = await import("node:os");
|
|
562823
|
-
const { readFileSync: readFileSync89, existsSync:
|
|
562824
|
-
const { join:
|
|
562825
|
-
const p2 =
|
|
562826
|
-
if (
|
|
562862
|
+
const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
|
|
562863
|
+
const { join: join129 } = await import("node:path");
|
|
562864
|
+
const p2 = join129(homedir46(), ".open-agents", "api.key");
|
|
562865
|
+
if (existsSync111(p2)) key = readFileSync89(p2, "utf8").trim();
|
|
562827
562866
|
} catch {
|
|
562828
562867
|
}
|
|
562829
562868
|
}
|
|
@@ -562862,13 +562901,13 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
562862
562901
|
try {
|
|
562863
562902
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
562864
562903
|
const { homedir: homedir46 } = await import("node:os");
|
|
562865
|
-
const { mkdirSync:
|
|
562866
|
-
const { join:
|
|
562904
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
562905
|
+
const { join: join129 } = await import("node:path");
|
|
562867
562906
|
const newKey = randomBytes25(16).toString("hex");
|
|
562868
562907
|
process.env["OA_API_KEY"] = newKey;
|
|
562869
|
-
const dir =
|
|
562870
|
-
|
|
562871
|
-
|
|
562908
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
562909
|
+
mkdirSync68(dir, { recursive: true });
|
|
562910
|
+
writeFileSync60(join129(dir, "api.key"), newKey + "\n", "utf8");
|
|
562872
562911
|
renderInfo2(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
562873
562912
|
renderInfo2("Restart the daemon to apply if needed. Use /access any to restart quickly.");
|
|
562874
562913
|
} catch (e2) {
|
|
@@ -563056,11 +563095,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563056
563095
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
563057
563096
|
try {
|
|
563058
563097
|
const { homedir: homedir47 } = await import("node:os");
|
|
563059
|
-
const { mkdirSync:
|
|
563060
|
-
const { join:
|
|
563061
|
-
const dir =
|
|
563062
|
-
|
|
563063
|
-
|
|
563098
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563099
|
+
const { join: join130 } = await import("node:path");
|
|
563100
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563101
|
+
mkdirSync69(dir, { recursive: true });
|
|
563102
|
+
writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
|
|
563064
563103
|
} catch {
|
|
563065
563104
|
}
|
|
563066
563105
|
}
|
|
@@ -563072,11 +563111,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563072
563111
|
const port2 = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
563073
563112
|
try {
|
|
563074
563113
|
const { homedir: homedir47 } = await import("node:os");
|
|
563075
|
-
const { mkdirSync:
|
|
563076
|
-
const { join:
|
|
563077
|
-
const dir =
|
|
563078
|
-
|
|
563079
|
-
|
|
563114
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563115
|
+
const { join: join130 } = await import("node:path");
|
|
563116
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563117
|
+
mkdirSync69(dir, { recursive: true });
|
|
563118
|
+
writeFileSync61(join130(dir, "access"), `${val2}
|
|
563080
563119
|
`, "utf8");
|
|
563081
563120
|
} catch {
|
|
563082
563121
|
}
|
|
@@ -563158,11 +563197,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563158
563197
|
renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
|
|
563159
563198
|
try {
|
|
563160
563199
|
const { homedir: homedir47 } = await import("node:os");
|
|
563161
|
-
const { mkdirSync:
|
|
563162
|
-
const { join:
|
|
563163
|
-
const dir =
|
|
563164
|
-
|
|
563165
|
-
|
|
563200
|
+
const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
|
|
563201
|
+
const { join: join130 } = await import("node:path");
|
|
563202
|
+
const dir = join130(homedir47(), ".open-agents");
|
|
563203
|
+
mkdirSync69(dir, { recursive: true });
|
|
563204
|
+
writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
|
|
563166
563205
|
} catch {
|
|
563167
563206
|
}
|
|
563168
563207
|
}
|
|
@@ -563173,12 +563212,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
563173
563212
|
}
|
|
563174
563213
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
563175
563214
|
const { homedir: homedir46 } = await import("node:os");
|
|
563176
|
-
const { mkdirSync:
|
|
563177
|
-
const { join:
|
|
563215
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
563216
|
+
const { join: join129 } = await import("node:path");
|
|
563178
563217
|
try {
|
|
563179
|
-
const dir =
|
|
563180
|
-
|
|
563181
|
-
|
|
563218
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
563219
|
+
mkdirSync68(dir, { recursive: true });
|
|
563220
|
+
writeFileSync60(join129(dir, "access"), `${val}
|
|
563182
563221
|
`, "utf8");
|
|
563183
563222
|
} catch (e2) {
|
|
563184
563223
|
renderWarning2(`Could not persist ~/.open-agents/access: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
@@ -564230,8 +564269,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
564230
564269
|
writeFileSync41(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
564231
564270
|
renderInfo2(`Launching fortemi-react from ${fDir}...`);
|
|
564232
564271
|
try {
|
|
564233
|
-
const { spawn:
|
|
564234
|
-
const child =
|
|
564272
|
+
const { spawn: spawn28 } = __require("node:child_process");
|
|
564273
|
+
const child = spawn28("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
564235
564274
|
cwd: join99(fDir, "apps", "standalone"),
|
|
564236
564275
|
stdio: "ignore",
|
|
564237
564276
|
detached: true,
|
|
@@ -564956,9 +564995,9 @@ systemctl --user daemon-reload || true
|
|
|
564956
564995
|
systemctl --user enable --now open-agents-daemon.service || true
|
|
564957
564996
|
sleep 1
|
|
564958
564997
|
`;
|
|
564959
|
-
const { spawn:
|
|
564998
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
564960
564999
|
await new Promise((resolve43) => {
|
|
564961
|
-
const child =
|
|
565000
|
+
const child = spawn28("bash", ["-lc", takeover], { stdio: "inherit" });
|
|
564962
565001
|
onChildExit(child, () => resolve43());
|
|
564963
565002
|
});
|
|
564964
565003
|
renderInfo2("Daemon takeover complete.");
|
|
@@ -567395,11 +567434,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
567395
567434
|
continue;
|
|
567396
567435
|
}
|
|
567397
567436
|
const { basename: basename21, join: pathJoin } = await import("node:path");
|
|
567398
|
-
const { copyFileSync: copyFileSync3, mkdirSync:
|
|
567437
|
+
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync68, existsSync: exists2 } = await import("node:fs");
|
|
567399
567438
|
const { homedir: homedir46 } = await import("node:os");
|
|
567400
567439
|
const modelName = basename21(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
567401
567440
|
const destDir = pathJoin(homedir46(), ".open-agents", "voice", "models", modelName);
|
|
567402
|
-
if (!exists2(destDir))
|
|
567441
|
+
if (!exists2(destDir)) mkdirSync68(destDir, { recursive: true });
|
|
567403
567442
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
567404
567443
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
567405
567444
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -568149,10 +568188,10 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
568149
568188
|
sponsors.push(...verified);
|
|
568150
568189
|
if (verified.length > 0) {
|
|
568151
568190
|
try {
|
|
568152
|
-
const { mkdirSync:
|
|
568153
|
-
|
|
568191
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
|
|
568192
|
+
mkdirSync68(sponsorDir2, { recursive: true });
|
|
568154
568193
|
const cached = verified.map((s2) => ({ ...s2, lastVerified: Date.now() }));
|
|
568155
|
-
|
|
568194
|
+
writeFileSync60(knownFile, JSON.stringify(cached, null, 2));
|
|
568156
568195
|
} catch {
|
|
568157
568196
|
}
|
|
568158
568197
|
}
|
|
@@ -568325,11 +568364,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
568325
568364
|
const models = await fetchModels(peerUrl, authKey);
|
|
568326
568365
|
if (models.length > 0) {
|
|
568327
568366
|
try {
|
|
568328
|
-
const { writeFileSync:
|
|
568329
|
-
const { join:
|
|
568330
|
-
const cachePath =
|
|
568331
|
-
|
|
568332
|
-
|
|
568367
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68 } = await import("node:fs");
|
|
568368
|
+
const { join: join129, dirname: dirname39 } = await import("node:path");
|
|
568369
|
+
const cachePath = join129(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
568370
|
+
mkdirSync68(dirname39(cachePath), { recursive: true });
|
|
568371
|
+
writeFileSync60(cachePath, JSON.stringify({
|
|
568333
568372
|
peerId,
|
|
568334
568373
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
568335
568374
|
models: models.map((m2) => ({ name: m2.name, size: m2.size, parameterSize: m2.parameterSize }))
|
|
@@ -568481,8 +568520,8 @@ ${escapedContent}EOF'`, { timeoutMs: 3e4 });
|
|
|
568481
568520
|
}
|
|
568482
568521
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
568483
568522
|
process.env.OLLAMA_NUM_PARALLEL = String(n2);
|
|
568484
|
-
const { spawn:
|
|
568485
|
-
const child =
|
|
568523
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
568524
|
+
const child = spawn28("ollama", ["serve"], {
|
|
568486
568525
|
stdio: "ignore",
|
|
568487
568526
|
detached: true,
|
|
568488
568527
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n2) }
|
|
@@ -568898,17 +568937,17 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
568898
568937
|
try {
|
|
568899
568938
|
const { createRequire: createRequire8 } = await import("node:module");
|
|
568900
568939
|
const { fileURLToPath: fileURLToPath20 } = await import("node:url");
|
|
568901
|
-
const { dirname: dirname39, join:
|
|
568902
|
-
const { existsSync:
|
|
568940
|
+
const { dirname: dirname39, join: join129 } = await import("node:path");
|
|
568941
|
+
const { existsSync: existsSync111 } = await import("node:fs");
|
|
568903
568942
|
const req2 = createRequire8(import.meta.url);
|
|
568904
568943
|
const thisDir = dirname39(fileURLToPath20(import.meta.url));
|
|
568905
568944
|
const candidates = [
|
|
568906
|
-
|
|
568907
|
-
|
|
568908
|
-
|
|
568945
|
+
join129(thisDir, "..", "package.json"),
|
|
568946
|
+
join129(thisDir, "..", "..", "package.json"),
|
|
568947
|
+
join129(thisDir, "..", "..", "..", "package.json")
|
|
568909
568948
|
];
|
|
568910
568949
|
for (const pkgPath of candidates) {
|
|
568911
|
-
if (
|
|
568950
|
+
if (existsSync111(pkgPath)) {
|
|
568912
568951
|
const pkg = req2(pkgPath);
|
|
568913
568952
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
568914
568953
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -570056,13 +570095,13 @@ var init_commands = __esm({
|
|
|
570056
570095
|
try {
|
|
570057
570096
|
const { randomBytes: randomBytes25 } = await import("node:crypto");
|
|
570058
570097
|
const { homedir: homedir46 } = await import("node:os");
|
|
570059
|
-
const { mkdirSync:
|
|
570060
|
-
const { join:
|
|
570098
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
570099
|
+
const { join: join129 } = await import("node:path");
|
|
570061
570100
|
const apiKey = randomBytes25(16).toString("hex");
|
|
570062
570101
|
process.env["OA_API_KEY"] = apiKey;
|
|
570063
|
-
const dir =
|
|
570064
|
-
|
|
570065
|
-
|
|
570102
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
570103
|
+
mkdirSync68(dir, { recursive: true });
|
|
570104
|
+
writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
|
|
570066
570105
|
renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
570067
570106
|
renderInfo2("Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it.");
|
|
570068
570107
|
} catch (e2) {
|
|
@@ -570077,11 +570116,11 @@ var init_commands = __esm({
|
|
|
570077
570116
|
const port = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
570078
570117
|
try {
|
|
570079
570118
|
const { homedir: homedir46 } = await import("node:os");
|
|
570080
|
-
const { mkdirSync:
|
|
570081
|
-
const { join:
|
|
570082
|
-
const dir =
|
|
570083
|
-
|
|
570084
|
-
|
|
570119
|
+
const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
|
|
570120
|
+
const { join: join129 } = await import("node:path");
|
|
570121
|
+
const dir = join129(homedir46(), ".open-agents");
|
|
570122
|
+
mkdirSync68(dir, { recursive: true });
|
|
570123
|
+
writeFileSync60(join129(dir, "access"), `${val}
|
|
570085
570124
|
`, "utf8");
|
|
570086
570125
|
} catch {
|
|
570087
570126
|
}
|
|
@@ -581893,11 +581932,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
581893
581932
|
let mimeType = "audio/wav";
|
|
581894
581933
|
try {
|
|
581895
581934
|
const { execSync: execSyncLocal } = await import("node:child_process");
|
|
581896
|
-
const { tmpdir:
|
|
581935
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
581897
581936
|
const { join: joinPath } = await import("node:path");
|
|
581898
581937
|
const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
|
|
581899
|
-
const tmpWav = joinPath(
|
|
581900
|
-
const tmpOgg = joinPath(
|
|
581938
|
+
const tmpWav = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.wav`);
|
|
581939
|
+
const tmpOgg = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.ogg`);
|
|
581901
581940
|
writeFs(tmpWav, wavBuffer);
|
|
581902
581941
|
execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
|
|
581903
581942
|
timeout: 15e3,
|
|
@@ -585772,9 +585811,131 @@ var init_tor_fallback = __esm({
|
|
|
585772
585811
|
}
|
|
585773
585812
|
});
|
|
585774
585813
|
|
|
585814
|
+
// packages/cli/src/api/graphical-sudo.ts
|
|
585815
|
+
var graphical_sudo_exports = {};
|
|
585816
|
+
__export(graphical_sudo_exports, {
|
|
585817
|
+
detectSudoHelper: () => detectSudoHelper,
|
|
585818
|
+
runGraphicalSudo: () => runGraphicalSudo
|
|
585819
|
+
});
|
|
585820
|
+
import { spawn as spawn24 } from "node:child_process";
|
|
585821
|
+
import { existsSync as existsSync102, mkdirSync as mkdirSync60, writeFileSync as writeFileSync52, chmodSync as chmodSync2 } from "node:fs";
|
|
585822
|
+
import { join as join118 } from "node:path";
|
|
585823
|
+
import { tmpdir as tmpdir21 } from "node:os";
|
|
585824
|
+
function detectSudoHelper() {
|
|
585825
|
+
if (process.platform === "win32") return null;
|
|
585826
|
+
if (process.platform === "darwin") return "osascript";
|
|
585827
|
+
if (which("pkexec")) return "pkexec";
|
|
585828
|
+
if (which("ssh-askpass")) return "ssh-askpass";
|
|
585829
|
+
if (which("zenity")) return "zenity";
|
|
585830
|
+
if (which("kdialog")) return "kdialog";
|
|
585831
|
+
if (which("sudo")) return "sudo-tty";
|
|
585832
|
+
return null;
|
|
585833
|
+
}
|
|
585834
|
+
function which(cmd) {
|
|
585835
|
+
const path8 = process.env["PATH"] || "/usr/bin:/bin:/usr/local/bin";
|
|
585836
|
+
for (const dir of path8.split(":")) {
|
|
585837
|
+
if (!dir) continue;
|
|
585838
|
+
const full = join118(dir, cmd);
|
|
585839
|
+
if (existsSync102(full)) return full;
|
|
585840
|
+
}
|
|
585841
|
+
return null;
|
|
585842
|
+
}
|
|
585843
|
+
function ensureAskpassShim(helper, description) {
|
|
585844
|
+
const shimDir = join118(tmpdir21(), "oa-askpass");
|
|
585845
|
+
mkdirSync60(shimDir, { recursive: true });
|
|
585846
|
+
const shim = join118(shimDir, `${helper}.sh`);
|
|
585847
|
+
let body;
|
|
585848
|
+
if (helper === "zenity") {
|
|
585849
|
+
body = `#!/bin/sh
|
|
585850
|
+
exec zenity --password --title="OA needs sudo" --text="${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
585851
|
+
`;
|
|
585852
|
+
} else {
|
|
585853
|
+
body = `#!/bin/sh
|
|
585854
|
+
exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
|
|
585855
|
+
`;
|
|
585856
|
+
}
|
|
585857
|
+
writeFileSync52(shim, body, "utf-8");
|
|
585858
|
+
chmodSync2(shim, 493);
|
|
585859
|
+
return shim;
|
|
585860
|
+
}
|
|
585861
|
+
async function runGraphicalSudo(opts) {
|
|
585862
|
+
const helper = detectSudoHelper();
|
|
585863
|
+
const description = opts.description || "Open Agents needs admin access to set up Tor (.onion hidden service)";
|
|
585864
|
+
const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
|
|
585865
|
+
if (!helper) throw new Error("No suitable sudo helper found (pkexec, zenity, kdialog, ssh-askpass).");
|
|
585866
|
+
let cmd;
|
|
585867
|
+
let args;
|
|
585868
|
+
let extraEnv = {};
|
|
585869
|
+
const envFlags = [];
|
|
585870
|
+
for (const [k, v] of Object.entries(opts.env || {})) envFlags.push(`${k}=${v}`);
|
|
585871
|
+
if (helper === "pkexec") {
|
|
585872
|
+
cmd = "pkexec";
|
|
585873
|
+
args = [];
|
|
585874
|
+
if (envFlags.length) args.push(...envFlags.flatMap((e2) => ["--user", "root", "env", e2]));
|
|
585875
|
+
args = ["env", ...envFlags, "/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585876
|
+
} else if (helper === "osascript") {
|
|
585877
|
+
const inner = `${envFlags.map((e2) => `${e2}`).join(" ")} /bin/bash ${shellQuote(opts.scriptPath)} ${shellQuote((opts.args ?? []).join(" "))}`.trim();
|
|
585878
|
+
cmd = "osascript";
|
|
585879
|
+
args = ["-e", `do shell script "${inner.replace(/"/g, '\\"')}" with administrator privileges`];
|
|
585880
|
+
} else if (helper === "ssh-askpass" || helper === "zenity" || helper === "kdialog") {
|
|
585881
|
+
const shim = helper === "ssh-askpass" ? which("ssh-askpass") : ensureAskpassShim(helper, description);
|
|
585882
|
+
extraEnv = { ...extraEnv, SUDO_ASKPASS: shim, DISPLAY: process.env["DISPLAY"] || ":0" };
|
|
585883
|
+
cmd = "sudo";
|
|
585884
|
+
args = ["-A", "-E", "/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585885
|
+
} else {
|
|
585886
|
+
cmd = "sudo";
|
|
585887
|
+
args = ["/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
585888
|
+
}
|
|
585889
|
+
return new Promise((resolve43, reject) => {
|
|
585890
|
+
const child = spawn24(cmd, args, {
|
|
585891
|
+
env: { ...process.env, ...opts.env || {}, ...extraEnv },
|
|
585892
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
585893
|
+
});
|
|
585894
|
+
let stdout = "";
|
|
585895
|
+
let stderr = "";
|
|
585896
|
+
let timedOut = false;
|
|
585897
|
+
const timer = setTimeout(() => {
|
|
585898
|
+
timedOut = true;
|
|
585899
|
+
try {
|
|
585900
|
+
child.kill("SIGTERM");
|
|
585901
|
+
} catch {
|
|
585902
|
+
}
|
|
585903
|
+
setTimeout(() => {
|
|
585904
|
+
try {
|
|
585905
|
+
child.kill("SIGKILL");
|
|
585906
|
+
} catch {
|
|
585907
|
+
}
|
|
585908
|
+
}, 2e3);
|
|
585909
|
+
}, timeoutMs);
|
|
585910
|
+
child.stdout.on("data", (d2) => {
|
|
585911
|
+
stdout += d2.toString("utf-8");
|
|
585912
|
+
});
|
|
585913
|
+
child.stderr.on("data", (d2) => {
|
|
585914
|
+
stderr += d2.toString("utf-8");
|
|
585915
|
+
});
|
|
585916
|
+
child.on("error", (e2) => {
|
|
585917
|
+
clearTimeout(timer);
|
|
585918
|
+
reject(e2);
|
|
585919
|
+
});
|
|
585920
|
+
child.on("close", (code8) => {
|
|
585921
|
+
clearTimeout(timer);
|
|
585922
|
+
if (timedOut) return reject(new Error(`graphical sudo timed out after ${timeoutMs}ms`));
|
|
585923
|
+
resolve43({ code: code8 ?? -1, stdout, stderr, helper });
|
|
585924
|
+
});
|
|
585925
|
+
});
|
|
585926
|
+
}
|
|
585927
|
+
function shellQuote(s2) {
|
|
585928
|
+
return "'" + s2.replace(/'/g, "'\\''") + "'";
|
|
585929
|
+
}
|
|
585930
|
+
var init_graphical_sudo = __esm({
|
|
585931
|
+
"packages/cli/src/api/graphical-sudo.ts"() {
|
|
585932
|
+
"use strict";
|
|
585933
|
+
}
|
|
585934
|
+
});
|
|
585935
|
+
|
|
585775
585936
|
// packages/cli/src/api/routes-v1.ts
|
|
585776
|
-
import { existsSync as
|
|
585777
|
-
import { join as
|
|
585937
|
+
import { existsSync as existsSync103, readFileSync as readFileSync83, readdirSync as readdirSync34, statSync as statSync34 } from "node:fs";
|
|
585938
|
+
import { join as join119, resolve as pathResolve2 } from "node:path";
|
|
585778
585939
|
import { homedir as homedir40 } from "node:os";
|
|
585779
585940
|
async function tryRouteV1(ctx3) {
|
|
585780
585941
|
const { pathname, method } = ctx3;
|
|
@@ -585859,6 +586020,9 @@ async function tryRouteV1(ctx3) {
|
|
|
585859
586020
|
}
|
|
585860
586021
|
if (pathname === "/v1/share/generate" && method === "POST") return handleGenerateShare(ctx3);
|
|
585861
586022
|
if (pathname === "/v1/remote-proxy" && method === "POST") return handleRemoteProxy(ctx3);
|
|
586023
|
+
if (pathname === "/v1/tor/status" && method === "GET") return handleTorStatus(ctx3);
|
|
586024
|
+
if (pathname === "/v1/tor/enable" && method === "POST") return handleTorEnable(ctx3);
|
|
586025
|
+
if (pathname === "/v1/tor/disable" && method === "POST") return handleTorDisable(ctx3);
|
|
585862
586026
|
if (pathname === "/v1/tools" && method === "GET") {
|
|
585863
586027
|
return handleListTools(ctx3);
|
|
585864
586028
|
}
|
|
@@ -586005,11 +586169,11 @@ async function handleGetSkill(ctx3, name10) {
|
|
|
586005
586169
|
async function fallbackDiscoverSkills() {
|
|
586006
586170
|
return (_root) => {
|
|
586007
586171
|
const roots = [
|
|
586008
|
-
|
|
586172
|
+
join119(homedir40(), ".local", "share", "ai-writing-guide")
|
|
586009
586173
|
];
|
|
586010
586174
|
const out = [];
|
|
586011
586175
|
for (const root of roots) {
|
|
586012
|
-
if (!
|
|
586176
|
+
if (!existsSync103(root)) continue;
|
|
586013
586177
|
walkForSkills(root, out, 0);
|
|
586014
586178
|
}
|
|
586015
586179
|
return out;
|
|
@@ -586020,7 +586184,7 @@ function walkForSkills(dir, out, depth) {
|
|
|
586020
586184
|
try {
|
|
586021
586185
|
for (const e2 of readdirSync34(dir, { withFileTypes: true })) {
|
|
586022
586186
|
if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
|
|
586023
|
-
const p2 =
|
|
586187
|
+
const p2 = join119(dir, e2.name);
|
|
586024
586188
|
if (e2.isDirectory()) {
|
|
586025
586189
|
walkForSkills(p2, out, depth + 1);
|
|
586026
586190
|
} else if (e2.isFile() && e2.name === "SKILL.md") {
|
|
@@ -586209,7 +586373,7 @@ async function getMemoryStores() {
|
|
|
586209
586373
|
if (memoryInitTried) return null;
|
|
586210
586374
|
memoryInitTried = true;
|
|
586211
586375
|
try {
|
|
586212
|
-
const dbPath =
|
|
586376
|
+
const dbPath = join119(homedir40(), ".open-agents", "memory.db");
|
|
586213
586377
|
const sharedDb = initDb(dbPath);
|
|
586214
586378
|
memoryStoresCache = {
|
|
586215
586379
|
episode: new EpisodeStore(dbPath),
|
|
@@ -586467,7 +586631,7 @@ async function handleFilesRead(ctx3) {
|
|
|
586467
586631
|
}));
|
|
586468
586632
|
return true;
|
|
586469
586633
|
}
|
|
586470
|
-
if (!
|
|
586634
|
+
if (!existsSync103(resolved)) {
|
|
586471
586635
|
sendProblem(res, problemDetails({
|
|
586472
586636
|
type: P.notFound,
|
|
586473
586637
|
status: 404,
|
|
@@ -586732,12 +586896,12 @@ async function handleNexusStatus(ctx3) {
|
|
|
586732
586896
|
const { res, requestId } = ctx3;
|
|
586733
586897
|
try {
|
|
586734
586898
|
const statePaths = [
|
|
586735
|
-
|
|
586736
|
-
|
|
586899
|
+
join119(process.cwd(), ".oa", "nexus-peer-state.json"),
|
|
586900
|
+
join119(homedir40(), ".open-agents", "nexus-peer-cache.json")
|
|
586737
586901
|
];
|
|
586738
586902
|
const states = [];
|
|
586739
586903
|
for (const p2 of statePaths) {
|
|
586740
|
-
if (!
|
|
586904
|
+
if (!existsSync103(p2)) continue;
|
|
586741
586905
|
try {
|
|
586742
586906
|
const raw = readFileSync83(p2, "utf-8");
|
|
586743
586907
|
states.push({ source: p2, data: JSON.parse(raw) });
|
|
@@ -586766,8 +586930,8 @@ async function handleNexusStatus(ctx3) {
|
|
|
586766
586930
|
}
|
|
586767
586931
|
function loadAgentName() {
|
|
586768
586932
|
try {
|
|
586769
|
-
const p2 =
|
|
586770
|
-
if (
|
|
586933
|
+
const p2 = join119(homedir40(), ".open-agents", "agent-name");
|
|
586934
|
+
if (existsSync103(p2)) return readFileSync83(p2, "utf-8").trim();
|
|
586771
586935
|
} catch {
|
|
586772
586936
|
}
|
|
586773
586937
|
return null;
|
|
@@ -586776,12 +586940,12 @@ async function handleSponsors(ctx3) {
|
|
|
586776
586940
|
const { req: req2, res, url, requestId } = ctx3;
|
|
586777
586941
|
try {
|
|
586778
586942
|
const candidates = [
|
|
586779
|
-
|
|
586780
|
-
|
|
586943
|
+
join119(homedir40(), ".open-agents", "sponsor-cache.json"),
|
|
586944
|
+
join119(homedir40(), ".open-agents", "sponsors.json")
|
|
586781
586945
|
];
|
|
586782
586946
|
let sponsors = [];
|
|
586783
586947
|
for (const p2 of candidates) {
|
|
586784
|
-
if (!
|
|
586948
|
+
if (!existsSync103(p2)) continue;
|
|
586785
586949
|
try {
|
|
586786
586950
|
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
586787
586951
|
if (Array.isArray(raw)) {
|
|
@@ -586852,8 +587016,8 @@ async function handleEvaluate(ctx3) {
|
|
|
586852
587016
|
}));
|
|
586853
587017
|
return true;
|
|
586854
587018
|
}
|
|
586855
|
-
const jobPath =
|
|
586856
|
-
if (!
|
|
587019
|
+
const jobPath = join119(process.cwd(), ".oa", "jobs", `${runId}.json`);
|
|
587020
|
+
if (!existsSync103(jobPath)) {
|
|
586857
587021
|
sendProblem(res, problemDetails({
|
|
586858
587022
|
type: P.notFound,
|
|
586859
587023
|
status: 404,
|
|
@@ -587000,23 +587164,211 @@ async function handleMintKey(ctx3) {
|
|
|
587000
587164
|
}
|
|
587001
587165
|
return true;
|
|
587002
587166
|
}
|
|
587167
|
+
function _readStatusFile(p2) {
|
|
587168
|
+
if (!existsSync103(p2)) return null;
|
|
587169
|
+
try {
|
|
587170
|
+
const data = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587171
|
+
if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
|
|
587172
|
+
return {
|
|
587173
|
+
peerId: data.peerId,
|
|
587174
|
+
agentName: typeof data.agentName === "string" ? data.agentName : null,
|
|
587175
|
+
source: p2
|
|
587176
|
+
};
|
|
587177
|
+
}
|
|
587178
|
+
} catch {
|
|
587179
|
+
}
|
|
587180
|
+
return null;
|
|
587181
|
+
}
|
|
587003
587182
|
function resolveLocalPeerId() {
|
|
587183
|
+
const override = process.env["OA_NEXUS_DIR"];
|
|
587184
|
+
if (override) {
|
|
587185
|
+
const r2 = _readStatusFile(join119(override, "status.json"));
|
|
587186
|
+
if (r2) return r2;
|
|
587187
|
+
}
|
|
587188
|
+
try {
|
|
587189
|
+
const regPath = join119(homedir40(), ".open-agents", "nexus-registry.json");
|
|
587190
|
+
if (existsSync103(regPath)) {
|
|
587191
|
+
const reg = JSON.parse(readFileSync83(regPath, "utf-8"));
|
|
587192
|
+
const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
|
|
587193
|
+
for (const entry of entries) {
|
|
587194
|
+
const dir = typeof entry === "string" ? entry : entry?.dir;
|
|
587195
|
+
if (typeof dir === "string") {
|
|
587196
|
+
const r2 = _readStatusFile(join119(dir, "status.json"));
|
|
587197
|
+
if (r2) return r2;
|
|
587198
|
+
}
|
|
587199
|
+
}
|
|
587200
|
+
}
|
|
587201
|
+
} catch {
|
|
587202
|
+
}
|
|
587004
587203
|
const candidates = [
|
|
587005
|
-
|
|
587006
|
-
|
|
587007
|
-
|
|
587204
|
+
join119(process.cwd(), ".oa", "nexus", "status.json"),
|
|
587205
|
+
join119(homedir40(), ".oa", "nexus", "status.json"),
|
|
587206
|
+
join119(homedir40(), ".open-agents", "nexus", "status.json")
|
|
587008
587207
|
];
|
|
587009
587208
|
for (const p2 of candidates) {
|
|
587010
|
-
|
|
587011
|
-
|
|
587012
|
-
|
|
587013
|
-
|
|
587014
|
-
|
|
587209
|
+
const r2 = _readStatusFile(p2);
|
|
587210
|
+
if (r2) return r2;
|
|
587211
|
+
}
|
|
587212
|
+
const now = Date.now();
|
|
587213
|
+
if (_peerIdScanCache && now - _peerIdScanCache.ts < 6e4) {
|
|
587214
|
+
return _peerIdScanCache.result;
|
|
587215
|
+
}
|
|
587216
|
+
let scanResult = null;
|
|
587217
|
+
try {
|
|
587218
|
+
const { execSync: execSync59 } = __require("node:child_process");
|
|
587219
|
+
const cmd = `find "${homedir40()}" -maxdepth 4 -path '*/.oa/nexus/status.json' -type f 2>/dev/null | head -50`;
|
|
587220
|
+
const out = execSync59(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
587221
|
+
for (const line of out.split("\n")) {
|
|
587222
|
+
const f2 = line.trim();
|
|
587223
|
+
if (!f2) continue;
|
|
587224
|
+
const r2 = _readStatusFile(f2);
|
|
587225
|
+
if (r2) {
|
|
587226
|
+
scanResult = r2;
|
|
587227
|
+
break;
|
|
587015
587228
|
}
|
|
587016
|
-
} catch {
|
|
587017
587229
|
}
|
|
587230
|
+
} catch {
|
|
587018
587231
|
}
|
|
587019
|
-
|
|
587232
|
+
_peerIdScanCache = { ts: now, result: scanResult };
|
|
587233
|
+
return scanResult;
|
|
587234
|
+
}
|
|
587235
|
+
async function handleTorStatus(ctx3) {
|
|
587236
|
+
const { res } = ctx3;
|
|
587237
|
+
const { getLocalOnion: getLocalOnion2, torIsReachable: torIsReachable2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587238
|
+
const { detectSudoHelper: detectSudoHelper2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587239
|
+
const onion = getLocalOnion2();
|
|
587240
|
+
const reachable = await torIsReachable2();
|
|
587241
|
+
sendJson(res, 200, {
|
|
587242
|
+
onion,
|
|
587243
|
+
socks5_reachable: reachable,
|
|
587244
|
+
sudo_helper: detectSudoHelper2()
|
|
587245
|
+
});
|
|
587246
|
+
return true;
|
|
587247
|
+
}
|
|
587248
|
+
async function handleTorEnable(ctx3) {
|
|
587249
|
+
const { req: req2, res, requestId } = ctx3;
|
|
587250
|
+
const reqAuth = req2;
|
|
587251
|
+
if (reqAuth._authScope !== "admin") {
|
|
587252
|
+
sendProblem(res, problemDetails({
|
|
587253
|
+
type: P.forbidden,
|
|
587254
|
+
status: 403,
|
|
587255
|
+
title: "Admin scope required",
|
|
587256
|
+
detail: "Tor setup requires elevated privileges; only admin keys can request it.",
|
|
587257
|
+
instance: requestId
|
|
587258
|
+
}));
|
|
587259
|
+
return true;
|
|
587260
|
+
}
|
|
587261
|
+
const { getLocalOnion: getLocalOnion2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
|
|
587262
|
+
if (getLocalOnion2()) {
|
|
587263
|
+
sendJson(res, 409, {
|
|
587264
|
+
status: "already_configured",
|
|
587265
|
+
onion: getLocalOnion2(),
|
|
587266
|
+
_note: "Tor hidden service already exists. Use /v1/tor/disable to remove."
|
|
587267
|
+
});
|
|
587268
|
+
return true;
|
|
587269
|
+
}
|
|
587270
|
+
let scriptPath2 = null;
|
|
587271
|
+
try {
|
|
587272
|
+
const candidates = [
|
|
587273
|
+
join119(process.cwd(), "scripts", "tor", "tor_setup.sh"),
|
|
587274
|
+
join119(__dirname, "..", "..", "scripts", "tor", "tor_setup.sh"),
|
|
587275
|
+
join119(__dirname, "..", "scripts", "tor", "tor_setup.sh")
|
|
587276
|
+
];
|
|
587277
|
+
for (const p2 of candidates) {
|
|
587278
|
+
if (existsSync103(p2)) {
|
|
587279
|
+
scriptPath2 = p2;
|
|
587280
|
+
break;
|
|
587281
|
+
}
|
|
587282
|
+
}
|
|
587283
|
+
if (!scriptPath2) {
|
|
587284
|
+
const { execSync: execSync59 } = __require("node:child_process");
|
|
587285
|
+
const root = execSync59("npm root -g", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
587286
|
+
const p2 = join119(root, "open-agents-ai", "scripts", "tor", "tor_setup.sh");
|
|
587287
|
+
if (existsSync103(p2)) scriptPath2 = p2;
|
|
587288
|
+
}
|
|
587289
|
+
} catch {
|
|
587290
|
+
}
|
|
587291
|
+
if (!scriptPath2) {
|
|
587292
|
+
sendProblem(res, problemDetails({
|
|
587293
|
+
type: P.internalError,
|
|
587294
|
+
status: 500,
|
|
587295
|
+
title: "tor_setup.sh not found",
|
|
587296
|
+
detail: "Could not locate the bundled Tor setup script.",
|
|
587297
|
+
instance: requestId
|
|
587298
|
+
}));
|
|
587299
|
+
return true;
|
|
587300
|
+
}
|
|
587301
|
+
const { detectSudoHelper: detectSudoHelper2, runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587302
|
+
const helper = detectSudoHelper2();
|
|
587303
|
+
if (!helper) {
|
|
587304
|
+
sendProblem(res, problemDetails({
|
|
587305
|
+
type: P.internalError,
|
|
587306
|
+
status: 503,
|
|
587307
|
+
title: "No graphical sudo helper",
|
|
587308
|
+
detail: "Install one of: pkexec (PolKit), zenity, kdialog, or ssh-askpass — then retry.",
|
|
587309
|
+
instance: requestId
|
|
587310
|
+
}));
|
|
587311
|
+
return true;
|
|
587312
|
+
}
|
|
587313
|
+
sendJson(res, 202, {
|
|
587314
|
+
status: "accepted",
|
|
587315
|
+
helper,
|
|
587316
|
+
script: scriptPath2,
|
|
587317
|
+
poll: "/v1/tor/status"
|
|
587318
|
+
});
|
|
587319
|
+
const apiPort = req2.socket?.localPort || parseInt(process.env["OA_API_PORT"] || "11435", 10);
|
|
587320
|
+
runGraphicalSudo2({
|
|
587321
|
+
scriptPath: scriptPath2,
|
|
587322
|
+
env: { OA_API_PORT: String(apiPort) },
|
|
587323
|
+
description: "Open Agents needs admin access to install Tor and configure a hidden service"
|
|
587324
|
+
}).then((r2) => {
|
|
587325
|
+
if (r2.code !== 0) {
|
|
587326
|
+
console.warn(`[tor-enable] sudo helper ${r2.helper} exited ${r2.code}: ${r2.stderr.slice(-300)}`);
|
|
587327
|
+
}
|
|
587328
|
+
}).catch((e2) => {
|
|
587329
|
+
console.warn(`[tor-enable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`);
|
|
587330
|
+
});
|
|
587331
|
+
return true;
|
|
587332
|
+
}
|
|
587333
|
+
async function handleTorDisable(ctx3) {
|
|
587334
|
+
const { req: req2, res, requestId } = ctx3;
|
|
587335
|
+
const reqAuth = req2;
|
|
587336
|
+
if (reqAuth._authScope !== "admin") {
|
|
587337
|
+
sendProblem(res, problemDetails({
|
|
587338
|
+
type: P.forbidden,
|
|
587339
|
+
status: 403,
|
|
587340
|
+
title: "Admin scope required",
|
|
587341
|
+
detail: "Tor teardown requires admin scope.",
|
|
587342
|
+
instance: requestId
|
|
587343
|
+
}));
|
|
587344
|
+
return true;
|
|
587345
|
+
}
|
|
587346
|
+
let scriptPath2 = null;
|
|
587347
|
+
const candidates = [
|
|
587348
|
+
join119(process.cwd(), "scripts", "tor", "destroy_tor.sh"),
|
|
587349
|
+
join119(__dirname, "..", "..", "scripts", "tor", "destroy_tor.sh"),
|
|
587350
|
+
join119(__dirname, "..", "scripts", "tor", "destroy_tor.sh")
|
|
587351
|
+
];
|
|
587352
|
+
for (const p2 of candidates) {
|
|
587353
|
+
if (existsSync103(p2)) {
|
|
587354
|
+
scriptPath2 = p2;
|
|
587355
|
+
break;
|
|
587356
|
+
}
|
|
587357
|
+
}
|
|
587358
|
+
if (!scriptPath2) {
|
|
587359
|
+
sendProblem(res, problemDetails({
|
|
587360
|
+
type: P.internalError,
|
|
587361
|
+
status: 500,
|
|
587362
|
+
title: "destroy_tor.sh not found",
|
|
587363
|
+
detail: "Bundled teardown script missing.",
|
|
587364
|
+
instance: requestId
|
|
587365
|
+
}));
|
|
587366
|
+
return true;
|
|
587367
|
+
}
|
|
587368
|
+
const { runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
|
|
587369
|
+
sendJson(res, 202, { status: "accepted", script: scriptPath2 });
|
|
587370
|
+
runGraphicalSudo2({ scriptPath: scriptPath2, description: "Open Agents needs admin access to remove the Tor hidden service" }).catch((e2) => console.warn(`[tor-disable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`));
|
|
587371
|
+
return true;
|
|
587020
587372
|
}
|
|
587021
587373
|
async function handleGenerateShare(ctx3) {
|
|
587022
587374
|
const { req: req2, res, requestId } = ctx3;
|
|
@@ -587085,9 +587437,11 @@ async function handleGenerateShare(ctx3) {
|
|
|
587085
587437
|
if (onion) plainParams.push(`oa-onion=${encodeURIComponent(onion)}`);
|
|
587086
587438
|
plainParams.push(`oa-share-label=${encodeURIComponent(label)}`);
|
|
587087
587439
|
const plainUrl = `${scheme}://${hostPort}/?${plainParams.join("&")}`;
|
|
587440
|
+
const torShareUrl = onion ? `oa-share-tor://${onion}#${fullKey}` : null;
|
|
587088
587441
|
sendJson(res, 201, {
|
|
587089
587442
|
shareUrl,
|
|
587090
587443
|
plainUrl,
|
|
587444
|
+
torShareUrl,
|
|
587091
587445
|
mode,
|
|
587092
587446
|
peerId: peerInfo?.peerId || null,
|
|
587093
587447
|
onion: onion || null,
|
|
@@ -587103,7 +587457,7 @@ async function handleGenerateShare(ctx3) {
|
|
|
587103
587457
|
tor: !!onion,
|
|
587104
587458
|
direct: !peerInfo
|
|
587105
587459
|
},
|
|
587106
|
-
_note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor:
|
|
587460
|
+
_note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor: run `oa tor enable`." : onion ? "Globally reachable via Tor only (.onion). Start nexus for libp2p tier." : "Nexus offline + no Tor — URL is direct-HTTP only (LAN/VPN reach)."
|
|
587107
587461
|
});
|
|
587108
587462
|
} catch (err) {
|
|
587109
587463
|
sendProblem(res, problemDetails({
|
|
@@ -587161,13 +587515,13 @@ async function handleRemoteProxy(ctx3) {
|
|
|
587161
587515
|
return true;
|
|
587162
587516
|
}
|
|
587163
587517
|
const nexusCandidates = [
|
|
587164
|
-
|
|
587165
|
-
|
|
587166
|
-
|
|
587518
|
+
join119(process.cwd(), ".oa", "nexus"),
|
|
587519
|
+
join119(homedir40(), ".oa", "nexus"),
|
|
587520
|
+
join119(homedir40(), ".open-agents", "nexus")
|
|
587167
587521
|
];
|
|
587168
587522
|
let nexusDirPath = null;
|
|
587169
587523
|
for (const p2 of nexusCandidates) {
|
|
587170
|
-
if (
|
|
587524
|
+
if (existsSync103(join119(p2, "status.json"))) {
|
|
587171
587525
|
nexusDirPath = p2;
|
|
587172
587526
|
break;
|
|
587173
587527
|
}
|
|
@@ -587263,7 +587617,7 @@ async function handleRemoteProxy(ctx3) {
|
|
|
587263
587617
|
}));
|
|
587264
587618
|
return true;
|
|
587265
587619
|
}
|
|
587266
|
-
const streamFile =
|
|
587620
|
+
const streamFile = join119(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
|
|
587267
587621
|
try {
|
|
587268
587622
|
const { writeFileSync: _wfs } = await import("node:fs");
|
|
587269
587623
|
_wfs(streamFile, "");
|
|
@@ -587706,14 +588060,14 @@ async function handleListEngines(ctx3) {
|
|
|
587706
588060
|
const home = homedir40();
|
|
587707
588061
|
sendJson(res, 200, {
|
|
587708
588062
|
engines: [
|
|
587709
|
-
{ name: "dream", state_file:
|
|
587710
|
-
{ name: "bless", state_file:
|
|
587711
|
-
{ name: "call", state_file:
|
|
587712
|
-
{ name: "listen", state_file:
|
|
587713
|
-
{ name: "telegram", state_file:
|
|
587714
|
-
{ name: "expose", state_file:
|
|
587715
|
-
{ name: "nexus", state_file:
|
|
587716
|
-
{ name: "ipfs", state_file:
|
|
588063
|
+
{ name: "dream", state_file: join119(process.cwd(), ".oa", "dreams"), controllable_via: "SSE + slash commands" },
|
|
588064
|
+
{ name: "bless", state_file: join119(process.cwd(), ".oa", "bless-state.json"), controllable_via: "slash commands" },
|
|
588065
|
+
{ name: "call", state_file: join119(process.cwd(), ".oa", "call-state.json"), controllable_via: "slash commands" },
|
|
588066
|
+
{ name: "listen", state_file: join119(process.cwd(), ".oa", "listen-state.json"), controllable_via: "slash commands" },
|
|
588067
|
+
{ name: "telegram", state_file: join119(home, ".open-agents", "telegram-state.json"), controllable_via: "slash commands" },
|
|
588068
|
+
{ name: "expose", state_file: join119(process.cwd(), ".oa", "expose-state.json"), controllable_via: "/expose commands" },
|
|
588069
|
+
{ name: "nexus", state_file: join119(home, ".open-agents", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
|
|
588070
|
+
{ name: "ipfs", state_file: join119(process.cwd(), ".oa", "ipfs"), controllable_via: "slash commands" }
|
|
587717
588071
|
],
|
|
587718
588072
|
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."
|
|
587719
588073
|
});
|
|
@@ -587796,21 +588150,21 @@ async function tryAimsRoute(ctx3) {
|
|
|
587796
588150
|
return false;
|
|
587797
588151
|
}
|
|
587798
588152
|
function aimsDir() {
|
|
587799
|
-
return
|
|
588153
|
+
return join119(homedir40(), ".open-agents", "aims");
|
|
587800
588154
|
}
|
|
587801
588155
|
function readAimsFile(name10, fallback) {
|
|
587802
588156
|
try {
|
|
587803
|
-
const p2 =
|
|
587804
|
-
if (
|
|
588157
|
+
const p2 = join119(aimsDir(), name10);
|
|
588158
|
+
if (existsSync103(p2)) return JSON.parse(readFileSync83(p2, "utf-8"));
|
|
587805
588159
|
} catch {
|
|
587806
588160
|
}
|
|
587807
588161
|
return fallback;
|
|
587808
588162
|
}
|
|
587809
588163
|
function writeAimsFile(name10, data) {
|
|
587810
588164
|
const dir = aimsDir();
|
|
587811
|
-
const { mkdirSync:
|
|
587812
|
-
|
|
587813
|
-
const finalPath =
|
|
588165
|
+
const { mkdirSync: mkdirSync68, writeFileSync: wf, renameSync: rn } = __require("node:fs");
|
|
588166
|
+
mkdirSync68(dir, { recursive: true });
|
|
588167
|
+
const finalPath = join119(dir, name10);
|
|
587814
588168
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
587815
588169
|
try {
|
|
587816
588170
|
wf(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
@@ -588140,10 +588494,10 @@ async function handleAimsSuppliers(ctx3) {
|
|
|
588140
588494
|
}
|
|
588141
588495
|
];
|
|
588142
588496
|
const sponsorPaths = [
|
|
588143
|
-
|
|
588497
|
+
join119(homedir40(), ".open-agents", "sponsor-cache.json")
|
|
588144
588498
|
];
|
|
588145
588499
|
for (const p2 of sponsorPaths) {
|
|
588146
|
-
if (!
|
|
588500
|
+
if (!existsSync103(p2)) continue;
|
|
588147
588501
|
try {
|
|
588148
588502
|
const raw = JSON.parse(readFileSync83(p2, "utf-8"));
|
|
588149
588503
|
const list = Array.isArray(raw) ? raw : raw?.sponsors ?? [];
|
|
@@ -588287,7 +588641,7 @@ async function handleAimsConfigHistory(ctx3) {
|
|
|
588287
588641
|
return true;
|
|
588288
588642
|
}
|
|
588289
588643
|
}
|
|
588290
|
-
var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _aimsLocks;
|
|
588644
|
+
var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _peerIdScanCache, _aimsLocks;
|
|
588291
588645
|
var init_routes_v1 = __esm({
|
|
588292
588646
|
"packages/cli/src/api/routes-v1.ts"() {
|
|
588293
588647
|
"use strict";
|
|
@@ -588313,6 +588667,7 @@ var init_routes_v1 = __esm({
|
|
|
588313
588667
|
memoryStoresCache = null;
|
|
588314
588668
|
memoryInitTried = false;
|
|
588315
588669
|
FILE_READ_MAX_BYTES = 2 * 1024 * 1024;
|
|
588670
|
+
_peerIdScanCache = null;
|
|
588316
588671
|
_aimsLocks = /* @__PURE__ */ new Map();
|
|
588317
588672
|
}
|
|
588318
588673
|
});
|
|
@@ -591669,6 +592024,19 @@ function _looksLikePeerId(s) {
|
|
|
591669
592024
|
function parseShareInput(raw) {
|
|
591670
592025
|
const v = String(raw || '').trim();
|
|
591671
592026
|
if (!v) return null;
|
|
592027
|
+
// oa-share-tor scheme — Tor-only routing via SOCKS5 to <onion>:80
|
|
592028
|
+
if (v.toLowerCase().startsWith('oa-share-tor://')) {
|
|
592029
|
+
const after = v.slice('oa-share-tor://'.length);
|
|
592030
|
+
const hashIdx = after.indexOf('#');
|
|
592031
|
+
if (hashIdx < 0) return null;
|
|
592032
|
+
const onionRaw = after.slice(0, hashIdx);
|
|
592033
|
+
// Strip optional :port suffix; we always dial 80 since hidden services
|
|
592034
|
+
// are configured to forward 80 → local API per the leek_messenger setup.
|
|
592035
|
+
const onion = onionRaw.split(':')[0];
|
|
592036
|
+
const key = after.slice(hashIdx + 1);
|
|
592037
|
+
if (!onion.endsWith('.onion') || !key) return null;
|
|
592038
|
+
return { peerId: null, onion, host: null, key, scheme: 'tor' };
|
|
592039
|
+
}
|
|
591672
592040
|
// oa-share scheme — custom parser since URL() doesn't always honor it.
|
|
591673
592041
|
if (v.toLowerCase().startsWith('oa-share://')) {
|
|
591674
592042
|
const after = v.slice('oa-share://'.length);
|
|
@@ -591829,10 +592197,25 @@ async function generateShareUrl() {
|
|
|
591829
592197
|
const j = await r.json();
|
|
591830
592198
|
const safeShare = escapeHtml(j.shareUrl || '');
|
|
591831
592199
|
const safePlain = escapeHtml(j.plainUrl || '');
|
|
592200
|
+
const safeTor = escapeHtml(j.torShareUrl || '');
|
|
592201
|
+
const torRow = j.torShareUrl
|
|
592202
|
+
? '<div style="margin:6px 0">' +
|
|
592203
|
+
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">tor-only URL (.onion routed via SOCKS5 — works through any firewall)</label>' +
|
|
592204
|
+
'<div style="display:flex;gap:6px;align-items:center">' +
|
|
592205
|
+
'<input readonly value="' + safeTor + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
|
|
592206
|
+
'<button type="button" onclick="copyShareUrl(\\'tor\\')" style="font-size:0.74rem">copy</button>' +
|
|
592207
|
+
'</div>' +
|
|
592208
|
+
'</div>'
|
|
592209
|
+
: '<div style="margin:8px 0;padding:8px;background:var(--color-bg-input);border:1px dashed var(--color-border);border-radius:var(--radius-sm)">' +
|
|
592210
|
+
'<div style="font-size:0.74rem;margin-bottom:4px">Tor (.onion) is not configured on this OA.</div>' +
|
|
592211
|
+
'<div style="font-size:0.68rem;color:var(--color-fg-muted);margin-bottom:6px">Enable Tor for global reach when libp2p fails. Asks for sudo via your system password dialog.</div>' +
|
|
592212
|
+
'<button type="button" onclick="enableTorShare()" style="font-size:0.74rem;background:var(--color-accent);color:#fff;border:none;padding:4px 12px;border-radius:var(--radius-sm);cursor:pointer">enable Tor</button>' +
|
|
592213
|
+
'<span id="enable-tor-status" style="font-size:0.68rem;margin-left:8px;color:var(--color-fg-muted)"></span>' +
|
|
592214
|
+
'</div>';
|
|
591832
592215
|
out.innerHTML =
|
|
591833
592216
|
'<div style="font-weight:500;margin-bottom:6px;color:var(--color-success)">✓ Share URL generated — hand off to remote</div>' +
|
|
591834
592217
|
'<div style="margin:6px 0">' +
|
|
591835
|
-
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (compact, recommended for OA-to-OA)</label>' +
|
|
592218
|
+
'<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (libp2p, compact, recommended for OA-to-OA)</label>' +
|
|
591836
592219
|
'<div style="display:flex;gap:6px;align-items:center">' +
|
|
591837
592220
|
'<input readonly value="' + safeShare + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
|
|
591838
592221
|
'<button type="button" onclick="copyShareUrl(\\'oa-share\\')" style="font-size:0.74rem">copy</button>' +
|
|
@@ -591845,17 +592228,22 @@ async function generateShareUrl() {
|
|
|
591845
592228
|
'<button type="button" onclick="copyShareUrl(\\'plain\\')" style="font-size:0.74rem">copy</button>' +
|
|
591846
592229
|
'</div>' +
|
|
591847
592230
|
'</div>' +
|
|
591848
|
-
|
|
592231
|
+
torRow +
|
|
592232
|
+
'<p style="font-size:0.68rem;color:var(--color-fg-muted);margin:6px 0 0">Note: these URLs contain the full secret. Anyone with one can use this OA. To revoke: Advanced settings → keys → revoke prefix <code>' + escapeHtml(j.keyPrefix || '') + '</code>.</p>';
|
|
591849
592233
|
// Stash for the copy buttons + add to recent.
|
|
591850
592234
|
window.__oaLastShareUrl = j.shareUrl;
|
|
591851
592235
|
window.__oaLastPlainUrl = j.plainUrl;
|
|
592236
|
+
window.__oaLastTorUrl = j.torShareUrl || null;
|
|
591852
592237
|
saveRecentKey({ key: j.key, host: j.host + ':' + j.port, label: j.label || ('shared ' + j.host) });
|
|
591853
592238
|
} catch (e) {
|
|
591854
592239
|
out.innerHTML = '<div style="color:var(--color-error)">✗ ' + escapeHtml(e && e.message ? e.message : String(e)) + '</div>';
|
|
591855
592240
|
}
|
|
591856
592241
|
}
|
|
591857
592242
|
function copyShareUrl(which) {
|
|
591858
|
-
|
|
592243
|
+
let v;
|
|
592244
|
+
if (which === 'plain') v = window.__oaLastPlainUrl;
|
|
592245
|
+
else if (which === 'tor') v = window.__oaLastTorUrl;
|
|
592246
|
+
else v = window.__oaLastShareUrl;
|
|
591859
592247
|
if (!v) return;
|
|
591860
592248
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
591861
592249
|
navigator.clipboard.writeText(v).then(
|
|
@@ -591875,6 +592263,46 @@ function fallbackCopy(v) {
|
|
|
591875
592263
|
window.generateShareUrl = generateShareUrl;
|
|
591876
592264
|
window.copyShareUrl = copyShareUrl;
|
|
591877
592265
|
|
|
592266
|
+
// ─── Enable Tor (graphical sudo) ────────────────────────────────────────
|
|
592267
|
+
async function enableTorShare() {
|
|
592268
|
+
const status = document.getElementById('enable-tor-status');
|
|
592269
|
+
if (status) { status.textContent = 'launching graphical sudo prompt…'; status.style.color = 'var(--color-fg-muted)'; }
|
|
592270
|
+
try {
|
|
592271
|
+
const r = await fetch('/v1/tor/enable', {
|
|
592272
|
+
method: 'POST',
|
|
592273
|
+
headers: { ...headers(), 'Content-Type': 'application/json' },
|
|
592274
|
+
body: '{}',
|
|
592275
|
+
});
|
|
592276
|
+
const j = await r.json().catch(() => ({}));
|
|
592277
|
+
if (r.status === 202) {
|
|
592278
|
+
if (status) {
|
|
592279
|
+
status.textContent = 'started — waiting for hidden service…';
|
|
592280
|
+
status.style.color = 'var(--color-accent)';
|
|
592281
|
+
}
|
|
592282
|
+
// Poll up to 90s for the .onion to appear
|
|
592283
|
+
for (let i = 0; i < 30; i++) {
|
|
592284
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
592285
|
+
const s = await fetch('/v1/tor/status', { headers: headers() }).then(x => x.json()).catch(() => ({}));
|
|
592286
|
+
if (s.onion) {
|
|
592287
|
+
if (status) { status.textContent = '✓ Tor enabled: ' + s.onion; status.style.color = 'var(--color-success)'; }
|
|
592288
|
+
// Re-generate share URL to pick up the .onion field
|
|
592289
|
+
setTimeout(() => generateShareUrl(), 500);
|
|
592290
|
+
return;
|
|
592291
|
+
}
|
|
592292
|
+
}
|
|
592293
|
+
if (status) { status.textContent = '⚠ setup ran but no .onion appeared. Check journalctl -u tor for errors.'; status.style.color = 'var(--color-warning)'; }
|
|
592294
|
+
} else if (r.status === 409) {
|
|
592295
|
+
if (status) { status.textContent = '✓ already enabled — re-generating'; status.style.color = 'var(--color-success)'; }
|
|
592296
|
+
setTimeout(() => generateShareUrl(), 500);
|
|
592297
|
+
} else {
|
|
592298
|
+
if (status) { status.textContent = '✗ ' + (j.detail || ('HTTP ' + r.status)); status.style.color = 'var(--color-error)'; }
|
|
592299
|
+
}
|
|
592300
|
+
} catch (e) {
|
|
592301
|
+
if (status) { status.textContent = '✗ ' + (e && e.message ? e.message : String(e)); status.style.color = 'var(--color-error)'; }
|
|
592302
|
+
}
|
|
592303
|
+
}
|
|
592304
|
+
window.enableTorShare = enableTorShare;
|
|
592305
|
+
|
|
591878
592306
|
// ─── Remote-state helpers (visual indicator on the key button) ───────
|
|
591879
592307
|
// When localStorage carries oa.remoteHost we are in REMOTE mode: the
|
|
591880
592308
|
// key was loaded from an oa-share URL or via on-load ?oa-key=. The key
|
|
@@ -596752,14 +597180,14 @@ var init_auth_oidc = __esm({
|
|
|
596752
597180
|
});
|
|
596753
597181
|
|
|
596754
597182
|
// packages/cli/src/api/usage-tracker.ts
|
|
596755
|
-
import { mkdirSync as
|
|
596756
|
-
import { join as
|
|
597183
|
+
import { mkdirSync as mkdirSync61, readFileSync as readFileSync84, writeFileSync as writeFileSync53, existsSync as existsSync104 } from "node:fs";
|
|
597184
|
+
import { join as join120 } from "node:path";
|
|
596757
597185
|
function initUsageTracker(oaDir) {
|
|
596758
|
-
const dir =
|
|
596759
|
-
|
|
596760
|
-
usageFile =
|
|
597186
|
+
const dir = join120(oaDir, "usage");
|
|
597187
|
+
mkdirSync61(dir, { recursive: true });
|
|
597188
|
+
usageFile = join120(dir, "token-usage.json");
|
|
596761
597189
|
try {
|
|
596762
|
-
if (
|
|
597190
|
+
if (existsSync104(usageFile)) {
|
|
596763
597191
|
store = JSON.parse(readFileSync84(usageFile, "utf-8"));
|
|
596764
597192
|
}
|
|
596765
597193
|
} catch {
|
|
@@ -596796,7 +597224,7 @@ function flush2() {
|
|
|
596796
597224
|
if (!initialized2 || !dirty) return;
|
|
596797
597225
|
try {
|
|
596798
597226
|
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
596799
|
-
|
|
597227
|
+
writeFileSync53(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
596800
597228
|
dirty = false;
|
|
596801
597229
|
} catch {
|
|
596802
597230
|
}
|
|
@@ -596824,24 +597252,24 @@ var init_usage_tracker = __esm({
|
|
|
596824
597252
|
});
|
|
596825
597253
|
|
|
596826
597254
|
// packages/cli/src/api/profiles.ts
|
|
596827
|
-
import { existsSync as
|
|
596828
|
-
import { join as
|
|
597255
|
+
import { existsSync as existsSync105, readFileSync as readFileSync85, writeFileSync as writeFileSync54, mkdirSync as mkdirSync62, readdirSync as readdirSync35, unlinkSync as unlinkSync23 } from "node:fs";
|
|
597256
|
+
import { join as join121 } from "node:path";
|
|
596829
597257
|
import { homedir as homedir41 } from "node:os";
|
|
596830
597258
|
import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes22, scryptSync as scryptSync3 } from "node:crypto";
|
|
596831
597259
|
function globalProfileDir() {
|
|
596832
|
-
return
|
|
597260
|
+
return join121(homedir41(), ".open-agents", "profiles");
|
|
596833
597261
|
}
|
|
596834
597262
|
function projectProfileDir(projectDir2) {
|
|
596835
|
-
return
|
|
597263
|
+
return join121(projectDir2 || process.cwd(), ".oa", "profiles");
|
|
596836
597264
|
}
|
|
596837
597265
|
function listProfiles(projectDir2) {
|
|
596838
597266
|
const result = [];
|
|
596839
597267
|
const seen = /* @__PURE__ */ new Set();
|
|
596840
597268
|
const projDir = projectProfileDir(projectDir2);
|
|
596841
|
-
if (
|
|
597269
|
+
if (existsSync105(projDir)) {
|
|
596842
597270
|
for (const f2 of readdirSync35(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596843
597271
|
try {
|
|
596844
|
-
const raw = JSON.parse(readFileSync85(
|
|
597272
|
+
const raw = JSON.parse(readFileSync85(join121(projDir, f2), "utf8"));
|
|
596845
597273
|
const name10 = f2.replace(".json", "");
|
|
596846
597274
|
seen.add(name10);
|
|
596847
597275
|
result.push({
|
|
@@ -596855,12 +597283,12 @@ function listProfiles(projectDir2) {
|
|
|
596855
597283
|
}
|
|
596856
597284
|
}
|
|
596857
597285
|
const globDir = globalProfileDir();
|
|
596858
|
-
if (
|
|
597286
|
+
if (existsSync105(globDir)) {
|
|
596859
597287
|
for (const f2 of readdirSync35(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
596860
597288
|
const name10 = f2.replace(".json", "");
|
|
596861
597289
|
if (seen.has(name10)) continue;
|
|
596862
597290
|
try {
|
|
596863
|
-
const raw = JSON.parse(readFileSync85(
|
|
597291
|
+
const raw = JSON.parse(readFileSync85(join121(globDir, f2), "utf8"));
|
|
596864
597292
|
result.push({
|
|
596865
597293
|
name: name10,
|
|
596866
597294
|
description: raw.description || "",
|
|
@@ -596875,9 +597303,9 @@ function listProfiles(projectDir2) {
|
|
|
596875
597303
|
}
|
|
596876
597304
|
function loadProfile(name10, password, projectDir2) {
|
|
596877
597305
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596878
|
-
const projPath =
|
|
596879
|
-
const globPath =
|
|
596880
|
-
const filePath =
|
|
597306
|
+
const projPath = join121(projectProfileDir(projectDir2), `${sanitized}.json`);
|
|
597307
|
+
const globPath = join121(globalProfileDir(), `${sanitized}.json`);
|
|
597308
|
+
const filePath = existsSync105(projPath) ? projPath : existsSync105(globPath) ? globPath : null;
|
|
596881
597309
|
if (!filePath) return null;
|
|
596882
597310
|
const raw = JSON.parse(readFileSync85(filePath, "utf8"));
|
|
596883
597311
|
if (raw.encrypted === true) {
|
|
@@ -596888,23 +597316,23 @@ function loadProfile(name10, password, projectDir2) {
|
|
|
596888
597316
|
}
|
|
596889
597317
|
function saveProfile(profile, password, scope = "global", projectDir2) {
|
|
596890
597318
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596891
|
-
|
|
597319
|
+
mkdirSync62(dir, { recursive: true });
|
|
596892
597320
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596893
|
-
const filePath =
|
|
597321
|
+
const filePath = join121(dir, `${sanitized}.json`);
|
|
596894
597322
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
596895
597323
|
if (password) {
|
|
596896
597324
|
const encrypted = encryptProfile(profile, password);
|
|
596897
|
-
|
|
597325
|
+
writeFileSync54(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
596898
597326
|
} else {
|
|
596899
597327
|
profile.encrypted = false;
|
|
596900
|
-
|
|
597328
|
+
writeFileSync54(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
|
|
596901
597329
|
}
|
|
596902
597330
|
}
|
|
596903
597331
|
function deleteProfile(name10, scope = "global", projectDir2) {
|
|
596904
597332
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
596905
597333
|
const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
|
|
596906
|
-
const filePath =
|
|
596907
|
-
if (
|
|
597334
|
+
const filePath = join121(dir, `${sanitized}.json`);
|
|
597335
|
+
if (existsSync105(filePath)) {
|
|
596908
597336
|
unlinkSync23(filePath);
|
|
596909
597337
|
return true;
|
|
596910
597338
|
}
|
|
@@ -597018,24 +597446,24 @@ var init_profiles = __esm({
|
|
|
597018
597446
|
});
|
|
597019
597447
|
|
|
597020
597448
|
// packages/cli/src/docker.ts
|
|
597021
|
-
import { execSync as execSync56, spawn as
|
|
597022
|
-
import { existsSync as
|
|
597023
|
-
import { join as
|
|
597449
|
+
import { execSync as execSync56, spawn as spawn25 } from "node:child_process";
|
|
597450
|
+
import { existsSync as existsSync106, mkdirSync as mkdirSync63, writeFileSync as writeFileSync55 } from "node:fs";
|
|
597451
|
+
import { join as join122, resolve as resolve37, dirname as dirname35 } from "node:path";
|
|
597024
597452
|
import { homedir as homedir42 } from "node:os";
|
|
597025
597453
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
597026
597454
|
function getDockerDir() {
|
|
597027
597455
|
try {
|
|
597028
597456
|
if (typeof __dirname !== "undefined") {
|
|
597029
|
-
return
|
|
597457
|
+
return join122(__dirname, "..", "..", "..", "docker");
|
|
597030
597458
|
}
|
|
597031
597459
|
} catch {
|
|
597032
597460
|
}
|
|
597033
597461
|
try {
|
|
597034
597462
|
const thisDir = dirname35(fileURLToPath16(import.meta.url));
|
|
597035
|
-
return
|
|
597463
|
+
return join122(thisDir, "..", "..", "..", "docker");
|
|
597036
597464
|
} catch {
|
|
597037
597465
|
}
|
|
597038
|
-
return
|
|
597466
|
+
return join122(process.cwd(), "docker");
|
|
597039
597467
|
}
|
|
597040
597468
|
function isDockerAvailable() {
|
|
597041
597469
|
try {
|
|
@@ -597166,11 +597594,11 @@ async function ensureOaImage(force = false) {
|
|
|
597166
597594
|
}
|
|
597167
597595
|
let buildContext;
|
|
597168
597596
|
const dockerDir = getDockerDir();
|
|
597169
|
-
if (
|
|
597597
|
+
if (existsSync106(join122(dockerDir, "Dockerfile"))) {
|
|
597170
597598
|
buildContext = dockerDir;
|
|
597171
597599
|
} else {
|
|
597172
|
-
buildContext =
|
|
597173
|
-
|
|
597600
|
+
buildContext = join122(homedir42(), ".oa", "docker-build");
|
|
597601
|
+
mkdirSync63(buildContext, { recursive: true });
|
|
597174
597602
|
writeDockerfiles(buildContext);
|
|
597175
597603
|
}
|
|
597176
597604
|
try {
|
|
@@ -597244,8 +597672,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
|
|
|
597244
597672
|
if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
|
|
597245
597673
|
exec "$@"
|
|
597246
597674
|
`;
|
|
597247
|
-
|
|
597248
|
-
|
|
597675
|
+
writeFileSync55(join122(dir, "Dockerfile"), dockerfile);
|
|
597676
|
+
writeFileSync55(join122(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
597249
597677
|
}
|
|
597250
597678
|
function hasNvidiaGpu() {
|
|
597251
597679
|
try {
|
|
@@ -597299,7 +597727,7 @@ function runInContainer(opts) {
|
|
|
597299
597727
|
if (opts.maxTurns) oaArgs.push("--max-turns", String(opts.maxTurns));
|
|
597300
597728
|
if (opts.timeoutS) oaArgs.push("--timeout", String(opts.timeoutS));
|
|
597301
597729
|
args.push(...oaArgs);
|
|
597302
|
-
return
|
|
597730
|
+
return spawn25("docker", args, {
|
|
597303
597731
|
stdio: ["ignore", "pipe", "pipe"]
|
|
597304
597732
|
});
|
|
597305
597733
|
}
|
|
@@ -597498,23 +597926,23 @@ import * as http5 from "node:http";
|
|
|
597498
597926
|
import * as https3 from "node:https";
|
|
597499
597927
|
import { createRequire as createRequire5 } from "node:module";
|
|
597500
597928
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
597501
|
-
import { dirname as dirname36, join as
|
|
597929
|
+
import { dirname as dirname36, join as join123, resolve as resolve38 } from "node:path";
|
|
597502
597930
|
import { homedir as homedir43 } from "node:os";
|
|
597503
|
-
import { spawn as
|
|
597504
|
-
import { mkdirSync as
|
|
597931
|
+
import { spawn as spawn26, execSync as execSync57 } from "node:child_process";
|
|
597932
|
+
import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync56, readFileSync as readFileSync86, readdirSync as readdirSync36, existsSync as existsSync107, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
|
|
597505
597933
|
import { randomBytes as randomBytes23, randomUUID as randomUUID16 } from "node:crypto";
|
|
597506
597934
|
import { createHash as createHash19 } from "node:crypto";
|
|
597507
597935
|
function getVersion3() {
|
|
597508
597936
|
try {
|
|
597509
597937
|
const thisDir = dirname36(fileURLToPath17(import.meta.url));
|
|
597510
597938
|
const candidates = [
|
|
597511
|
-
|
|
597512
|
-
|
|
597513
|
-
|
|
597939
|
+
join123(thisDir, "..", "package.json"),
|
|
597940
|
+
join123(thisDir, "..", "..", "package.json"),
|
|
597941
|
+
join123(thisDir, "..", "..", "..", "package.json")
|
|
597514
597942
|
];
|
|
597515
597943
|
for (const pkgPath of candidates) {
|
|
597516
597944
|
try {
|
|
597517
|
-
if (!
|
|
597945
|
+
if (!existsSync107(pkgPath)) continue;
|
|
597518
597946
|
const pkg = require3(pkgPath);
|
|
597519
597947
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
597520
597948
|
return pkg.version ?? "0.0.0";
|
|
@@ -597716,8 +598144,8 @@ function isOriginAllowed(origin) {
|
|
|
597716
598144
|
if (!origin) return true;
|
|
597717
598145
|
let accessMode = (process.env["OA_ACCESS"] || "").toLowerCase().trim();
|
|
597718
598146
|
try {
|
|
597719
|
-
const accessFile =
|
|
597720
|
-
if (
|
|
598147
|
+
const accessFile = join123(homedir43(), ".open-agents", "access");
|
|
598148
|
+
if (existsSync107(accessFile)) {
|
|
597721
598149
|
const persisted = readFileSync86(accessFile, "utf8").trim().toLowerCase();
|
|
597722
598150
|
if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
|
|
597723
598151
|
accessMode = persisted;
|
|
@@ -597778,7 +598206,7 @@ async function retrieveMemoryContext(userMessage, sessionId, maxEpisodes = 5) {
|
|
|
597778
598206
|
if (!memMod || !memMod.EpisodeStore) {
|
|
597779
598207
|
return { contextBlock: "", retrieved: [] };
|
|
597780
598208
|
}
|
|
597781
|
-
const dbPath =
|
|
598209
|
+
const dbPath = join123(homedir43(), ".open-agents", "memory.db");
|
|
597782
598210
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597783
598211
|
const recent = store2.search({ limit: 30, sessionId: void 0 }) ?? [];
|
|
597784
598212
|
const qLower = userMessage.toLowerCase();
|
|
@@ -597821,7 +598249,7 @@ async function writeMemoryEpisodes(sessionId, userMessage, assistantContent, too
|
|
|
597821
598249
|
try {
|
|
597822
598250
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2)).catch(() => null);
|
|
597823
598251
|
if (!memMod || !memMod.EpisodeStore) return 0;
|
|
597824
|
-
const dbPath =
|
|
598252
|
+
const dbPath = join123(homedir43(), ".open-agents", "memory.db");
|
|
597825
598253
|
const store2 = new memMod.EpisodeStore(dbPath);
|
|
597826
598254
|
let written = 0;
|
|
597827
598255
|
try {
|
|
@@ -598143,13 +598571,13 @@ function ollamaStream(ollamaUrl, path8, method, body, onData, onEnd, onError, ti
|
|
|
598143
598571
|
}
|
|
598144
598572
|
function jobsDir() {
|
|
598145
598573
|
const root = resolve38(process.cwd());
|
|
598146
|
-
const dir =
|
|
598147
|
-
|
|
598574
|
+
const dir = join123(root, ".oa", "jobs");
|
|
598575
|
+
mkdirSync64(dir, { recursive: true });
|
|
598148
598576
|
return dir;
|
|
598149
598577
|
}
|
|
598150
598578
|
function loadJob(id) {
|
|
598151
|
-
const file =
|
|
598152
|
-
if (!
|
|
598579
|
+
const file = join123(jobsDir(), `${id}.json`);
|
|
598580
|
+
if (!existsSync107(file)) return null;
|
|
598153
598581
|
try {
|
|
598154
598582
|
return JSON.parse(readFileSync86(file, "utf-8"));
|
|
598155
598583
|
} catch {
|
|
@@ -598158,12 +598586,12 @@ function loadJob(id) {
|
|
|
598158
598586
|
}
|
|
598159
598587
|
function listJobs() {
|
|
598160
598588
|
const dir = jobsDir();
|
|
598161
|
-
if (!
|
|
598589
|
+
if (!existsSync107(dir)) return [];
|
|
598162
598590
|
const files = readdirSync36(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
598163
598591
|
const jobs = [];
|
|
598164
598592
|
for (const file of files) {
|
|
598165
598593
|
try {
|
|
598166
|
-
jobs.push(JSON.parse(readFileSync86(
|
|
598594
|
+
jobs.push(JSON.parse(readFileSync86(join123(dir, file), "utf-8")));
|
|
598167
598595
|
} catch {
|
|
598168
598596
|
}
|
|
598169
598597
|
}
|
|
@@ -598173,12 +598601,12 @@ function pruneOldJobs() {
|
|
|
598173
598601
|
const retentionH = parseFloat(process.env["OA_RUN_RETENTION_H"] || "24");
|
|
598174
598602
|
const cutoffMs = Date.now() - (Number.isFinite(retentionH) && retentionH > 0 ? retentionH : 24) * 36e5;
|
|
598175
598603
|
const dir = jobsDir();
|
|
598176
|
-
if (!
|
|
598604
|
+
if (!existsSync107(dir)) return { pruned: 0, kept: 0 };
|
|
598177
598605
|
let pruned = 0;
|
|
598178
598606
|
let kept = 0;
|
|
598179
598607
|
for (const file of readdirSync36(dir)) {
|
|
598180
598608
|
if (!file.endsWith(".json")) continue;
|
|
598181
|
-
const path8 =
|
|
598609
|
+
const path8 = join123(dir, file);
|
|
598182
598610
|
try {
|
|
598183
598611
|
const job = JSON.parse(readFileSync86(path8, "utf-8"));
|
|
598184
598612
|
if (job.status === "running") {
|
|
@@ -598193,7 +598621,7 @@ function pruneOldJobs() {
|
|
|
598193
598621
|
} catch {
|
|
598194
598622
|
}
|
|
598195
598623
|
const outFile = path8.replace(/\.json$/, ".output");
|
|
598196
|
-
if (
|
|
598624
|
+
if (existsSync107(outFile)) {
|
|
598197
598625
|
try {
|
|
598198
598626
|
unlinkSync24(outFile);
|
|
598199
598627
|
} catch {
|
|
@@ -598486,14 +598914,14 @@ function autoSeedTodosFromPrompt(prompt) {
|
|
|
598486
598914
|
return [];
|
|
598487
598915
|
}
|
|
598488
598916
|
function atomicJobWrite(dir, id, job) {
|
|
598489
|
-
const finalPath =
|
|
598917
|
+
const finalPath = join123(dir, `${id}.json`);
|
|
598490
598918
|
const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
|
|
598491
598919
|
try {
|
|
598492
|
-
|
|
598920
|
+
writeFileSync56(tmpPath, JSON.stringify(job, null, 2), "utf-8");
|
|
598493
598921
|
renameSync8(tmpPath, finalPath);
|
|
598494
598922
|
} catch {
|
|
598495
598923
|
try {
|
|
598496
|
-
|
|
598924
|
+
writeFileSync56(finalPath, JSON.stringify(job, null, 2), "utf-8");
|
|
598497
598925
|
} catch {
|
|
598498
598926
|
}
|
|
598499
598927
|
try {
|
|
@@ -599695,7 +600123,7 @@ ${task}` : task;
|
|
|
599695
600123
|
runEnv["OA_RUN_SCOPE"] = req2._authScope || "admin";
|
|
599696
600124
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
599697
600125
|
if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
599698
|
-
const child =
|
|
600126
|
+
const child = spawn26(process.execPath, [oaBin, ...args], {
|
|
599699
600127
|
cwd: resolve38(process.cwd()),
|
|
599700
600128
|
env: runEnv,
|
|
599701
600129
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -599912,15 +600340,15 @@ ${task}` : task;
|
|
|
599912
600340
|
});
|
|
599913
600341
|
}
|
|
599914
600342
|
function updateStateFile() {
|
|
599915
|
-
return
|
|
600343
|
+
return join123(homedir43(), ".open-agents", "update-state.json");
|
|
599916
600344
|
}
|
|
599917
600345
|
function updateLogPath() {
|
|
599918
|
-
return
|
|
600346
|
+
return join123(homedir43(), ".open-agents", "update.log");
|
|
599919
600347
|
}
|
|
599920
600348
|
function readUpdateState() {
|
|
599921
600349
|
try {
|
|
599922
600350
|
const p2 = updateStateFile();
|
|
599923
|
-
if (!
|
|
600351
|
+
if (!existsSync107(p2)) return null;
|
|
599924
600352
|
return JSON.parse(readFileSync86(p2, "utf-8"));
|
|
599925
600353
|
} catch {
|
|
599926
600354
|
return null;
|
|
@@ -599928,11 +600356,11 @@ function readUpdateState() {
|
|
|
599928
600356
|
}
|
|
599929
600357
|
function writeUpdateState(state) {
|
|
599930
600358
|
try {
|
|
599931
|
-
const dir =
|
|
599932
|
-
|
|
600359
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
600360
|
+
mkdirSync64(dir, { recursive: true });
|
|
599933
600361
|
const finalPath = updateStateFile();
|
|
599934
600362
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
599935
|
-
|
|
600363
|
+
writeFileSync56(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
599936
600364
|
renameSync8(tmpPath, finalPath);
|
|
599937
600365
|
} catch {
|
|
599938
600366
|
}
|
|
@@ -599976,15 +600404,15 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
599976
600404
|
const { execSync: es } = require3("node:child_process");
|
|
599977
600405
|
const isWin2 = process.platform === "win32";
|
|
599978
600406
|
let npmBin = "";
|
|
599979
|
-
for (const candidate of isWin2 ? [
|
|
599980
|
-
if (
|
|
600407
|
+
for (const candidate of isWin2 ? [join123(nodeDir, "npm.cmd"), join123(nodeDir, "npm")] : [join123(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
|
|
600408
|
+
if (existsSync107(candidate)) {
|
|
599981
600409
|
npmBin = candidate;
|
|
599982
600410
|
break;
|
|
599983
600411
|
}
|
|
599984
600412
|
}
|
|
599985
600413
|
if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
|
|
599986
600414
|
const pkgSpec = `open-agents-ai@${targetVersion}`;
|
|
599987
|
-
const dir =
|
|
600415
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
599988
600416
|
fs7.mkdirSync(dir, { recursive: true });
|
|
599989
600417
|
const logFd = fs7.openSync(logPath3, "w");
|
|
599990
600418
|
const npmPrefix = dirname36(nodeDir);
|
|
@@ -599994,13 +600422,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
599994
600422
|
globalBinDir = es(`${npmBin} bin -g`, { encoding: "utf8", timeout: 5e3, stdio: "pipe" }).trim();
|
|
599995
600423
|
} else {
|
|
599996
600424
|
const npmCliCandidates = [
|
|
599997
|
-
|
|
599998
|
-
|
|
600425
|
+
join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600426
|
+
join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
599999
600427
|
];
|
|
600000
600428
|
let npmCli = "";
|
|
600001
600429
|
for (const c9 of npmCliCandidates) {
|
|
600002
600430
|
try {
|
|
600003
|
-
if (
|
|
600431
|
+
if (existsSync107(c9)) {
|
|
600004
600432
|
npmCli = c9;
|
|
600005
600433
|
break;
|
|
600006
600434
|
}
|
|
@@ -600024,7 +600452,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600024
600452
|
cleanEnv.PATH = pathParts.join(":");
|
|
600025
600453
|
let child;
|
|
600026
600454
|
if (isWin2) {
|
|
600027
|
-
child =
|
|
600455
|
+
child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600028
600456
|
detached: true,
|
|
600029
600457
|
stdio: ["ignore", logFd, logFd],
|
|
600030
600458
|
windowsHide: true,
|
|
@@ -600032,13 +600460,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600032
600460
|
});
|
|
600033
600461
|
} else {
|
|
600034
600462
|
const npmCliCandidates = [
|
|
600035
|
-
|
|
600036
|
-
|
|
600463
|
+
join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
600464
|
+
join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
600037
600465
|
];
|
|
600038
600466
|
let npmCli = "";
|
|
600039
600467
|
for (const c9 of npmCliCandidates) {
|
|
600040
600468
|
try {
|
|
600041
|
-
if (
|
|
600469
|
+
if (existsSync107(c9)) {
|
|
600042
600470
|
npmCli = c9;
|
|
600043
600471
|
break;
|
|
600044
600472
|
}
|
|
@@ -600046,13 +600474,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600046
600474
|
}
|
|
600047
600475
|
}
|
|
600048
600476
|
if (npmCli) {
|
|
600049
|
-
child =
|
|
600477
|
+
child = spawn26(nodeBin, [npmCli, "install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600050
600478
|
detached: true,
|
|
600051
600479
|
stdio: ["ignore", logFd, logFd],
|
|
600052
600480
|
env: cleanEnv
|
|
600053
600481
|
});
|
|
600054
600482
|
} else {
|
|
600055
|
-
child =
|
|
600483
|
+
child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
600056
600484
|
detached: true,
|
|
600057
600485
|
stdio: ["ignore", logFd, logFd],
|
|
600058
600486
|
env: cleanEnv
|
|
@@ -600063,7 +600491,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600063
600491
|
const installPid = child.pid ?? 0;
|
|
600064
600492
|
if (installPid > 0 && !isWin2) {
|
|
600065
600493
|
try {
|
|
600066
|
-
const follower =
|
|
600494
|
+
const follower = spawn26("bash", ["-c", `while kill -0 ${installPid} 2>/dev/null; do sleep 1; done; echo "__EXIT_CODE=0" >> "${logPath3}"`], {
|
|
600067
600495
|
detached: true,
|
|
600068
600496
|
stdio: "ignore"
|
|
600069
600497
|
});
|
|
@@ -600076,8 +600504,8 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600076
600504
|
}
|
|
600077
600505
|
let oaAbs = "oa";
|
|
600078
600506
|
try {
|
|
600079
|
-
const
|
|
600080
|
-
if (
|
|
600507
|
+
const which2 = es("command -v oa 2>/dev/null || which oa 2>/dev/null", { encoding: "utf8", timeout: 2e3, stdio: "pipe", env: cleanEnv }).trim();
|
|
600508
|
+
if (which2) oaAbs = which2;
|
|
600081
600509
|
} catch {
|
|
600082
600510
|
}
|
|
600083
600511
|
const relaunchScript = [
|
|
@@ -600086,7 +600514,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
600086
600514
|
hasSystemdUnit ? `systemctl --user restart open-agents-daemon.service >/dev/null 2>&1 || true` : `${JSON.stringify(oaAbs)} serve --quiet --daemon >/dev/null 2>&1 & disown`,
|
|
600087
600515
|
`kill -TERM ${process.pid} >/dev/null 2>&1 || true`
|
|
600088
600516
|
].join("; ");
|
|
600089
|
-
const relauncher =
|
|
600517
|
+
const relauncher = spawn26("bash", ["-c", relaunchScript], {
|
|
600090
600518
|
detached: true,
|
|
600091
600519
|
stdio: "ignore",
|
|
600092
600520
|
env: cleanEnv
|
|
@@ -600135,7 +600563,7 @@ function handleV1UpdateStatus(res) {
|
|
|
600135
600563
|
let logTail = "";
|
|
600136
600564
|
let exitCode = null;
|
|
600137
600565
|
try {
|
|
600138
|
-
if (
|
|
600566
|
+
if (existsSync107(logPath3)) {
|
|
600139
600567
|
const raw = readFileSync86(logPath3, "utf-8");
|
|
600140
600568
|
const m2 = raw.match(/__EXIT_CODE=(\d+)/);
|
|
600141
600569
|
if (m2) exitCode = parseInt(m2[1], 10);
|
|
@@ -600232,8 +600660,8 @@ async function handleV1Run(req2, res) {
|
|
|
600232
600660
|
if (workingDir) {
|
|
600233
600661
|
cwd4 = resolve38(workingDir);
|
|
600234
600662
|
} else if (isolate) {
|
|
600235
|
-
const wsDir =
|
|
600236
|
-
|
|
600663
|
+
const wsDir = join123(dir, "..", "workspaces", id);
|
|
600664
|
+
mkdirSync64(wsDir, { recursive: true });
|
|
600237
600665
|
cwd4 = wsDir;
|
|
600238
600666
|
} else {
|
|
600239
600667
|
cwd4 = resolve38(process.cwd());
|
|
@@ -600308,7 +600736,7 @@ async function handleV1Run(req2, res) {
|
|
|
600308
600736
|
});
|
|
600309
600737
|
job.sandbox = "container";
|
|
600310
600738
|
} else {
|
|
600311
|
-
child =
|
|
600739
|
+
child = spawn26(process.execPath, [oaBin, ...args], {
|
|
600312
600740
|
cwd: cwd4,
|
|
600313
600741
|
env: runEnv,
|
|
600314
600742
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -600419,7 +600847,7 @@ async function handleV1Run(req2, res) {
|
|
|
600419
600847
|
let output = "";
|
|
600420
600848
|
let tailBytes = 0;
|
|
600421
600849
|
const TAIL_BUDGET = 1048576;
|
|
600422
|
-
const outputWriter = new DiskTaskOutput(
|
|
600850
|
+
const outputWriter = new DiskTaskOutput(join123(dir, `${id}.output`));
|
|
600423
600851
|
job.outputFile = outputWriter.path;
|
|
600424
600852
|
atomicJobWrite(dir, id, job);
|
|
600425
600853
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -600818,7 +601246,7 @@ async function handlePostCommand(res, cmd) {
|
|
|
600818
601246
|
return;
|
|
600819
601247
|
}
|
|
600820
601248
|
try {
|
|
600821
|
-
const child =
|
|
601249
|
+
const child = spawn26("node", [oaBin, "run", `/${cmd}`, "--json"], {
|
|
600822
601250
|
env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
|
|
600823
601251
|
stdio: ["ignore", "pipe", "pipe"],
|
|
600824
601252
|
timeout: 3e4
|
|
@@ -601335,11 +601763,11 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
601335
601763
|
jsonResponse(res, 400, { error: "audio_too_small", message: "Reference audio must be at least ~4 KB" });
|
|
601336
601764
|
return;
|
|
601337
601765
|
}
|
|
601338
|
-
const { tmpdir:
|
|
601339
|
-
const { writeFileSync:
|
|
601766
|
+
const { tmpdir: tmpdir23 } = await import("node:os");
|
|
601767
|
+
const { writeFileSync: writeFileSync60, unlinkSync: unlinkSync25 } = await import("node:fs");
|
|
601340
601768
|
const { join: pjoin } = await import("node:path");
|
|
601341
|
-
const tmpPath = pjoin(
|
|
601342
|
-
|
|
601769
|
+
const tmpPath = pjoin(tmpdir23(), `oa-clone-upload-${Date.now()}-${safeName}`);
|
|
601770
|
+
writeFileSync60(tmpPath, buf);
|
|
601343
601771
|
try {
|
|
601344
601772
|
const ve = getVoiceEngine();
|
|
601345
601773
|
const msg = await ve.setCloneVoice(tmpPath);
|
|
@@ -601889,7 +602317,7 @@ data: ${JSON.stringify(data)}
|
|
|
601889
602317
|
}
|
|
601890
602318
|
for (const f2 of seenFiles) {
|
|
601891
602319
|
try {
|
|
601892
|
-
|
|
602320
|
+
writeFileSync56(f2, JSON.stringify({ tasks: [] }, null, 2));
|
|
601893
602321
|
deleted++;
|
|
601894
602322
|
} catch {
|
|
601895
602323
|
}
|
|
@@ -602190,7 +602618,7 @@ ${historyLines}
|
|
|
602190
602618
|
}
|
|
602191
602619
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
602192
602620
|
if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
602193
|
-
const child =
|
|
602621
|
+
const child = spawn26(process.execPath, [oaBin, ...args], {
|
|
602194
602622
|
cwd: cwdPath,
|
|
602195
602623
|
env: runEnv,
|
|
602196
602624
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -602993,7 +603421,7 @@ ${steering}`;
|
|
|
602993
603421
|
function getScheduleRoots() {
|
|
602994
603422
|
const rootsEnv = process.env["OA_SCHEDULE_ROOTS"] || "";
|
|
602995
603423
|
const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
|
|
602996
|
-
const defaults3 = [process.cwd(),
|
|
603424
|
+
const defaults3 = [process.cwd(), join123(homedir43(), "Documents")];
|
|
602997
603425
|
const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
|
|
602998
603426
|
return [...set];
|
|
602999
603427
|
}
|
|
@@ -603005,8 +603433,8 @@ function listScheduledTasks() {
|
|
|
603005
603433
|
for (const root of roots) {
|
|
603006
603434
|
try {
|
|
603007
603435
|
walk(root, 0, (dir) => {
|
|
603008
|
-
if (dir.endsWith(`${
|
|
603009
|
-
const file =
|
|
603436
|
+
if (dir.endsWith(`${join123(".oa", "scheduled")}`) || dir.includes(`${join123(".oa", "scheduled")}`)) {
|
|
603437
|
+
const file = join123(dir, "tasks.json");
|
|
603010
603438
|
try {
|
|
603011
603439
|
const raw = readFileSync86(file, "utf-8");
|
|
603012
603440
|
const json = JSON.parse(raw);
|
|
@@ -603073,7 +603501,7 @@ function walk(dir, depth, onDir, maxDepth) {
|
|
|
603073
603501
|
if (e2.name === "node_modules" || e2.name.startsWith(".")) {
|
|
603074
603502
|
if (e2.name !== ".oa") continue;
|
|
603075
603503
|
}
|
|
603076
|
-
const child =
|
|
603504
|
+
const child = join123(dir, e2.name);
|
|
603077
603505
|
walk(child, depth + 1, onDir, maxDepth);
|
|
603078
603506
|
}
|
|
603079
603507
|
}
|
|
@@ -603089,11 +603517,11 @@ function setScheduledEnabled(id, enabled2) {
|
|
|
603089
603517
|
arr[target.index].enabled = enabled2;
|
|
603090
603518
|
if (Array.isArray(json?.tasks)) {
|
|
603091
603519
|
json.tasks = arr;
|
|
603092
|
-
|
|
603520
|
+
writeFileSync56(target.file, JSON.stringify(json, null, 2));
|
|
603093
603521
|
} else if (Array.isArray(json)) {
|
|
603094
|
-
|
|
603522
|
+
writeFileSync56(target.file, JSON.stringify(arr, null, 2));
|
|
603095
603523
|
} else {
|
|
603096
|
-
|
|
603524
|
+
writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
603097
603525
|
}
|
|
603098
603526
|
if (!enabled2) {
|
|
603099
603527
|
try {
|
|
@@ -603123,11 +603551,11 @@ function deleteScheduledById(id) {
|
|
|
603123
603551
|
arr.splice(target.index, 1);
|
|
603124
603552
|
if (Array.isArray(json?.tasks)) {
|
|
603125
603553
|
json.tasks = arr;
|
|
603126
|
-
|
|
603554
|
+
writeFileSync56(target.file, JSON.stringify(json, null, 2));
|
|
603127
603555
|
} else if (Array.isArray(json)) {
|
|
603128
|
-
|
|
603556
|
+
writeFileSync56(target.file, JSON.stringify(arr, null, 2));
|
|
603129
603557
|
} else {
|
|
603130
|
-
|
|
603558
|
+
writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
|
|
603131
603559
|
}
|
|
603132
603560
|
const candidates = [];
|
|
603133
603561
|
if (id) candidates.push(id);
|
|
@@ -603380,7 +603808,7 @@ function reconcileScheduledTasks(apply) {
|
|
|
603380
603808
|
const errors = [];
|
|
603381
603809
|
for (const f2 of found) {
|
|
603382
603810
|
const wdir = f2.workingDir || process.cwd();
|
|
603383
|
-
const file =
|
|
603811
|
+
const file = join123(wdir, ".oa", "scheduled", "tasks.json");
|
|
603384
603812
|
try {
|
|
603385
603813
|
let json = { tasks: [] };
|
|
603386
603814
|
try {
|
|
@@ -603395,9 +603823,9 @@ function reconcileScheduledTasks(apply) {
|
|
|
603395
603823
|
const entry = { task: f2.task || `legacy ${f2.id}`, schedule: f2.cron, enabled: true };
|
|
603396
603824
|
arr.push(entry);
|
|
603397
603825
|
const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
|
|
603398
|
-
|
|
603399
|
-
|
|
603400
|
-
|
|
603826
|
+
mkdirSync64(join123(wdir, ".oa", "scheduled"), { recursive: true });
|
|
603827
|
+
mkdirSync64(join123(wdir, ".oa", "scheduled", "logs"), { recursive: true });
|
|
603828
|
+
writeFileSync56(file, JSON.stringify(toWrite, null, 2));
|
|
603401
603829
|
adopted.push({ file, index: arr.length - 1 });
|
|
603402
603830
|
}
|
|
603403
603831
|
} else {
|
|
@@ -603441,32 +603869,32 @@ function writeCrontabLines(lines) {
|
|
|
603441
603869
|
}
|
|
603442
603870
|
function canonicalCronLine(rec) {
|
|
603443
603871
|
const oaBin = findOaBinary4();
|
|
603444
|
-
const logDir =
|
|
603445
|
-
const logFile =
|
|
603446
|
-
const storeFile =
|
|
603872
|
+
const logDir = join123(rec.workingDir, ".oa", "scheduled", "logs");
|
|
603873
|
+
const logFile = join123(logDir, `${rec.id}.log`);
|
|
603874
|
+
const storeFile = join123(rec.workingDir, ".oa", "scheduled", "tasks.json");
|
|
603447
603875
|
const taskEsc = rec.task.replace(/'/g, "'\\''");
|
|
603448
|
-
const lockDir =
|
|
603449
|
-
const lockPath =
|
|
603876
|
+
const lockDir = join123(rec.workingDir, ".oa", "run");
|
|
603877
|
+
const lockPath = join123(lockDir, `${rec.id}.lock`);
|
|
603450
603878
|
const wrapper = [
|
|
603451
603879
|
`cd ${JSON.stringify(rec.workingDir)}`,
|
|
603452
603880
|
`mkdir -p ${JSON.stringify(logDir)}`,
|
|
603453
603881
|
`mkdir -p ${JSON.stringify(lockDir)}`,
|
|
603454
603882
|
`if mkdir ${JSON.stringify(lockPath)} 2>/dev/null; then`,
|
|
603455
|
-
` echo $$ > ${JSON.stringify(
|
|
603883
|
+
` echo $$ > ${JSON.stringify(join123(lockPath, "pid"))}`,
|
|
603456
603884
|
` trap 'rm -rf ${lockPath}' EXIT`,
|
|
603457
603885
|
`else`,
|
|
603458
|
-
` if [ -f ${JSON.stringify(
|
|
603459
|
-
` oldpid=$(cat ${JSON.stringify(
|
|
603886
|
+
` if [ -f ${JSON.stringify(join123(lockPath, "pid"))} ]; then`,
|
|
603887
|
+
` oldpid=$(cat ${JSON.stringify(join123(lockPath, "pid"))} 2>/dev/null || echo)`,
|
|
603460
603888
|
` if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then`,
|
|
603461
603889
|
` echo "[oa-scheduler] ${rec.id} already running as PID $oldpid; skipping" >> ${JSON.stringify(logFile)}`,
|
|
603462
603890
|
` exit 0`,
|
|
603463
603891
|
` else`,
|
|
603464
603892
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
603465
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603893
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
603466
603894
|
` fi`,
|
|
603467
603895
|
` else`,
|
|
603468
603896
|
` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
|
|
603469
|
-
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(
|
|
603897
|
+
` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
|
|
603470
603898
|
` fi`,
|
|
603471
603899
|
`fi`,
|
|
603472
603900
|
`${oaBin} '${taskEsc}' >> ${JSON.stringify(logFile)} 2>&1; _oa_exit=$?`,
|
|
@@ -603498,9 +603926,9 @@ function fixupOrMigrateScheduled(mode, dryRun) {
|
|
|
603498
603926
|
try {
|
|
603499
603927
|
if (!f2.workingDir || !f2.task) continue;
|
|
603500
603928
|
const unitBase = `oa-${f2.id}`;
|
|
603501
|
-
const unitDir =
|
|
603502
|
-
const svc =
|
|
603503
|
-
const tim =
|
|
603929
|
+
const unitDir = join123(homedir43(), ".config", "systemd", "user");
|
|
603930
|
+
const svc = join123(unitDir, `${unitBase}.service`);
|
|
603931
|
+
const tim = join123(unitDir, `${unitBase}.timer`);
|
|
603504
603932
|
const oaBin = findOaBinary4();
|
|
603505
603933
|
const rec = { id: f2.id, cron: f2.cron, workingDir: f2.workingDir, task: f2.task };
|
|
603506
603934
|
const cmd = canonicalCronLine(rec).split(" ").slice(5).join(" ");
|
|
@@ -603530,9 +603958,9 @@ Persistent=true
|
|
|
603530
603958
|
WantedBy=timers.target
|
|
603531
603959
|
`;
|
|
603532
603960
|
if (!dryRun) {
|
|
603533
|
-
|
|
603534
|
-
|
|
603535
|
-
|
|
603961
|
+
mkdirSync64(unitDir, { recursive: true });
|
|
603962
|
+
writeFileSync56(svc, svcText);
|
|
603963
|
+
writeFileSync56(tim, timText);
|
|
603536
603964
|
try {
|
|
603537
603965
|
const { execSync: es } = require3("node:child_process");
|
|
603538
603966
|
es("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
@@ -603626,8 +604054,8 @@ function startApiServer(options2 = {}) {
|
|
|
603626
604054
|
const config = loadConfig();
|
|
603627
604055
|
const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
|
|
603628
604056
|
const cwd4 = process.cwd();
|
|
603629
|
-
initAuditLog(
|
|
603630
|
-
initUsageTracker(
|
|
604057
|
+
initAuditLog(join123(cwd4, ".oa"));
|
|
604058
|
+
initUsageTracker(join123(cwd4, ".oa"));
|
|
603631
604059
|
try {
|
|
603632
604060
|
const taskMgr = getSharedTaskManager();
|
|
603633
604061
|
taskMgr.setEventPublisher((type, data, opts) => {
|
|
@@ -603669,7 +604097,7 @@ function startApiServer(options2 = {}) {
|
|
|
603669
604097
|
try {
|
|
603670
604098
|
const dir = todoDir();
|
|
603671
604099
|
try {
|
|
603672
|
-
|
|
604100
|
+
mkdirSync64(dir, { recursive: true });
|
|
603673
604101
|
} catch {
|
|
603674
604102
|
}
|
|
603675
604103
|
const cache8 = /* @__PURE__ */ new Map();
|
|
@@ -603678,7 +604106,7 @@ function startApiServer(options2 = {}) {
|
|
|
603678
604106
|
if (!f2.endsWith(".json") || f2.includes(".tmp.")) continue;
|
|
603679
604107
|
const sid = f2.replace(/\.json$/, "");
|
|
603680
604108
|
try {
|
|
603681
|
-
const items = JSON.parse(readFileSync86(
|
|
604109
|
+
const items = JSON.parse(readFileSync86(join123(dir, f2), "utf-8"));
|
|
603682
604110
|
if (Array.isArray(items)) {
|
|
603683
604111
|
cache8.set(sid, new Map(items.map((t2) => [t2.id, t2])));
|
|
603684
604112
|
}
|
|
@@ -603690,10 +604118,10 @@ function startApiServer(options2 = {}) {
|
|
|
603690
604118
|
const watcher = fsWatch3(dir, (_evt, fname) => {
|
|
603691
604119
|
if (!fname || !fname.endsWith(".json") || fname.includes(".tmp.")) return;
|
|
603692
604120
|
const sid = fname.replace(/\.json$/, "");
|
|
603693
|
-
const fp =
|
|
604121
|
+
const fp = join123(dir, fname);
|
|
603694
604122
|
let next = [];
|
|
603695
604123
|
try {
|
|
603696
|
-
if (!
|
|
604124
|
+
if (!existsSync107(fp)) {
|
|
603697
604125
|
const old = cache8.get(sid);
|
|
603698
604126
|
if (old) {
|
|
603699
604127
|
for (const t2 of old.values()) {
|
|
@@ -603745,13 +604173,13 @@ function startApiServer(options2 = {}) {
|
|
|
603745
604173
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
603746
604174
|
if (retentionDays > 0) {
|
|
603747
604175
|
try {
|
|
603748
|
-
const jobsDir3 =
|
|
603749
|
-
if (
|
|
604176
|
+
const jobsDir3 = join123(cwd4, ".oa", "jobs");
|
|
604177
|
+
if (existsSync107(jobsDir3)) {
|
|
603750
604178
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
603751
604179
|
for (const f2 of readdirSync36(jobsDir3)) {
|
|
603752
604180
|
if (!f2.endsWith(".json")) continue;
|
|
603753
604181
|
try {
|
|
603754
|
-
const jobPath =
|
|
604182
|
+
const jobPath = join123(jobsDir3, f2);
|
|
603755
604183
|
const job = JSON.parse(readFileSync86(jobPath, "utf-8"));
|
|
603756
604184
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
603757
604185
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
@@ -603784,8 +604212,8 @@ function startApiServer(options2 = {}) {
|
|
|
603784
604212
|
}
|
|
603785
604213
|
let runtimeAccessMode = resolveAccessMode(process.env["OA_ACCESS"], host);
|
|
603786
604214
|
try {
|
|
603787
|
-
const accessFile =
|
|
603788
|
-
if (
|
|
604215
|
+
const accessFile = join123(homedir43(), ".open-agents", "access");
|
|
604216
|
+
if (existsSync107(accessFile)) {
|
|
603789
604217
|
const persisted = readFileSync86(accessFile, "utf8").trim();
|
|
603790
604218
|
const resolved = resolveAccessMode(persisted, host);
|
|
603791
604219
|
if (resolved) runtimeAccessMode = resolved;
|
|
@@ -603839,9 +604267,9 @@ function startApiServer(options2 = {}) {
|
|
|
603839
604267
|
const previous = runtimeAccessMode;
|
|
603840
604268
|
runtimeAccessMode = requested;
|
|
603841
604269
|
try {
|
|
603842
|
-
const dir =
|
|
603843
|
-
|
|
603844
|
-
|
|
604270
|
+
const dir = join123(homedir43(), ".open-agents");
|
|
604271
|
+
mkdirSync64(dir, { recursive: true });
|
|
604272
|
+
writeFileSync56(join123(dir, "access"), `${runtimeAccessMode}
|
|
603845
604273
|
`, "utf8");
|
|
603846
604274
|
} catch {
|
|
603847
604275
|
}
|
|
@@ -604054,9 +604482,9 @@ function startApiServer(options2 = {}) {
|
|
|
604054
604482
|
try {
|
|
604055
604483
|
const { startEmbeddingWorkers: startEmbeddingWorkers2 } = await Promise.resolve().then(() => (init_embedding_workers(), embedding_workers_exports));
|
|
604056
604484
|
const { ensureEmbedDeps: ensureEmbedDeps2, runEmbedImage: runEmbedImage2, runEmbedAudio: runEmbedAudio2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
|
|
604057
|
-
const dbBase =
|
|
604058
|
-
const epStore = new mem.EpisodeStore(
|
|
604059
|
-
const kg = new mem.TemporalGraph(
|
|
604485
|
+
const dbBase = join123(cwd4, ".oa");
|
|
604486
|
+
const epStore = new mem.EpisodeStore(join123(dbBase, "memory.db"));
|
|
604487
|
+
const kg = new mem.TemporalGraph(join123(dbBase, "kg.db"));
|
|
604060
604488
|
try {
|
|
604061
604489
|
ensureEmbedDeps2();
|
|
604062
604490
|
} catch {
|
|
@@ -604134,7 +604562,7 @@ function startApiServer(options2 = {}) {
|
|
|
604134
604562
|
log22(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
|
|
604135
604563
|
`);
|
|
604136
604564
|
try {
|
|
604137
|
-
const { writeFileSync:
|
|
604565
|
+
const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: _exists, readFileSync: _rfs } = require3("node:fs");
|
|
604138
604566
|
const { join: _join } = require3("node:path");
|
|
604139
604567
|
const { homedir: _homedir } = require3("node:os");
|
|
604140
604568
|
const apiHint = JSON.stringify({
|
|
@@ -604145,22 +604573,111 @@ function startApiServer(options2 = {}) {
|
|
|
604145
604573
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
604146
604574
|
version: version4
|
|
604147
604575
|
}, null, 2);
|
|
604148
|
-
const
|
|
604149
|
-
|
|
604150
|
-
_join(_homedir(), ".
|
|
604151
|
-
|
|
604152
|
-
|
|
604153
|
-
|
|
604576
|
+
const dirSet = /* @__PURE__ */ new Set();
|
|
604577
|
+
try {
|
|
604578
|
+
const regPath = _join(_homedir(), ".open-agents", "nexus-registry.json");
|
|
604579
|
+
if (_exists(regPath)) {
|
|
604580
|
+
const reg = JSON.parse(_rfs(regPath, "utf-8"));
|
|
604581
|
+
for (const e2 of reg?.dirs || []) {
|
|
604582
|
+
const d2 = typeof e2 === "string" ? e2 : e2?.dir;
|
|
604583
|
+
if (typeof d2 === "string") dirSet.add(d2);
|
|
604584
|
+
}
|
|
604585
|
+
}
|
|
604586
|
+
} catch {
|
|
604587
|
+
}
|
|
604588
|
+
if (process.env["OA_NEXUS_DIR"]) dirSet.add(process.env["OA_NEXUS_DIR"]);
|
|
604589
|
+
dirSet.add(_join(process.cwd(), ".oa", "nexus"));
|
|
604590
|
+
dirSet.add(_join(_homedir(), ".oa", "nexus"));
|
|
604591
|
+
dirSet.add(_join(_homedir(), ".open-agents", "nexus"));
|
|
604592
|
+
let written = 0;
|
|
604593
|
+
for (const dir of dirSet) {
|
|
604154
604594
|
try {
|
|
604155
|
-
if (!_exists(dir))
|
|
604156
|
-
|
|
604595
|
+
if (!_exists(dir)) mkdirSync68(dir, { recursive: true });
|
|
604596
|
+
writeFileSync60(_join(dir, "api-port.json"), apiHint);
|
|
604597
|
+
written++;
|
|
604157
604598
|
} catch {
|
|
604158
604599
|
}
|
|
604159
604600
|
}
|
|
604601
|
+
if (written > 0) log22(` api-port hint: wrote to ${written} nexus dir(s)
|
|
604602
|
+
`);
|
|
604160
604603
|
} catch (e2) {
|
|
604161
604604
|
log22(` WARN: api-port hint write failed: ${e2.message}
|
|
604162
604605
|
`);
|
|
604163
604606
|
}
|
|
604607
|
+
if (process.env["OA_AUTO_NEXUS"] !== "0") {
|
|
604608
|
+
(async () => {
|
|
604609
|
+
try {
|
|
604610
|
+
const { join: _j } = require3("node:path");
|
|
604611
|
+
const { homedir: _hd } = require3("node:os");
|
|
604612
|
+
const { existsSync: _ex, readFileSync: _rf, statSync: _st } = require3("node:fs");
|
|
604613
|
+
const { execSync: _ex2 } = require3("node:child_process");
|
|
604614
|
+
let chosenNexusDir = null;
|
|
604615
|
+
if (process.env["OA_NEXUS_DIR"]) chosenNexusDir = process.env["OA_NEXUS_DIR"];
|
|
604616
|
+
if (!chosenNexusDir) {
|
|
604617
|
+
try {
|
|
604618
|
+
const regPath = _j(_hd(), ".open-agents", "nexus-registry.json");
|
|
604619
|
+
if (_ex(regPath)) {
|
|
604620
|
+
const reg = JSON.parse(_rf(regPath, "utf-8"));
|
|
604621
|
+
for (const e2 of reg?.dirs || []) {
|
|
604622
|
+
const d2 = typeof e2 === "string" ? e2 : e2?.dir;
|
|
604623
|
+
if (typeof d2 === "string" && _ex(d2)) {
|
|
604624
|
+
chosenNexusDir = d2;
|
|
604625
|
+
break;
|
|
604626
|
+
}
|
|
604627
|
+
}
|
|
604628
|
+
}
|
|
604629
|
+
} catch {
|
|
604630
|
+
}
|
|
604631
|
+
}
|
|
604632
|
+
if (!chosenNexusDir) {
|
|
604633
|
+
try {
|
|
604634
|
+
const cmd = `find "${_hd()}" -maxdepth 4 -path '*/.oa/nexus' -type d 2>/dev/null | head -10`;
|
|
604635
|
+
const out = _ex2(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
604636
|
+
for (const ln of out.split("\n").filter(Boolean)) {
|
|
604637
|
+
if (_ex(_j(ln, "status.json"))) {
|
|
604638
|
+
chosenNexusDir = ln;
|
|
604639
|
+
break;
|
|
604640
|
+
}
|
|
604641
|
+
}
|
|
604642
|
+
if (!chosenNexusDir && out) chosenNexusDir = out.split("\n")[0]?.trim() || null;
|
|
604643
|
+
} catch {
|
|
604644
|
+
}
|
|
604645
|
+
}
|
|
604646
|
+
const finalNexusDir = chosenNexusDir ?? _j(_hd(), ".oa", "nexus");
|
|
604647
|
+
chosenNexusDir = finalNexusDir;
|
|
604648
|
+
const repoRoot = finalNexusDir.replace(/[\\/]\.oa[\\/]nexus$/, "");
|
|
604649
|
+
log22(` Nexus auto-recover: target ${finalNexusDir}
|
|
604650
|
+
`);
|
|
604651
|
+
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
|
|
604652
|
+
const tool = new NexusTool2(repoRoot);
|
|
604653
|
+
const result = await tool.execute({ action: "connect" });
|
|
604654
|
+
const status = result?.success ? "ok" : "fail";
|
|
604655
|
+
const detail = result?.output || result?.error || "";
|
|
604656
|
+
log22(` Nexus auto-recover: ${status}${detail ? " — " + String(detail).split("\n")[0].slice(0, 120) : ""}
|
|
604657
|
+
`);
|
|
604658
|
+
if (status === "ok") {
|
|
604659
|
+
try {
|
|
604660
|
+
const { writeFileSync: _wfs2, mkdirSync: _mks, existsSync: _exf } = require3("node:fs");
|
|
604661
|
+
const apiHint2 = JSON.stringify({
|
|
604662
|
+
port,
|
|
604663
|
+
host: host === "0.0.0.0" ? "127.0.0.1" : host,
|
|
604664
|
+
scheme: proto,
|
|
604665
|
+
pid: process.pid,
|
|
604666
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
604667
|
+
version: version4
|
|
604668
|
+
}, null, 2);
|
|
604669
|
+
const dirOut = chosenNexusDir;
|
|
604670
|
+
if (!_exf(dirOut)) _mks(dirOut, { recursive: true });
|
|
604671
|
+
_wfs2(_j(dirOut, "api-port.json"), apiHint2);
|
|
604672
|
+
} catch {
|
|
604673
|
+
}
|
|
604674
|
+
}
|
|
604675
|
+
} catch (e2) {
|
|
604676
|
+
log22(` Nexus auto-recover: skipped (${e2.message.slice(0, 80)})
|
|
604677
|
+
`);
|
|
604678
|
+
}
|
|
604679
|
+
})();
|
|
604680
|
+
}
|
|
604164
604681
|
try {
|
|
604165
604682
|
adoptHandoffRuns();
|
|
604166
604683
|
} catch (e2) {
|
|
@@ -604394,10 +604911,10 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
604394
604911
|
const labels = Array.isArray(b.labels) ? b.labels : [];
|
|
604395
604912
|
const mediaPath = typeof b.media_path === "string" ? b.media_path : void 0;
|
|
604396
604913
|
const cwd4 = process.cwd();
|
|
604397
|
-
const dbBase =
|
|
604914
|
+
const dbBase = join123(cwd4, ".oa");
|
|
604398
604915
|
const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604399
|
-
const epStore = new EpisodeStore3(
|
|
604400
|
-
const kg = new TemporalGraph3(
|
|
604916
|
+
const epStore = new EpisodeStore3(join123(dbBase, "memory.db"));
|
|
604917
|
+
const kg = new TemporalGraph3(join123(dbBase, "kg.db"));
|
|
604401
604918
|
const meta = {};
|
|
604402
604919
|
if (mediaPath) meta.media_path = mediaPath;
|
|
604403
604920
|
const epId = epStore.insert({ modality, content: content || (mediaPath || ""), metadata: meta, toolName: "memory_ingest" });
|
|
@@ -604464,7 +604981,7 @@ async function handleEntitiesList(req2, res) {
|
|
|
604464
604981
|
const type = url.searchParams.get("type") || "person";
|
|
604465
604982
|
const limit = Math.max(1, Math.min(1e3, parseInt(url.searchParams.get("limit") || "100", 10)));
|
|
604466
604983
|
const { TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604467
|
-
const kg = new TemporalGraph3(
|
|
604984
|
+
const kg = new TemporalGraph3(join123(process.cwd(), ".oa", "kg.db"));
|
|
604468
604985
|
const nodes = kg.nodesByType(type, limit).map((n2) => ({ id: n2.id, text: n2.text, mentionCount: n2.mentionCount, firstSeen: n2.firstSeen, lastSeen: n2.lastSeen }));
|
|
604469
604986
|
jsonResponse(res, 200, { object: "list", data: nodes });
|
|
604470
604987
|
} catch (err) {
|
|
@@ -604486,7 +605003,7 @@ async function handleMemorySearch2(req2, res) {
|
|
|
604486
605003
|
const wLex = typeof b.lexical_weight === "number" ? b.lexical_weight : 1;
|
|
604487
605004
|
const wEmb = typeof b.embedding_weight === "number" ? b.embedding_weight : 1;
|
|
604488
605005
|
const { EpisodeStore: EpisodeStore3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
604489
|
-
const epStore = new EpisodeStore3(
|
|
605006
|
+
const epStore = new EpisodeStore3(join123(process.cwd(), ".oa", "memory.db"));
|
|
604490
605007
|
const results = epStore.search({ query, modality, limit }, { queryEmbedding: qEmb, lexicalWeight: wLex, embeddingWeight: wEmb });
|
|
604491
605008
|
jsonResponse(res, 200, { object: "list", data: results.map((e2) => ({ id: e2.id, modality: e2.modality, content: e2.content, timestamp: e2.timestamp })) });
|
|
604492
605009
|
} catch (err) {
|
|
@@ -604603,11 +605120,11 @@ var init_serve = __esm({
|
|
|
604603
605120
|
|
|
604604
605121
|
// packages/cli/src/tui/interactive.ts
|
|
604605
605122
|
import { cwd } from "node:process";
|
|
604606
|
-
import { resolve as resolve39, join as
|
|
605123
|
+
import { resolve as resolve39, join as join124, dirname as dirname37, extname as extname12 } from "node:path";
|
|
604607
605124
|
import { createRequire as createRequire6 } from "node:module";
|
|
604608
605125
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
604609
|
-
import { readFileSync as readFileSync87, writeFileSync as
|
|
604610
|
-
import { existsSync as
|
|
605126
|
+
import { readFileSync as readFileSync87, writeFileSync as writeFileSync57, appendFileSync as appendFileSync8, rmSync as rmSync5, readdirSync as readdirSync37, mkdirSync as mkdirSync65 } from "node:fs";
|
|
605127
|
+
import { existsSync as existsSync108 } from "node:fs";
|
|
604611
605128
|
import { execSync as execSync58 } from "node:child_process";
|
|
604612
605129
|
import { homedir as homedir44 } from "node:os";
|
|
604613
605130
|
function formatTimeAgo2(date) {
|
|
@@ -604625,12 +605142,12 @@ function getVersion4() {
|
|
|
604625
605142
|
const require4 = createRequire6(import.meta.url);
|
|
604626
605143
|
const thisDir = dirname37(fileURLToPath18(import.meta.url));
|
|
604627
605144
|
const candidates = [
|
|
604628
|
-
|
|
604629
|
-
|
|
604630
|
-
|
|
605145
|
+
join124(thisDir, "..", "package.json"),
|
|
605146
|
+
join124(thisDir, "..", "..", "package.json"),
|
|
605147
|
+
join124(thisDir, "..", "..", "..", "package.json")
|
|
604631
605148
|
];
|
|
604632
605149
|
for (const pkgPath of candidates) {
|
|
604633
|
-
if (
|
|
605150
|
+
if (existsSync108(pkgPath)) {
|
|
604634
605151
|
const pkg = require4(pkgPath);
|
|
604635
605152
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
604636
605153
|
return pkg.version ?? "0.0.0";
|
|
@@ -605436,14 +605953,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
|
|
|
605436
605953
|
function gatherMemorySnippets(root) {
|
|
605437
605954
|
const snippets = [];
|
|
605438
605955
|
const dirs = [
|
|
605439
|
-
|
|
605440
|
-
|
|
605956
|
+
join124(root, ".oa", "memory"),
|
|
605957
|
+
join124(root, ".open-agents", "memory")
|
|
605441
605958
|
];
|
|
605442
605959
|
for (const dir of dirs) {
|
|
605443
|
-
if (!
|
|
605960
|
+
if (!existsSync108(dir)) continue;
|
|
605444
605961
|
try {
|
|
605445
605962
|
for (const f2 of readdirSync37(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
605446
|
-
const data = JSON.parse(readFileSync87(
|
|
605963
|
+
const data = JSON.parse(readFileSync87(join124(dir, f2), "utf-8"));
|
|
605447
605964
|
for (const val of Object.values(data)) {
|
|
605448
605965
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
605449
605966
|
if (v.length > 10) snippets.push(v);
|
|
@@ -605597,8 +606114,8 @@ ${metabolismMemories}
|
|
|
605597
606114
|
} catch {
|
|
605598
606115
|
}
|
|
605599
606116
|
try {
|
|
605600
|
-
const archeFile =
|
|
605601
|
-
if (
|
|
606117
|
+
const archeFile = join124(repoRoot, ".oa", "arche", "variants.json");
|
|
606118
|
+
if (existsSync108(archeFile)) {
|
|
605602
606119
|
const variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
605603
606120
|
if (variants.length > 0) {
|
|
605604
606121
|
let filtered = variants;
|
|
@@ -605771,8 +606288,8 @@ RULES:
|
|
|
605771
606288
|
const compactionThreshold = Number.isFinite(envOverride) && envOverride > 0 ? envOverride : modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
605772
606289
|
let identityInjection = "";
|
|
605773
606290
|
try {
|
|
605774
|
-
const ikStateFile =
|
|
605775
|
-
if (
|
|
606291
|
+
const ikStateFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
606292
|
+
if (existsSync108(ikStateFile)) {
|
|
605776
606293
|
const selfState = JSON.parse(readFileSync87(ikStateFile, "utf8"));
|
|
605777
606294
|
const lines = [
|
|
605778
606295
|
`[Identity State v${selfState.version}]`,
|
|
@@ -606635,13 +607152,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606635
607152
|
});
|
|
606636
607153
|
}
|
|
606637
607154
|
try {
|
|
606638
|
-
const ikDir =
|
|
606639
|
-
const ikFile =
|
|
607155
|
+
const ikDir = join124(repoRoot, ".oa", "identity");
|
|
607156
|
+
const ikFile = join124(ikDir, "self-state.json");
|
|
606640
607157
|
let ikState;
|
|
606641
|
-
if (
|
|
607158
|
+
if (existsSync108(ikFile)) {
|
|
606642
607159
|
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
606643
607160
|
} else {
|
|
606644
|
-
|
|
607161
|
+
mkdirSync65(ikDir, { recursive: true });
|
|
606645
607162
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
606646
607163
|
ikState = {
|
|
606647
607164
|
self_id: `oa-${machineId}`,
|
|
@@ -606697,7 +607214,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606697
607214
|
}
|
|
606698
607215
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
606699
607216
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
606700
|
-
|
|
607217
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
606701
607218
|
} catch (ikErr) {
|
|
606702
607219
|
try {
|
|
606703
607220
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -606716,8 +607233,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606716
607233
|
} else {
|
|
606717
607234
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
606718
607235
|
try {
|
|
606719
|
-
const ikFile =
|
|
606720
|
-
if (
|
|
607236
|
+
const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
607237
|
+
if (existsSync108(ikFile)) {
|
|
606721
607238
|
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
606722
607239
|
if (!ikState.stats) ikState.stats = { queries_served: 0 };
|
|
606723
607240
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -606729,7 +607246,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
606729
607246
|
if (ikState.version_history.length > 200) ikState.version_history = ikState.version_history.slice(-200);
|
|
606730
607247
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
606731
607248
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
606732
|
-
|
|
607249
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
606733
607250
|
}
|
|
606734
607251
|
} catch {
|
|
606735
607252
|
}
|
|
@@ -606974,9 +607491,9 @@ async function startInteractive(config, repoPath) {
|
|
|
606974
607491
|
process.stdin.pause();
|
|
606975
607492
|
}
|
|
606976
607493
|
try {
|
|
606977
|
-
const oaDir =
|
|
606978
|
-
const nexusPidFile =
|
|
606979
|
-
if (
|
|
607494
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
607495
|
+
const nexusPidFile = join124(oaDir, "nexus", "daemon.pid");
|
|
607496
|
+
if (existsSync108(nexusPidFile)) {
|
|
606980
607497
|
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
606981
607498
|
if (pid > 0) {
|
|
606982
607499
|
try {
|
|
@@ -607637,7 +608154,7 @@ ${result.summary}`
|
|
|
607637
608154
|
let p2pGateway = null;
|
|
607638
608155
|
let peerMesh = null;
|
|
607639
608156
|
let inferenceRouter = null;
|
|
607640
|
-
const secretVault = new SecretVault(
|
|
608157
|
+
const secretVault = new SecretVault(join124(repoRoot, ".oa", "vault.enc"));
|
|
607641
608158
|
let adminSessionKey = null;
|
|
607642
608159
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
607643
608160
|
const streamRenderer = new StreamRenderer();
|
|
@@ -607868,12 +608385,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
607868
608385
|
const hits = allCompletions.filter((c9) => c9.toLowerCase().startsWith(lower));
|
|
607869
608386
|
return [hits, line];
|
|
607870
608387
|
}
|
|
607871
|
-
const HISTORY_DIR =
|
|
607872
|
-
const HISTORY_FILE =
|
|
608388
|
+
const HISTORY_DIR = join124(homedir44(), ".open-agents");
|
|
608389
|
+
const HISTORY_FILE = join124(HISTORY_DIR, "repl-history");
|
|
607873
608390
|
const MAX_HISTORY_LINES = 500;
|
|
607874
608391
|
let savedHistory = [];
|
|
607875
608392
|
try {
|
|
607876
|
-
if (
|
|
608393
|
+
if (existsSync108(HISTORY_FILE)) {
|
|
607877
608394
|
const raw = readFileSync87(HISTORY_FILE, "utf8").trim();
|
|
607878
608395
|
if (raw) savedHistory = raw.split("\n").reverse();
|
|
607879
608396
|
}
|
|
@@ -608021,12 +608538,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608021
608538
|
function persistHistoryLine(line) {
|
|
608022
608539
|
if (!line.trim()) return;
|
|
608023
608540
|
try {
|
|
608024
|
-
|
|
608541
|
+
mkdirSync65(HISTORY_DIR, { recursive: true });
|
|
608025
608542
|
appendFileSync8(HISTORY_FILE, line + "\n", "utf8");
|
|
608026
608543
|
if (Math.random() < 0.02) {
|
|
608027
608544
|
const all2 = readFileSync87(HISTORY_FILE, "utf8").trim().split("\n");
|
|
608028
608545
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
608029
|
-
|
|
608546
|
+
writeFileSync57(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
608030
608547
|
}
|
|
608031
608548
|
}
|
|
608032
608549
|
} catch {
|
|
@@ -608211,10 +608728,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608211
608728
|
const { unlinkSync: _rmStale } = await import("node:fs");
|
|
608212
608729
|
const { homedir: _hdir } = await import("node:os");
|
|
608213
608730
|
for (const dp of [
|
|
608214
|
-
|
|
608215
|
-
|
|
608731
|
+
join124(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
608732
|
+
join124(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
608216
608733
|
]) {
|
|
608217
|
-
if (
|
|
608734
|
+
if (existsSync108(dp)) try {
|
|
608218
608735
|
_rmStale(dp);
|
|
608219
608736
|
} catch {
|
|
608220
608737
|
}
|
|
@@ -608225,8 +608742,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608225
608742
|
const autoNexus = new NexusTool(repoRoot);
|
|
608226
608743
|
const _registerNexusDaemon = () => {
|
|
608227
608744
|
try {
|
|
608228
|
-
const nexusPidFile =
|
|
608229
|
-
if (
|
|
608745
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
608746
|
+
if (existsSync108(nexusPidFile)) {
|
|
608230
608747
|
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
608231
608748
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
608232
608749
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
@@ -608284,7 +608801,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608284
608801
|
} catch {
|
|
608285
608802
|
}
|
|
608286
608803
|
try {
|
|
608287
|
-
const oaDir =
|
|
608804
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
608288
608805
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
608289
608806
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
608290
608807
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -608316,7 +608833,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608316
608833
|
} catch {
|
|
608317
608834
|
}
|
|
608318
608835
|
try {
|
|
608319
|
-
const oaDir =
|
|
608836
|
+
const oaDir = join124(repoRoot, ".oa");
|
|
608320
608837
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
608321
608838
|
onInfo: (msg) => writeContent(() => renderInfo2(msg)),
|
|
608322
608839
|
onError: (msg) => writeContent(() => renderWarning2(msg))
|
|
@@ -608357,10 +608874,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608357
608874
|
}
|
|
608358
608875
|
try {
|
|
608359
608876
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
608360
|
-
const globalNamePath =
|
|
608877
|
+
const globalNamePath = join124(_hd(), ".open-agents", "agent-name");
|
|
608361
608878
|
let agName = "";
|
|
608362
608879
|
try {
|
|
608363
|
-
if (
|
|
608880
|
+
if (existsSync108(globalNamePath)) agName = readFileSync87(globalNamePath, "utf8").trim();
|
|
608364
608881
|
} catch {
|
|
608365
608882
|
}
|
|
608366
608883
|
if (!agName) {
|
|
@@ -608389,10 +608906,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
608389
608906
|
}
|
|
608390
608907
|
if (!ollamaAlive) {
|
|
608391
608908
|
try {
|
|
608392
|
-
const savedSponsorsPath =
|
|
608909
|
+
const savedSponsorsPath = join124(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
608393
608910
|
let savedSponsors = [];
|
|
608394
608911
|
try {
|
|
608395
|
-
if (
|
|
608912
|
+
if (existsSync108(savedSponsorsPath)) {
|
|
608396
608913
|
savedSponsors = JSON.parse(readFileSync87(savedSponsorsPath, "utf8"));
|
|
608397
608914
|
const oneHourAgo = Date.now() - 36e5;
|
|
608398
608915
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
@@ -609485,10 +610002,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609485
610002
|
if (name10 === "voice_list_files") {
|
|
609486
610003
|
const baseDir = String(args?.dir ?? ".");
|
|
609487
610004
|
const { readdirSync: readdirSync39, statSync: statSync36 } = __require("node:fs");
|
|
609488
|
-
const { join:
|
|
609489
|
-
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(
|
|
610005
|
+
const { join: join129, resolve: resolve43 } = __require("node:path");
|
|
610006
|
+
const base3 = baseDir.startsWith("/") ? baseDir : resolve43(join129(repoRoot, baseDir));
|
|
609490
610007
|
const items = readdirSync39(base3).slice(0, 200).map((f2) => {
|
|
609491
|
-
const s2 = statSync36(
|
|
610008
|
+
const s2 = statSync36(join129(base3, f2));
|
|
609492
610009
|
return { name: f2, dir: s2.isDirectory(), size: s2.size };
|
|
609493
610010
|
});
|
|
609494
610011
|
return JSON.stringify({ dir: base3, items }, null, 2);
|
|
@@ -609576,7 +610093,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609576
610093
|
kind,
|
|
609577
610094
|
targetUrl,
|
|
609578
610095
|
authKey,
|
|
609579
|
-
stateDir:
|
|
610096
|
+
stateDir: join124(repoRoot, ".oa"),
|
|
609580
610097
|
passthrough: passthrough ?? false,
|
|
609581
610098
|
loadbalance: loadbalance ?? false,
|
|
609582
610099
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -609622,7 +610139,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609622
610139
|
await tunnelGateway.stop();
|
|
609623
610140
|
tunnelGateway = null;
|
|
609624
610141
|
}
|
|
609625
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
610142
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join124(repoRoot, ".oa") });
|
|
609626
610143
|
newTunnel.on("stats", (stats) => {
|
|
609627
610144
|
statusBar.setExposeStatus({
|
|
609628
610145
|
status: stats.status,
|
|
@@ -609643,14 +610160,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609643
610160
|
throw err;
|
|
609644
610161
|
}
|
|
609645
610162
|
},
|
|
609646
|
-
async exposeStop(
|
|
609647
|
-
if (!
|
|
610163
|
+
async exposeStop(which2) {
|
|
610164
|
+
if (!which2 || which2 === "tunnel") {
|
|
609648
610165
|
if (tunnelGateway) {
|
|
609649
610166
|
await tunnelGateway.stop();
|
|
609650
610167
|
tunnelGateway = null;
|
|
609651
610168
|
}
|
|
609652
610169
|
}
|
|
609653
|
-
if (!
|
|
610170
|
+
if (!which2 || which2 === "libp2p") {
|
|
609654
610171
|
if (p2pGateway) {
|
|
609655
610172
|
await p2pGateway.stop();
|
|
609656
610173
|
p2pGateway = null;
|
|
@@ -609709,8 +610226,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609709
610226
|
});
|
|
609710
610227
|
if (!result.success) throw new Error(result.error || "Connect failed");
|
|
609711
610228
|
try {
|
|
609712
|
-
const nexusPidFile =
|
|
609713
|
-
if (
|
|
610229
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
610230
|
+
if (existsSync108(nexusPidFile)) {
|
|
609714
610231
|
const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
609715
610232
|
if (pid > 0) {
|
|
609716
610233
|
registry2.register({
|
|
@@ -609899,9 +610416,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609899
610416
|
writeContent(() => renderInfo2(`Killed ${bgKilled} background task(s).`));
|
|
609900
610417
|
}
|
|
609901
610418
|
try {
|
|
609902
|
-
const nexusDir =
|
|
609903
|
-
const pidFile =
|
|
609904
|
-
if (
|
|
610419
|
+
const nexusDir = join124(repoRoot, OA_DIR, "nexus");
|
|
610420
|
+
const pidFile = join124(nexusDir, "daemon.pid");
|
|
610421
|
+
if (existsSync108(pidFile)) {
|
|
609905
610422
|
const pid = parseInt(readFileSync87(pidFile, "utf8").trim(), 10);
|
|
609906
610423
|
if (pid > 0) {
|
|
609907
610424
|
try {
|
|
@@ -609924,11 +610441,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609924
610441
|
} catch {
|
|
609925
610442
|
}
|
|
609926
610443
|
try {
|
|
609927
|
-
const voiceDir2 =
|
|
610444
|
+
const voiceDir2 = join124(homedir44(), ".open-agents", "voice");
|
|
609928
610445
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
609929
610446
|
for (const pf of voicePidFiles) {
|
|
609930
|
-
const pidPath =
|
|
609931
|
-
if (
|
|
610447
|
+
const pidPath = join124(voiceDir2, pf);
|
|
610448
|
+
if (existsSync108(pidPath)) {
|
|
609932
610449
|
try {
|
|
609933
610450
|
const pid = parseInt(readFileSync87(pidPath, "utf8").trim(), 10);
|
|
609934
610451
|
if (pid > 0) {
|
|
@@ -609954,8 +610471,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
609954
610471
|
execSync58(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
609955
610472
|
} catch {
|
|
609956
610473
|
}
|
|
609957
|
-
const oaPath =
|
|
609958
|
-
if (
|
|
610474
|
+
const oaPath = join124(repoRoot, OA_DIR);
|
|
610475
|
+
if (existsSync108(oaPath)) {
|
|
609959
610476
|
let deleted = false;
|
|
609960
610477
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
609961
610478
|
try {
|
|
@@ -610039,18 +610556,18 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
610039
610556
|
try {
|
|
610040
610557
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
610041
610558
|
if (isPersonaPlexRunning2()) {
|
|
610042
|
-
const ppPidFile =
|
|
610043
|
-
const ppPortFile =
|
|
610044
|
-
if (
|
|
610559
|
+
const ppPidFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
610560
|
+
const ppPortFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
610561
|
+
if (existsSync108(ppPidFile)) {
|
|
610045
610562
|
const ppPid = parseInt(readFileSync87(ppPidFile, "utf8").trim(), 10);
|
|
610046
|
-
const ppPort =
|
|
610563
|
+
const ppPort = existsSync108(ppPortFile) ? parseInt(readFileSync87(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
610047
610564
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
610048
610565
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
610049
610566
|
}
|
|
610050
610567
|
}
|
|
610051
610568
|
}
|
|
610052
|
-
const nexusPidFile =
|
|
610053
|
-
if (
|
|
610569
|
+
const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
610570
|
+
if (existsSync108(nexusPidFile)) {
|
|
610054
610571
|
const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
|
|
610055
610572
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
610056
610573
|
try {
|
|
@@ -610418,9 +610935,9 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
610418
610935
|
}
|
|
610419
610936
|
}
|
|
610420
610937
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
610421
|
-
const isImage = isImagePath(cleanPath) &&
|
|
610422
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
610423
|
-
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) &&
|
|
610938
|
+
const isImage = isImagePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610939
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610940
|
+
const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
|
|
610424
610941
|
if (activeTask) {
|
|
610425
610942
|
if (activeTask.runner.isPaused) {
|
|
610426
610943
|
activeTask.runner.resume();
|
|
@@ -611007,13 +611524,13 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611007
611524
|
const handle2 = startTask(task, config, repoRoot);
|
|
611008
611525
|
await handle2.promise;
|
|
611009
611526
|
try {
|
|
611010
|
-
const ikDir =
|
|
611011
|
-
const ikFile =
|
|
611527
|
+
const ikDir = join124(repoRoot, ".oa", "identity");
|
|
611528
|
+
const ikFile = join124(ikDir, "self-state.json");
|
|
611012
611529
|
let ikState;
|
|
611013
|
-
if (
|
|
611530
|
+
if (existsSync108(ikFile)) {
|
|
611014
611531
|
ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
611015
611532
|
} else {
|
|
611016
|
-
|
|
611533
|
+
mkdirSync65(ikDir, { recursive: true });
|
|
611017
611534
|
ikState = {
|
|
611018
611535
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
611019
611536
|
version: 1,
|
|
@@ -611035,7 +611552,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611035
611552
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
611036
611553
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
611037
611554
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
611038
|
-
|
|
611555
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
611039
611556
|
} catch (ikErr) {
|
|
611040
611557
|
}
|
|
611041
611558
|
try {
|
|
@@ -611048,11 +611565,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611048
611565
|
);
|
|
611049
611566
|
} catch {
|
|
611050
611567
|
try {
|
|
611051
|
-
const archeDir =
|
|
611052
|
-
const archeFile =
|
|
611568
|
+
const archeDir = join124(repoRoot, ".oa", "arche");
|
|
611569
|
+
const archeFile = join124(archeDir, "variants.json");
|
|
611053
611570
|
let variants = [];
|
|
611054
611571
|
try {
|
|
611055
|
-
if (
|
|
611572
|
+
if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
611056
611573
|
} catch {
|
|
611057
611574
|
}
|
|
611058
611575
|
variants.push({
|
|
@@ -611066,14 +611583,14 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611066
611583
|
tags: ["general"]
|
|
611067
611584
|
});
|
|
611068
611585
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
611069
|
-
|
|
611070
|
-
|
|
611586
|
+
mkdirSync65(archeDir, { recursive: true });
|
|
611587
|
+
writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
|
|
611071
611588
|
} catch {
|
|
611072
611589
|
}
|
|
611073
611590
|
}
|
|
611074
611591
|
try {
|
|
611075
|
-
const metaFile =
|
|
611076
|
-
if (
|
|
611592
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611593
|
+
if (existsSync108(metaFile)) {
|
|
611077
611594
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611078
611595
|
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);
|
|
611079
611596
|
let updated = false;
|
|
@@ -611085,7 +611602,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
611085
611602
|
updated = true;
|
|
611086
611603
|
}
|
|
611087
611604
|
if (updated) {
|
|
611088
|
-
|
|
611605
|
+
writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
|
|
611089
611606
|
}
|
|
611090
611607
|
}
|
|
611091
611608
|
} catch {
|
|
@@ -611138,9 +611655,9 @@ Rules:
|
|
|
611138
611655
|
try {
|
|
611139
611656
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
611140
611657
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
611141
|
-
const dbDir =
|
|
611142
|
-
|
|
611143
|
-
const db = initDb2(
|
|
611658
|
+
const dbDir = join124(repoRoot, ".oa", "memory");
|
|
611659
|
+
mkdirSync65(dbDir, { recursive: true });
|
|
611660
|
+
const db = initDb2(join124(dbDir, "structured.db"));
|
|
611144
611661
|
const memStore = new ProceduralMemoryStore2(db);
|
|
611145
611662
|
memStore.createWithEmbedding({
|
|
611146
611663
|
content: content.slice(0, 600),
|
|
@@ -611155,11 +611672,11 @@ Rules:
|
|
|
611155
611672
|
db.close();
|
|
611156
611673
|
} catch {
|
|
611157
611674
|
}
|
|
611158
|
-
const metaDir =
|
|
611159
|
-
const storeFile =
|
|
611675
|
+
const metaDir = join124(repoRoot, ".oa", "memory", "metabolism");
|
|
611676
|
+
const storeFile = join124(metaDir, "store.json");
|
|
611160
611677
|
let store2 = [];
|
|
611161
611678
|
try {
|
|
611162
|
-
if (
|
|
611679
|
+
if (existsSync108(storeFile)) store2 = JSON.parse(readFileSync87(storeFile, "utf8"));
|
|
611163
611680
|
} catch {
|
|
611164
611681
|
}
|
|
611165
611682
|
store2.push({
|
|
@@ -611174,25 +611691,25 @@ Rules:
|
|
|
611174
611691
|
accessCount: 0
|
|
611175
611692
|
});
|
|
611176
611693
|
if (store2.length > 100) store2 = store2.slice(-100);
|
|
611177
|
-
|
|
611178
|
-
|
|
611694
|
+
mkdirSync65(metaDir, { recursive: true });
|
|
611695
|
+
writeFileSync57(storeFile, JSON.stringify(store2, null, 2));
|
|
611179
611696
|
}
|
|
611180
611697
|
}
|
|
611181
611698
|
} catch {
|
|
611182
611699
|
}
|
|
611183
611700
|
try {
|
|
611184
|
-
const cohereSettingsFile =
|
|
611701
|
+
const cohereSettingsFile = join124(repoRoot, ".oa", "settings.json");
|
|
611185
611702
|
let cohereActive = false;
|
|
611186
611703
|
try {
|
|
611187
|
-
if (
|
|
611704
|
+
if (existsSync108(cohereSettingsFile)) {
|
|
611188
611705
|
const settings = JSON.parse(readFileSync87(cohereSettingsFile, "utf8"));
|
|
611189
611706
|
cohereActive = settings.cohere === true;
|
|
611190
611707
|
}
|
|
611191
611708
|
} catch {
|
|
611192
611709
|
}
|
|
611193
611710
|
if (cohereActive) {
|
|
611194
|
-
const metaFile =
|
|
611195
|
-
if (
|
|
611711
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611712
|
+
if (existsSync108(metaFile)) {
|
|
611196
611713
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611197
611714
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
611198
611715
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
@@ -611218,17 +611735,17 @@ Rules:
|
|
|
611218
611735
|
}
|
|
611219
611736
|
} catch (err) {
|
|
611220
611737
|
try {
|
|
611221
|
-
const ikFile =
|
|
611222
|
-
if (
|
|
611738
|
+
const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
|
|
611739
|
+
if (existsSync108(ikFile)) {
|
|
611223
611740
|
const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
|
|
611224
611741
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
611225
611742
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
611226
611743
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
611227
611744
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
611228
|
-
|
|
611745
|
+
writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
|
|
611229
611746
|
}
|
|
611230
|
-
const metaFile =
|
|
611231
|
-
if (
|
|
611747
|
+
const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
611748
|
+
if (existsSync108(metaFile)) {
|
|
611232
611749
|
const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
|
|
611233
611750
|
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);
|
|
611234
611751
|
for (const item of surfaced) {
|
|
@@ -611237,14 +611754,14 @@ Rules:
|
|
|
611237
611754
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
611238
611755
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
611239
611756
|
}
|
|
611240
|
-
|
|
611757
|
+
writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
|
|
611241
611758
|
}
|
|
611242
611759
|
try {
|
|
611243
|
-
const archeDir =
|
|
611244
|
-
const archeFile =
|
|
611760
|
+
const archeDir = join124(repoRoot, ".oa", "arche");
|
|
611761
|
+
const archeFile = join124(archeDir, "variants.json");
|
|
611245
611762
|
let variants = [];
|
|
611246
611763
|
try {
|
|
611247
|
-
if (
|
|
611764
|
+
if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
|
|
611248
611765
|
} catch {
|
|
611249
611766
|
}
|
|
611250
611767
|
variants.push({
|
|
@@ -611258,8 +611775,8 @@ Rules:
|
|
|
611258
611775
|
tags: ["general"]
|
|
611259
611776
|
});
|
|
611260
611777
|
if (variants.length > 50) variants = variants.slice(-50);
|
|
611261
|
-
|
|
611262
|
-
|
|
611778
|
+
mkdirSync65(archeDir, { recursive: true });
|
|
611779
|
+
writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
|
|
611263
611780
|
} catch {
|
|
611264
611781
|
}
|
|
611265
611782
|
} catch {
|
|
@@ -611347,14 +611864,14 @@ __export(run_exports, {
|
|
|
611347
611864
|
statusCommand: () => statusCommand
|
|
611348
611865
|
});
|
|
611349
611866
|
import { resolve as resolve40 } from "node:path";
|
|
611350
|
-
import { spawn as
|
|
611351
|
-
import { mkdirSync as
|
|
611867
|
+
import { spawn as spawn27 } from "node:child_process";
|
|
611868
|
+
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58, readFileSync as readFileSync88, readdirSync as readdirSync38, existsSync as existsSync109 } from "node:fs";
|
|
611352
611869
|
import { randomBytes as randomBytes24 } from "node:crypto";
|
|
611353
|
-
import { join as
|
|
611870
|
+
import { join as join125 } from "node:path";
|
|
611354
611871
|
function jobsDir2(repoPath) {
|
|
611355
611872
|
const root = resolve40(repoPath ?? process.cwd());
|
|
611356
|
-
const dir =
|
|
611357
|
-
|
|
611873
|
+
const dir = join125(root, ".oa", "jobs");
|
|
611874
|
+
mkdirSync66(dir, { recursive: true });
|
|
611358
611875
|
return dir;
|
|
611359
611876
|
}
|
|
611360
611877
|
async function runCommand(opts, config) {
|
|
@@ -611460,7 +611977,7 @@ async function runBackground(task, config, opts) {
|
|
|
611460
611977
|
const oaBin = process.argv[1] || "oa";
|
|
611461
611978
|
const args = [task, "--json"];
|
|
611462
611979
|
if (config.model) args.push("--model", config.model);
|
|
611463
|
-
const child =
|
|
611980
|
+
const child = spawn27(process.execPath, [oaBin, ...args], {
|
|
611464
611981
|
cwd: repoRoot,
|
|
611465
611982
|
env: { ...process.env, OA_JOB_ID: id },
|
|
611466
611983
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -611476,7 +611993,7 @@ async function runBackground(task, config, opts) {
|
|
|
611476
611993
|
}
|
|
611477
611994
|
});
|
|
611478
611995
|
job.pid = child.pid ?? 0;
|
|
611479
|
-
|
|
611996
|
+
writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
611480
611997
|
let output = "";
|
|
611481
611998
|
child.stdout?.on("data", (chunk) => {
|
|
611482
611999
|
output += chunk.toString();
|
|
@@ -611492,7 +612009,7 @@ async function runBackground(task, config, opts) {
|
|
|
611492
612009
|
job.summary = result.summary;
|
|
611493
612010
|
job.durationMs = result.durationMs;
|
|
611494
612011
|
job.error = result.error;
|
|
611495
|
-
|
|
612012
|
+
writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
611496
612013
|
} catch {
|
|
611497
612014
|
}
|
|
611498
612015
|
});
|
|
@@ -611508,8 +612025,8 @@ async function runBackground(task, config, opts) {
|
|
|
611508
612025
|
}
|
|
611509
612026
|
function statusCommand(jobId, repoPath) {
|
|
611510
612027
|
const dir = jobsDir2(repoPath);
|
|
611511
|
-
const file =
|
|
611512
|
-
if (!
|
|
612028
|
+
const file = join125(dir, `${jobId}.json`);
|
|
612029
|
+
if (!existsSync109(file)) {
|
|
611513
612030
|
console.error(`Job not found: ${jobId}`);
|
|
611514
612031
|
console.log(`Available jobs: oa jobs`);
|
|
611515
612032
|
process.exit(1);
|
|
@@ -611535,7 +612052,7 @@ function jobsCommand(repoPath) {
|
|
|
611535
612052
|
console.log("Jobs:");
|
|
611536
612053
|
for (const file of files) {
|
|
611537
612054
|
try {
|
|
611538
|
-
const job = JSON.parse(readFileSync88(
|
|
612055
|
+
const job = JSON.parse(readFileSync88(join125(dir, file), "utf-8"));
|
|
611539
612056
|
const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
|
|
611540
612057
|
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`;
|
|
611541
612058
|
const cleanListTask = cleanForStorage(job.task) || job.task;
|
|
@@ -611559,13 +612076,13 @@ __export(index_repo_exports, {
|
|
|
611559
612076
|
indexRepoCommand: () => indexRepoCommand
|
|
611560
612077
|
});
|
|
611561
612078
|
import { resolve as resolve41 } from "node:path";
|
|
611562
|
-
import { existsSync as
|
|
612079
|
+
import { existsSync as existsSync110, statSync as statSync35 } from "node:fs";
|
|
611563
612080
|
import { cwd as cwd2 } from "node:process";
|
|
611564
612081
|
async function indexRepoCommand(opts, _config3) {
|
|
611565
612082
|
const repoRoot = resolve41(opts.repoPath ?? cwd2());
|
|
611566
612083
|
printHeader("Index Repository");
|
|
611567
612084
|
printInfo(`Indexing: ${repoRoot}`);
|
|
611568
|
-
if (!
|
|
612085
|
+
if (!existsSync110(repoRoot)) {
|
|
611569
612086
|
printError(`Path does not exist: ${repoRoot}`);
|
|
611570
612087
|
process.exit(1);
|
|
611571
612088
|
}
|
|
@@ -611817,7 +612334,7 @@ var config_exports2 = {};
|
|
|
611817
612334
|
__export(config_exports2, {
|
|
611818
612335
|
configCommand: () => configCommand
|
|
611819
612336
|
});
|
|
611820
|
-
import { join as
|
|
612337
|
+
import { join as join126, resolve as resolve42 } from "node:path";
|
|
611821
612338
|
import { homedir as homedir45 } from "node:os";
|
|
611822
612339
|
import { cwd as cwd3 } from "node:process";
|
|
611823
612340
|
function redactIfSensitive(key, value2) {
|
|
@@ -611899,7 +612416,7 @@ function handleShow(opts, config) {
|
|
|
611899
612416
|
}
|
|
611900
612417
|
}
|
|
611901
612418
|
printSection("Config File");
|
|
611902
|
-
printInfo(`~/.open-agents/config.json (${
|
|
612419
|
+
printInfo(`~/.open-agents/config.json (${join126(homedir45(), ".open-agents", "config.json")})`);
|
|
611903
612420
|
printSection("Priority Chain");
|
|
611904
612421
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
611905
612422
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -611938,7 +612455,7 @@ function handleSet(opts, _config3) {
|
|
|
611938
612455
|
const coerced = coerceForSettings(key, value2);
|
|
611939
612456
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
611940
612457
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
|
|
611941
|
-
printInfo(`Saved to ${
|
|
612458
|
+
printInfo(`Saved to ${join126(repoRoot, ".oa", "settings.json")}`);
|
|
611942
612459
|
printInfo("This override applies only when running in this workspace.");
|
|
611943
612460
|
} catch (err) {
|
|
611944
612461
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -612121,9 +612638,9 @@ var eval_exports = {};
|
|
|
612121
612638
|
__export(eval_exports, {
|
|
612122
612639
|
evalCommand: () => evalCommand
|
|
612123
612640
|
});
|
|
612124
|
-
import { tmpdir as
|
|
612125
|
-
import { mkdirSync as
|
|
612126
|
-
import { join as
|
|
612641
|
+
import { tmpdir as tmpdir22 } from "node:os";
|
|
612642
|
+
import { mkdirSync as mkdirSync67, writeFileSync as writeFileSync59 } from "node:fs";
|
|
612643
|
+
import { join as join127 } from "node:path";
|
|
612127
612644
|
async function evalCommand(opts, config) {
|
|
612128
612645
|
const suiteName = opts.suite ?? "basic";
|
|
612129
612646
|
const suite = SUITES[suiteName];
|
|
@@ -612252,10 +612769,10 @@ async function evalCommand(opts, config) {
|
|
|
612252
612769
|
process.exit(failed > 0 ? 1 : 0);
|
|
612253
612770
|
}
|
|
612254
612771
|
function createTempEvalRepo() {
|
|
612255
|
-
const dir =
|
|
612256
|
-
|
|
612257
|
-
|
|
612258
|
-
|
|
612772
|
+
const dir = join127(tmpdir22(), `open-agents-eval-${Date.now()}`);
|
|
612773
|
+
mkdirSync67(dir, { recursive: true });
|
|
612774
|
+
writeFileSync59(
|
|
612775
|
+
join127(dir, "package.json"),
|
|
612259
612776
|
JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
|
|
612260
612777
|
"utf8"
|
|
612261
612778
|
);
|
|
@@ -612319,7 +612836,7 @@ init_typed_node_events();
|
|
|
612319
612836
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
612320
612837
|
import { createRequire as createRequire7 } from "node:module";
|
|
612321
612838
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
612322
|
-
import { dirname as dirname38, join as
|
|
612839
|
+
import { dirname as dirname38, join as join128 } from "node:path";
|
|
612323
612840
|
|
|
612324
612841
|
// packages/cli/src/cli.ts
|
|
612325
612842
|
init_typed_node_events();
|
|
@@ -612459,7 +612976,7 @@ init_output();
|
|
|
612459
612976
|
function getVersion5() {
|
|
612460
612977
|
try {
|
|
612461
612978
|
const require4 = createRequire7(import.meta.url);
|
|
612462
|
-
const pkgPath =
|
|
612979
|
+
const pkgPath = join128(dirname38(fileURLToPath19(import.meta.url)), "..", "package.json");
|
|
612463
612980
|
const pkg = require4(pkgPath);
|
|
612464
612981
|
return pkg.version;
|
|
612465
612982
|
} catch {
|
|
@@ -612648,9 +613165,9 @@ async function main() {
|
|
|
612648
613165
|
const mode = process.argv[process.argv.indexOf("--self-test") + 1] || "crossmodal";
|
|
612649
613166
|
if (mode === "crossmodal") {
|
|
612650
613167
|
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
612651
|
-
const { spawn:
|
|
613168
|
+
const { spawn: spawn28 } = await import("node:child_process");
|
|
612652
613169
|
const run = (file) => new Promise((resolve43, reject) => {
|
|
612653
|
-
const p2 =
|
|
613170
|
+
const p2 = spawn28(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
612654
613171
|
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
612655
613172
|
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
612656
613173
|
onChildExit(p2, (code8) => code8 === 0 ? resolve43() : reject(new Error(`${file} exited ${code8}`)));
|
|
@@ -612773,12 +613290,12 @@ function crashLog(label, err) {
|
|
|
612773
613290
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
612774
613291
|
`;
|
|
612775
613292
|
try {
|
|
612776
|
-
const { appendFileSync: appendFileSync9, mkdirSync:
|
|
612777
|
-
const { join:
|
|
613293
|
+
const { appendFileSync: appendFileSync9, mkdirSync: mkdirSync68 } = __require("node:fs");
|
|
613294
|
+
const { join: join129 } = __require("node:path");
|
|
612778
613295
|
const { homedir: homedir46 } = __require("node:os");
|
|
612779
|
-
const logDir =
|
|
612780
|
-
|
|
612781
|
-
appendFileSync9(
|
|
613296
|
+
const logDir = join129(homedir46(), ".open-agents");
|
|
613297
|
+
mkdirSync68(logDir, { recursive: true });
|
|
613298
|
+
appendFileSync9(join129(logDir, "crash.log"), logLine);
|
|
612782
613299
|
} catch {
|
|
612783
613300
|
}
|
|
612784
613301
|
try {
|