open-agents-ai 0.184.1 → 0.184.3
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 +1094 -502
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -61,11 +61,11 @@ function parseBackendType(value) {
|
|
|
61
61
|
return VALID_BACKEND_TYPES.has(value) ? value : void 0;
|
|
62
62
|
}
|
|
63
63
|
function loadConfigFile() {
|
|
64
|
-
const
|
|
65
|
-
if (!existsSync(
|
|
64
|
+
const configPath2 = join(homedir(), ".open-agents", "config.json");
|
|
65
|
+
if (!existsSync(configPath2))
|
|
66
66
|
return {};
|
|
67
67
|
try {
|
|
68
|
-
const raw = readFileSync(
|
|
68
|
+
const raw = readFileSync(configPath2, "utf8");
|
|
69
69
|
const parsed = JSON.parse(raw);
|
|
70
70
|
const result = {};
|
|
71
71
|
if (typeof parsed.backendUrl === "string")
|
|
@@ -111,10 +111,10 @@ function mergeConfig(base, overrides) {
|
|
|
111
111
|
function setConfigValue(key, value) {
|
|
112
112
|
const dir = join(homedir(), ".open-agents");
|
|
113
113
|
mkdirSync(dir, { recursive: true });
|
|
114
|
-
const
|
|
114
|
+
const configPath2 = join(dir, "config.json");
|
|
115
115
|
const existing = loadConfigFile();
|
|
116
116
|
existing[key] = coerceConfigValue(key, value);
|
|
117
|
-
writeFileSync(
|
|
117
|
+
writeFileSync(configPath2, JSON.stringify(existing, null, 2) + "\n", { encoding: "utf8", mode: 384 });
|
|
118
118
|
}
|
|
119
119
|
function coerceConfigValue(key, value) {
|
|
120
120
|
const intKeys = /* @__PURE__ */ new Set(["maxRetries", "timeoutMs"]);
|
|
@@ -13402,9 +13402,9 @@ print("${sentinel}")
|
|
|
13402
13402
|
if (!this.proc || this.proc.killed) {
|
|
13403
13403
|
return { success: false, path: "" };
|
|
13404
13404
|
}
|
|
13405
|
-
const { mkdirSync:
|
|
13405
|
+
const { mkdirSync: mkdirSync27, writeFileSync: writeFileSync26 } = await import("node:fs");
|
|
13406
13406
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13407
|
-
|
|
13407
|
+
mkdirSync27(sessionDir, { recursive: true });
|
|
13408
13408
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13409
13409
|
try {
|
|
13410
13410
|
const inspectCode = `
|
|
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13428
13428
|
trajectoryCount: this.trajectory.length,
|
|
13429
13429
|
subCallCount: this.subCallCount
|
|
13430
13430
|
};
|
|
13431
|
-
|
|
13431
|
+
writeFileSync26(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13432
13432
|
return { success: true, path: sessionPath };
|
|
13433
13433
|
}
|
|
13434
13434
|
} catch {
|
|
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13440
13440
|
* what was previously computed. */
|
|
13441
13441
|
async loadSessionInfo() {
|
|
13442
13442
|
try {
|
|
13443
|
-
const { readFileSync:
|
|
13443
|
+
const { readFileSync: readFileSync41, existsSync: existsSync53 } = await import("node:fs");
|
|
13444
13444
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13445
|
-
if (!
|
|
13445
|
+
if (!existsSync53(sessionPath))
|
|
13446
13446
|
return null;
|
|
13447
|
-
return JSON.parse(
|
|
13447
|
+
return JSON.parse(readFileSync41(sessionPath, "utf8"));
|
|
13448
13448
|
} catch {
|
|
13449
13449
|
return null;
|
|
13450
13450
|
}
|
|
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
|
|
|
13621
13621
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
13622
13622
|
let lessons = [];
|
|
13623
13623
|
try {
|
|
13624
|
-
const { readdirSync: readdirSync21, readFileSync:
|
|
13624
|
+
const { readdirSync: readdirSync21, readFileSync: readFileSync41 } = await import("node:fs");
|
|
13625
13625
|
const files = readdirSync21(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
13626
13626
|
for (const file of files) {
|
|
13627
|
-
const lines =
|
|
13627
|
+
const lines = readFileSync41(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
13628
13628
|
for (const line of lines) {
|
|
13629
13629
|
try {
|
|
13630
13630
|
const entry = JSON.parse(line);
|
|
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14008
14008
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14009
14009
|
*/
|
|
14010
14010
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14011
|
-
const { readFileSync:
|
|
14011
|
+
const { readFileSync: readFileSync41, existsSync: existsSync53 } = __require("node:fs");
|
|
14012
14012
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14013
14013
|
const storeFile = join23(metaDir, "store.json");
|
|
14014
|
-
if (!
|
|
14014
|
+
if (!existsSync53(storeFile))
|
|
14015
14015
|
return "";
|
|
14016
14016
|
let store = [];
|
|
14017
14017
|
try {
|
|
14018
|
-
store = JSON.parse(
|
|
14018
|
+
store = JSON.parse(readFileSync41(storeFile, "utf8"));
|
|
14019
14019
|
} catch {
|
|
14020
14020
|
return "";
|
|
14021
14021
|
}
|
|
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14037
14037
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14038
14038
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14039
14039
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14040
|
-
const { readFileSync:
|
|
14040
|
+
const { readFileSync: readFileSync41, writeFileSync: writeFileSync26, existsSync: existsSync53, mkdirSync: mkdirSync27 } = __require("node:fs");
|
|
14041
14041
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14042
14042
|
const storeFile = join23(metaDir, "store.json");
|
|
14043
|
-
if (!
|
|
14043
|
+
if (!existsSync53(storeFile))
|
|
14044
14044
|
return;
|
|
14045
14045
|
let store = [];
|
|
14046
14046
|
try {
|
|
14047
|
-
store = JSON.parse(
|
|
14047
|
+
store = JSON.parse(readFileSync41(storeFile, "utf8"));
|
|
14048
14048
|
} catch {
|
|
14049
14049
|
return;
|
|
14050
14050
|
}
|
|
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14068
14068
|
updated = true;
|
|
14069
14069
|
}
|
|
14070
14070
|
if (updated) {
|
|
14071
|
-
|
|
14072
|
-
|
|
14071
|
+
mkdirSync27(metaDir, { recursive: true });
|
|
14072
|
+
writeFileSync26(storeFile, JSON.stringify(store, null, 2));
|
|
14073
14073
|
}
|
|
14074
14074
|
}
|
|
14075
14075
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14491
14491
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14492
14492
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14493
14493
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14494
|
-
const { readFileSync:
|
|
14494
|
+
const { readFileSync: readFileSync41, existsSync: existsSync53 } = __require("node:fs");
|
|
14495
14495
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14496
|
-
if (!
|
|
14496
|
+
if (!existsSync53(archiveFile))
|
|
14497
14497
|
return "";
|
|
14498
14498
|
let variants = [];
|
|
14499
14499
|
try {
|
|
14500
|
-
variants = JSON.parse(
|
|
14500
|
+
variants = JSON.parse(readFileSync41(archiveFile, "utf8"));
|
|
14501
14501
|
} catch {
|
|
14502
14502
|
return "";
|
|
14503
14503
|
}
|
|
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14515
14515
|
}
|
|
14516
14516
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14517
14517
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14518
|
-
const { readFileSync:
|
|
14518
|
+
const { readFileSync: readFileSync41, writeFileSync: writeFileSync26, existsSync: existsSync53, mkdirSync: mkdirSync27 } = __require("node:fs");
|
|
14519
14519
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14520
14520
|
const archiveFile = join25(dir, "variants.json");
|
|
14521
14521
|
let variants = [];
|
|
14522
14522
|
try {
|
|
14523
|
-
if (
|
|
14524
|
-
variants = JSON.parse(
|
|
14523
|
+
if (existsSync53(archiveFile))
|
|
14524
|
+
variants = JSON.parse(readFileSync41(archiveFile, "utf8"));
|
|
14525
14525
|
} catch {
|
|
14526
14526
|
}
|
|
14527
14527
|
variants.push({
|
|
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14536
14536
|
});
|
|
14537
14537
|
if (variants.length > 50)
|
|
14538
14538
|
variants = variants.slice(-50);
|
|
14539
|
-
|
|
14540
|
-
|
|
14539
|
+
mkdirSync27(dir, { recursive: true });
|
|
14540
|
+
writeFileSync26(archiveFile, JSON.stringify(variants, null, 2));
|
|
14541
14541
|
}
|
|
14542
14542
|
async saveArchive(variants) {
|
|
14543
14543
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -26895,10 +26895,10 @@ ${marker}` : marker);
|
|
|
26895
26895
|
if (!this._workingDirectory)
|
|
26896
26896
|
return;
|
|
26897
26897
|
try {
|
|
26898
|
-
const { mkdirSync:
|
|
26899
|
-
const { join:
|
|
26900
|
-
const sessionDir =
|
|
26901
|
-
|
|
26898
|
+
const { mkdirSync: mkdirSync27, writeFileSync: writeFileSync26 } = __require("node:fs");
|
|
26899
|
+
const { join: join73 } = __require("node:path");
|
|
26900
|
+
const sessionDir = join73(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
26901
|
+
mkdirSync27(sessionDir, { recursive: true });
|
|
26902
26902
|
const checkpoint = {
|
|
26903
26903
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26904
26904
|
sessionId: this._sessionId,
|
|
@@ -26910,7 +26910,7 @@ ${marker}` : marker);
|
|
|
26910
26910
|
memexEntryCount: this._memexArchive.size,
|
|
26911
26911
|
fileRegistrySize: this._fileRegistry.size
|
|
26912
26912
|
};
|
|
26913
|
-
|
|
26913
|
+
writeFileSync26(join73(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
26914
26914
|
} catch {
|
|
26915
26915
|
}
|
|
26916
26916
|
}
|
|
@@ -34617,6 +34617,10 @@ var init_render = __esm({
|
|
|
34617
34617
|
["/nexus restart --clean", "Restart + clear metering data for fresh stats"],
|
|
34618
34618
|
["/nexus disconnect", "Kill daemon without reconnecting"],
|
|
34619
34619
|
["/nexus wallet", "Show wallet address and x402 payment status"],
|
|
34620
|
+
["/sponsor", "Sponsor inference \u2014 onboarding wizard or dashboard"],
|
|
34621
|
+
["/sponsor status", "Show sponsor dashboard with usage metrics"],
|
|
34622
|
+
["/sponsor pause", "Pause active sponsorship"],
|
|
34623
|
+
["/sponsor remove", "Remove sponsorship entirely"],
|
|
34620
34624
|
["/expose <backend>", "Expose local inference via libp2p (default)"],
|
|
34621
34625
|
["/expose <backend> --tunnel", "Expose via cloudflared tunnel"],
|
|
34622
34626
|
["/expose passthrough", "Forward configured /endpoint through libp2p P2P"],
|
|
@@ -35573,6 +35577,9 @@ var init_expose = __esm({
|
|
|
35573
35577
|
/** Periodic PID watchdog for reconnect mode (no ChildProcess close event) */
|
|
35574
35578
|
_pidWatchdog = null;
|
|
35575
35579
|
_tunnelUrl = null;
|
|
35580
|
+
/** Debounce tracking for tunnel restarts */
|
|
35581
|
+
_lastRestartAttempt = 0;
|
|
35582
|
+
_consecutiveFailures = 0;
|
|
35576
35583
|
_authKey;
|
|
35577
35584
|
_targetUrl;
|
|
35578
35585
|
_kind;
|
|
@@ -35634,16 +35641,19 @@ var init_expose = __esm({
|
|
|
35634
35641
|
this.server.on("error", reject);
|
|
35635
35642
|
});
|
|
35636
35643
|
let lastStartErr;
|
|
35644
|
+
this._consecutiveFailures = 0;
|
|
35637
35645
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
35638
35646
|
try {
|
|
35647
|
+
this._lastRestartAttempt = Date.now();
|
|
35639
35648
|
this._tunnelUrl = await this.startCloudflared(port);
|
|
35649
|
+
this._consecutiveFailures = 0;
|
|
35640
35650
|
break;
|
|
35641
35651
|
} catch (err) {
|
|
35642
35652
|
lastStartErr = err instanceof Error ? err : new Error(String(err));
|
|
35643
|
-
|
|
35644
|
-
if (
|
|
35645
|
-
const delaySec = (
|
|
35646
|
-
this.options.onInfo?.(`
|
|
35653
|
+
this._consecutiveFailures++;
|
|
35654
|
+
if (attempt < 2) {
|
|
35655
|
+
const delaySec = Math.min(15 * Math.pow(2, attempt), 60);
|
|
35656
|
+
this.options.onInfo?.(`Tunnel start failed \u2014 retrying in ${delaySec}s (attempt ${attempt + 2}/3)...`);
|
|
35647
35657
|
await new Promise((r) => setTimeout(r, delaySec * 1e3));
|
|
35648
35658
|
continue;
|
|
35649
35659
|
}
|
|
@@ -36052,9 +36062,19 @@ var init_expose = __esm({
|
|
|
36052
36062
|
startCloudflared(port) {
|
|
36053
36063
|
this._proxyPort = port;
|
|
36054
36064
|
return new Promise((resolve35, reject) => {
|
|
36065
|
+
const TUNNEL_TIMEOUT_MS = 6e4;
|
|
36055
36066
|
const timeout = setTimeout(() => {
|
|
36056
|
-
reject(new Error("Cloudflared tunnel start timeout (
|
|
36057
|
-
},
|
|
36067
|
+
reject(new Error("Cloudflared tunnel start timeout (60s). Slow network? Try again."));
|
|
36068
|
+
}, TUNNEL_TIMEOUT_MS);
|
|
36069
|
+
let elapsed = 0;
|
|
36070
|
+
const progressInterval = setInterval(() => {
|
|
36071
|
+
elapsed += 5;
|
|
36072
|
+
this.options.onInfo?.(`Starting cloudflared tunnel... (${elapsed}s)`);
|
|
36073
|
+
}, 5e3);
|
|
36074
|
+
const cleanTimers = () => {
|
|
36075
|
+
clearTimeout(timeout);
|
|
36076
|
+
clearInterval(progressInterval);
|
|
36077
|
+
};
|
|
36058
36078
|
this.cloudflaredProcess = spawn18("cloudflared", [
|
|
36059
36079
|
"tunnel",
|
|
36060
36080
|
"--url",
|
|
@@ -36074,9 +36094,14 @@ var init_expose = __esm({
|
|
|
36074
36094
|
if (stderrOutput.length > 4096)
|
|
36075
36095
|
stderrOutput = stderrOutput.slice(-4096);
|
|
36076
36096
|
const urlMatch = text.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);
|
|
36097
|
+
const statusMatch = text.match(/INF\s+(.*)/);
|
|
36098
|
+
if (statusMatch && !urlFound) {
|
|
36099
|
+
this.options.onInfo?.(`cloudflared: ${statusMatch[1].slice(0, 80)}`);
|
|
36100
|
+
}
|
|
36077
36101
|
if (urlMatch && !urlFound) {
|
|
36078
36102
|
urlFound = true;
|
|
36079
|
-
|
|
36103
|
+
cleanTimers();
|
|
36104
|
+
this._consecutiveFailures = 0;
|
|
36080
36105
|
this.cloudflaredProcess?.unref();
|
|
36081
36106
|
this.cloudflaredProcess?.stdout?.destroy();
|
|
36082
36107
|
this.cloudflaredProcess?.stderr?.destroy();
|
|
@@ -36086,59 +36111,80 @@ var init_expose = __esm({
|
|
|
36086
36111
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
36087
36112
|
this.cloudflaredProcess.stderr?.on("data", handleOutput);
|
|
36088
36113
|
this.cloudflaredProcess.on("error", (err) => {
|
|
36089
|
-
|
|
36090
|
-
|
|
36114
|
+
cleanTimers();
|
|
36115
|
+
const msg = err.message;
|
|
36116
|
+
if (msg.includes("ENOENT")) {
|
|
36117
|
+
reject(new Error("cloudflared not installed. Install: brew install cloudflared (macOS) or download from https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"));
|
|
36118
|
+
} else {
|
|
36119
|
+
reject(new Error(`Failed to start cloudflared: ${msg}`));
|
|
36120
|
+
}
|
|
36091
36121
|
});
|
|
36092
36122
|
this.cloudflaredProcess.on("close", (code) => {
|
|
36093
36123
|
if (!urlFound) {
|
|
36094
|
-
|
|
36124
|
+
cleanTimers();
|
|
36095
36125
|
const hint = stderrOutput.trim().split("\n").slice(-3).join(" | ");
|
|
36096
|
-
|
|
36126
|
+
if (hint.includes("address already in use")) {
|
|
36127
|
+
reject(new Error(`Port ${port} already in use. Another expose gateway may be running. Try: /expose stop first.`));
|
|
36128
|
+
} else if (hint.includes("429") || hint.includes("Too Many")) {
|
|
36129
|
+
reject(new Error(`Cloudflare rate limited (429). Wait 60s or use /expose libp2p instead.`));
|
|
36130
|
+
} else {
|
|
36131
|
+
reject(new Error(`Cloudflared exited with code ${code}. ${hint ? "Output: " + hint : ""}`));
|
|
36132
|
+
}
|
|
36097
36133
|
}
|
|
36098
36134
|
if (this._stats.status === "active") {
|
|
36099
|
-
this.options.onInfo?.("Cloudflared tunnel died \u2014 restarting...");
|
|
36100
36135
|
this._stats.status = "error";
|
|
36101
36136
|
this.emitStats();
|
|
36102
|
-
this.
|
|
36137
|
+
this.debouncedRestart();
|
|
36103
36138
|
}
|
|
36104
36139
|
});
|
|
36105
36140
|
});
|
|
36106
36141
|
}
|
|
36107
|
-
/**
|
|
36108
|
-
|
|
36142
|
+
/**
|
|
36143
|
+
* Debounced auto-restart: ensures minimum 10s between attempts,
|
|
36144
|
+
* exponential cooldown on consecutive failures, stops after 3 failures
|
|
36145
|
+
* and waits for manual `/expose tunnel` retry.
|
|
36146
|
+
*/
|
|
36147
|
+
async debouncedRestart() {
|
|
36109
36148
|
if (!this.server || this._proxyPort === 0)
|
|
36110
36149
|
return;
|
|
36111
|
-
|
|
36112
|
-
|
|
36113
|
-
|
|
36114
|
-
|
|
36115
|
-
|
|
36116
|
-
|
|
36150
|
+
this._consecutiveFailures++;
|
|
36151
|
+
if (this._consecutiveFailures >= 3) {
|
|
36152
|
+
this._stats.status = "standby";
|
|
36153
|
+
this.emitStats();
|
|
36154
|
+
this.options.onError?.(`Tunnel failed to start after ${this._consecutiveFailures} attempts.
|
|
36155
|
+
Type /expose tunnel to retry manually, or /expose libp2p as alternative.`);
|
|
36156
|
+
return;
|
|
36157
|
+
}
|
|
36158
|
+
const cooldownSec = Math.min(10 * Math.pow(2, this._consecutiveFailures - 1), 300);
|
|
36159
|
+
const sinceLast = (Date.now() - this._lastRestartAttempt) / 1e3;
|
|
36160
|
+
const waitSec = Math.max(cooldownSec - sinceLast, 0);
|
|
36161
|
+
if (waitSec > 0) {
|
|
36162
|
+
this.options.onInfo?.(`Tunnel died \u2014 will retry in ${Math.ceil(waitSec)}s (attempt ${this._consecutiveFailures + 1}/3)...`);
|
|
36163
|
+
await new Promise((r) => setTimeout(r, waitSec * 1e3));
|
|
36164
|
+
}
|
|
36165
|
+
this._lastRestartAttempt = Date.now();
|
|
36166
|
+
try {
|
|
36167
|
+
this._tunnelUrl = await this.startCloudflared(this._proxyPort);
|
|
36168
|
+
this._stats.status = "active";
|
|
36169
|
+
this._consecutiveFailures = 0;
|
|
36170
|
+
this.emitStats();
|
|
36171
|
+
this.options.onInfo?.(`Tunnel restarted with new URL \u2014 share with consumers:
|
|
36117
36172
|
${this.formatConnectionInfo()}`);
|
|
36118
|
-
|
|
36119
|
-
|
|
36120
|
-
|
|
36121
|
-
|
|
36122
|
-
|
|
36123
|
-
|
|
36124
|
-
|
|
36125
|
-
|
|
36126
|
-
|
|
36127
|
-
|
|
36128
|
-
}
|
|
36129
|
-
return;
|
|
36130
|
-
} catch (err) {
|
|
36131
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
36132
|
-
const is429 = msg.includes("429") || msg.includes("Too Many Requests");
|
|
36133
|
-
if (is429 && attempt < 2) {
|
|
36134
|
-
const delaySec = (attempt + 1) * 15;
|
|
36135
|
-
this.options.onInfo?.(`Cloudflare rate limited \u2014 retrying in ${delaySec}s...`);
|
|
36136
|
-
await new Promise((r) => setTimeout(r, delaySec * 1e3));
|
|
36137
|
-
continue;
|
|
36138
|
-
}
|
|
36139
|
-
this.options.onError?.(`Tunnel restart failed: ${msg}`);
|
|
36140
|
-
return;
|
|
36173
|
+
if (this._stateDir) {
|
|
36174
|
+
writeExposeState(this._stateDir, {
|
|
36175
|
+
pid: this._cloudflaredPid,
|
|
36176
|
+
tunnelUrl: this._tunnelUrl,
|
|
36177
|
+
authKey: this._authKey,
|
|
36178
|
+
proxyPort: this._proxyPort,
|
|
36179
|
+
targetUrl: this._targetUrl,
|
|
36180
|
+
kind: this._kind,
|
|
36181
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
36182
|
+
});
|
|
36141
36183
|
}
|
|
36184
|
+
} catch (err) {
|
|
36185
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
36186
|
+
this.options.onError?.(`Tunnel restart failed (attempt ${this._consecutiveFailures}/3): ${msg}`);
|
|
36187
|
+
this.debouncedRestart();
|
|
36142
36188
|
}
|
|
36143
36189
|
}
|
|
36144
36190
|
/**
|
|
@@ -36155,7 +36201,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
36155
36201
|
this.options.onInfo?.("Cloudflared tunnel died (detected by watchdog) \u2014 restarting...");
|
|
36156
36202
|
this._stats.status = "error";
|
|
36157
36203
|
this.emitStats();
|
|
36158
|
-
this.
|
|
36204
|
+
this.debouncedRestart();
|
|
36159
36205
|
}
|
|
36160
36206
|
}
|
|
36161
36207
|
}, 1e4);
|
|
@@ -38138,26 +38184,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
38138
38184
|
async function fetchPeerModels(peerId, authKey) {
|
|
38139
38185
|
try {
|
|
38140
38186
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
38141
|
-
const { existsSync:
|
|
38142
|
-
const { join:
|
|
38187
|
+
const { existsSync: existsSync53, readFileSync: readFileSync41 } = await import("node:fs");
|
|
38188
|
+
const { join: join73 } = await import("node:path");
|
|
38143
38189
|
const cwd4 = process.cwd();
|
|
38144
38190
|
const nexusTool = new NexusTool2(cwd4);
|
|
38145
38191
|
const nexusDir = nexusTool.getNexusDir();
|
|
38146
38192
|
let isLocalPeer = false;
|
|
38147
38193
|
try {
|
|
38148
|
-
const statusPath =
|
|
38149
|
-
if (
|
|
38150
|
-
const status = JSON.parse(
|
|
38194
|
+
const statusPath = join73(nexusDir, "status.json");
|
|
38195
|
+
if (existsSync53(statusPath)) {
|
|
38196
|
+
const status = JSON.parse(readFileSync41(statusPath, "utf8"));
|
|
38151
38197
|
if (status.peerId === peerId)
|
|
38152
38198
|
isLocalPeer = true;
|
|
38153
38199
|
}
|
|
38154
38200
|
} catch {
|
|
38155
38201
|
}
|
|
38156
38202
|
if (isLocalPeer) {
|
|
38157
|
-
const pricingPath =
|
|
38158
|
-
if (
|
|
38203
|
+
const pricingPath = join73(nexusDir, "pricing.json");
|
|
38204
|
+
if (existsSync53(pricingPath)) {
|
|
38159
38205
|
try {
|
|
38160
|
-
const pricing = JSON.parse(
|
|
38206
|
+
const pricing = JSON.parse(readFileSync41(pricingPath, "utf8"));
|
|
38161
38207
|
const localModels = (pricing.models || []).map((m) => ({
|
|
38162
38208
|
name: m.model || "unknown",
|
|
38163
38209
|
size: m.parameterSize || "",
|
|
@@ -38171,10 +38217,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
38171
38217
|
}
|
|
38172
38218
|
}
|
|
38173
38219
|
}
|
|
38174
|
-
const cachePath =
|
|
38175
|
-
if (
|
|
38220
|
+
const cachePath = join73(nexusDir, "peer-models-cache.json");
|
|
38221
|
+
if (existsSync53(cachePath)) {
|
|
38176
38222
|
try {
|
|
38177
|
-
const cache4 = JSON.parse(
|
|
38223
|
+
const cache4 = JSON.parse(readFileSync41(cachePath, "utf8"));
|
|
38178
38224
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
38179
38225
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
38180
38226
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -38289,10 +38335,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
38289
38335
|
} catch {
|
|
38290
38336
|
}
|
|
38291
38337
|
if (isLocalPeer) {
|
|
38292
|
-
const pricingPath =
|
|
38293
|
-
if (
|
|
38338
|
+
const pricingPath = join73(nexusDir, "pricing.json");
|
|
38339
|
+
if (existsSync53(pricingPath)) {
|
|
38294
38340
|
try {
|
|
38295
|
-
const pricing = JSON.parse(
|
|
38341
|
+
const pricing = JSON.parse(readFileSync41(pricingPath, "utf8"));
|
|
38296
38342
|
return (pricing.models || []).map((m) => ({
|
|
38297
38343
|
name: m.model || "unknown",
|
|
38298
38344
|
size: m.parameterSize || "",
|
|
@@ -42325,6 +42371,471 @@ var init_neovim_mode = __esm({
|
|
|
42325
42371
|
}
|
|
42326
42372
|
});
|
|
42327
42373
|
|
|
42374
|
+
// packages/cli/dist/tui/sponsor-wizard.js
|
|
42375
|
+
var sponsor_wizard_exports = {};
|
|
42376
|
+
__export(sponsor_wizard_exports, {
|
|
42377
|
+
loadSponsorConfig: () => loadSponsorConfig,
|
|
42378
|
+
runSponsorWizard: () => runSponsorWizard,
|
|
42379
|
+
saveSponsorConfig: () => saveSponsorConfig,
|
|
42380
|
+
showSponsorDashboard: () => showSponsorDashboard
|
|
42381
|
+
});
|
|
42382
|
+
import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync16 } from "node:fs";
|
|
42383
|
+
import { join as join56 } from "node:path";
|
|
42384
|
+
function sponsorDir(projectDir) {
|
|
42385
|
+
return join56(projectDir, ".oa", "sponsor");
|
|
42386
|
+
}
|
|
42387
|
+
function configPath(projectDir) {
|
|
42388
|
+
return join56(sponsorDir(projectDir), "config.json");
|
|
42389
|
+
}
|
|
42390
|
+
function loadSponsorConfig(projectDir) {
|
|
42391
|
+
const p = configPath(projectDir);
|
|
42392
|
+
if (!existsSync40(p))
|
|
42393
|
+
return null;
|
|
42394
|
+
try {
|
|
42395
|
+
return JSON.parse(readFileSync29(p, "utf8"));
|
|
42396
|
+
} catch {
|
|
42397
|
+
return null;
|
|
42398
|
+
}
|
|
42399
|
+
}
|
|
42400
|
+
function saveSponsorConfig(projectDir, config) {
|
|
42401
|
+
const dir = sponsorDir(projectDir);
|
|
42402
|
+
mkdirSync16(dir, { recursive: true });
|
|
42403
|
+
config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
42404
|
+
writeFileSync17(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
|
|
42405
|
+
}
|
|
42406
|
+
function defaultConfig() {
|
|
42407
|
+
return {
|
|
42408
|
+
endpoints: [],
|
|
42409
|
+
banner: { preset: "wave" },
|
|
42410
|
+
header: {
|
|
42411
|
+
messageEnabled: false,
|
|
42412
|
+
message: "",
|
|
42413
|
+
linkEnabled: false,
|
|
42414
|
+
linkUrl: "",
|
|
42415
|
+
linkText: ""
|
|
42416
|
+
},
|
|
42417
|
+
transport: { cloudflared: true, libp2p: false },
|
|
42418
|
+
rateLimits: {
|
|
42419
|
+
maxRequestsPerMinute: 60,
|
|
42420
|
+
maxTokensPerDay: 1e5,
|
|
42421
|
+
maxConcurrent: 5,
|
|
42422
|
+
allowedModels: "all"
|
|
42423
|
+
},
|
|
42424
|
+
status: "inactive",
|
|
42425
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
42426
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
42427
|
+
};
|
|
42428
|
+
}
|
|
42429
|
+
async function discoverEndpoints(ollamaUrl) {
|
|
42430
|
+
const endpoints = [];
|
|
42431
|
+
try {
|
|
42432
|
+
const resp = await fetch(`${ollamaUrl}/api/tags`, { signal: AbortSignal.timeout(5e3) });
|
|
42433
|
+
if (resp.ok) {
|
|
42434
|
+
const data = await resp.json();
|
|
42435
|
+
const models = (data.models || []).map((m) => m.name);
|
|
42436
|
+
endpoints.push({
|
|
42437
|
+
kind: "ollama",
|
|
42438
|
+
url: ollamaUrl,
|
|
42439
|
+
models,
|
|
42440
|
+
label: `Local Ollama (${new URL(ollamaUrl).host})`,
|
|
42441
|
+
enabled: true
|
|
42442
|
+
});
|
|
42443
|
+
}
|
|
42444
|
+
} catch {
|
|
42445
|
+
}
|
|
42446
|
+
return endpoints;
|
|
42447
|
+
}
|
|
42448
|
+
async function stepEndpoints(config, ollamaUrl, rl, availableRows) {
|
|
42449
|
+
const discovered = await discoverEndpoints(ollamaUrl);
|
|
42450
|
+
for (const disc of discovered) {
|
|
42451
|
+
const existing = config.endpoints.find((e) => e.url === disc.url);
|
|
42452
|
+
if (!existing) {
|
|
42453
|
+
config.endpoints.push(disc);
|
|
42454
|
+
} else {
|
|
42455
|
+
existing.models = disc.models;
|
|
42456
|
+
}
|
|
42457
|
+
}
|
|
42458
|
+
const items = [
|
|
42459
|
+
{ key: "hdr", label: "Select Endpoints to Sponsor", isToggleable: false }
|
|
42460
|
+
];
|
|
42461
|
+
for (const ep of config.endpoints) {
|
|
42462
|
+
const modelList = ep.models.length > 0 ? ep.models.slice(0, 3).join(", ") + (ep.models.length > 3 ? ` +${ep.models.length - 3} more` : "") : "all models";
|
|
42463
|
+
items.push({
|
|
42464
|
+
key: ep.url,
|
|
42465
|
+
label: `${ep.enabled ? "[x]" : "[ ]"} ${ep.label}`,
|
|
42466
|
+
detail: `Models: ${modelList}`,
|
|
42467
|
+
endpoint: ep,
|
|
42468
|
+
isToggleable: true
|
|
42469
|
+
});
|
|
42470
|
+
}
|
|
42471
|
+
items.push({
|
|
42472
|
+
key: "add_custom",
|
|
42473
|
+
label: " + Add custom endpoint URL...",
|
|
42474
|
+
isToggleable: false
|
|
42475
|
+
});
|
|
42476
|
+
items.push({ key: "sep", label: "", isToggleable: false });
|
|
42477
|
+
items.push({
|
|
42478
|
+
key: "next",
|
|
42479
|
+
label: selectColors.green(" Next Step \u2192"),
|
|
42480
|
+
isToggleable: false
|
|
42481
|
+
});
|
|
42482
|
+
const result = await tuiSelect({
|
|
42483
|
+
items,
|
|
42484
|
+
title: "Step 1/5 \u2014 Endpoint Selection",
|
|
42485
|
+
rl,
|
|
42486
|
+
skipKeys: ["hdr", "sep"],
|
|
42487
|
+
availableRows,
|
|
42488
|
+
onAction: (item, action) => {
|
|
42489
|
+
if (action === "space" && item.isToggleable && item.endpoint) {
|
|
42490
|
+
item.endpoint.enabled = !item.endpoint.enabled;
|
|
42491
|
+
item.label = `${item.endpoint.enabled ? "[x]" : "[ ]"} ${item.endpoint.label}`;
|
|
42492
|
+
return true;
|
|
42493
|
+
}
|
|
42494
|
+
return false;
|
|
42495
|
+
},
|
|
42496
|
+
renderRow: (item, focused, _isActive) => {
|
|
42497
|
+
const prefix = focused ? selectColors.orange("\u276F ") : " ";
|
|
42498
|
+
if (item.key === "hdr") {
|
|
42499
|
+
return selectColors.bold(item.label);
|
|
42500
|
+
}
|
|
42501
|
+
if (item.detail) {
|
|
42502
|
+
return `${prefix}${item.label}
|
|
42503
|
+
${selectColors.dim(item.detail)}`;
|
|
42504
|
+
}
|
|
42505
|
+
return `${prefix}${item.label}`;
|
|
42506
|
+
}
|
|
42507
|
+
});
|
|
42508
|
+
if (!result.confirmed)
|
|
42509
|
+
return false;
|
|
42510
|
+
if (result.key === "next") {
|
|
42511
|
+
const anyEnabled = config.endpoints.some((e) => e.enabled);
|
|
42512
|
+
if (!anyEnabled) {
|
|
42513
|
+
renderWarning("Select at least one endpoint before continuing.");
|
|
42514
|
+
return stepEndpoints(config, ollamaUrl, rl, availableRows);
|
|
42515
|
+
}
|
|
42516
|
+
return true;
|
|
42517
|
+
}
|
|
42518
|
+
if (result.key && result.key !== "add_custom") {
|
|
42519
|
+
const ep = config.endpoints.find((e) => e.url === result.key);
|
|
42520
|
+
if (ep) {
|
|
42521
|
+
ep.enabled = !ep.enabled;
|
|
42522
|
+
return stepEndpoints(config, ollamaUrl, rl, availableRows);
|
|
42523
|
+
}
|
|
42524
|
+
}
|
|
42525
|
+
if (result.key === "add_custom") {
|
|
42526
|
+
renderInfo("Custom endpoint support coming soon. Use /endpoint to configure external APIs.");
|
|
42527
|
+
return stepEndpoints(config, ollamaUrl, rl, availableRows);
|
|
42528
|
+
}
|
|
42529
|
+
return false;
|
|
42530
|
+
}
|
|
42531
|
+
async function stepBanner(config, rl, availableRows) {
|
|
42532
|
+
const items = [
|
|
42533
|
+
{ key: "hdr", label: "Select Banner Animation" }
|
|
42534
|
+
];
|
|
42535
|
+
for (const preset of ANIM_PRESETS) {
|
|
42536
|
+
items.push({
|
|
42537
|
+
key: preset.id,
|
|
42538
|
+
label: `${config.banner.preset === preset.id ? "(\u25CF)" : "( )"} ${preset.name}`,
|
|
42539
|
+
detail: preset.desc
|
|
42540
|
+
});
|
|
42541
|
+
}
|
|
42542
|
+
items.push({ key: "sep", label: "" });
|
|
42543
|
+
items.push({ key: "next", label: selectColors.green(" Next Step \u2192") });
|
|
42544
|
+
const result = await tuiSelect({
|
|
42545
|
+
items,
|
|
42546
|
+
title: "Step 2/5 \u2014 Banner Animation",
|
|
42547
|
+
rl,
|
|
42548
|
+
skipKeys: ["hdr", "sep"],
|
|
42549
|
+
availableRows,
|
|
42550
|
+
onAction: (item, action) => {
|
|
42551
|
+
if (action === "space" && ANIM_PRESETS.some((p) => p.id === item.key)) {
|
|
42552
|
+
config.banner.preset = item.key;
|
|
42553
|
+
for (const it of items) {
|
|
42554
|
+
const p = ANIM_PRESETS.find((pr) => pr.id === it.key);
|
|
42555
|
+
if (p) {
|
|
42556
|
+
it.label = `${config.banner.preset === p.id ? "(\u25CF)" : "( )"} ${p.name}`;
|
|
42557
|
+
}
|
|
42558
|
+
}
|
|
42559
|
+
return true;
|
|
42560
|
+
}
|
|
42561
|
+
return false;
|
|
42562
|
+
}
|
|
42563
|
+
});
|
|
42564
|
+
if (!result.confirmed)
|
|
42565
|
+
return false;
|
|
42566
|
+
if (result.key === "next")
|
|
42567
|
+
return true;
|
|
42568
|
+
if (ANIM_PRESETS.some((p) => p.id === result.key)) {
|
|
42569
|
+
config.banner.preset = result.key;
|
|
42570
|
+
return true;
|
|
42571
|
+
}
|
|
42572
|
+
return false;
|
|
42573
|
+
}
|
|
42574
|
+
async function stepHeader(config, rl, availableRows) {
|
|
42575
|
+
const items = [
|
|
42576
|
+
{ key: "hdr", label: "Header Content" },
|
|
42577
|
+
{
|
|
42578
|
+
key: "message_toggle",
|
|
42579
|
+
label: `${config.header.messageEnabled ? "[x]" : "[ ]"} Header Message`,
|
|
42580
|
+
detail: config.header.message || "(none set)"
|
|
42581
|
+
},
|
|
42582
|
+
{
|
|
42583
|
+
key: "link_toggle",
|
|
42584
|
+
label: `${config.header.linkEnabled ? "[x]" : "[ ]"} Link`,
|
|
42585
|
+
detail: config.header.linkUrl ? `${config.header.linkUrl} [${config.header.linkText || "link"}]` : "(none set)"
|
|
42586
|
+
},
|
|
42587
|
+
{ key: "sep", label: "" },
|
|
42588
|
+
{ key: "next", label: selectColors.green(" Next Step \u2192") }
|
|
42589
|
+
];
|
|
42590
|
+
const result = await tuiSelect({
|
|
42591
|
+
items,
|
|
42592
|
+
title: "Step 3/5 \u2014 Header Text & Links",
|
|
42593
|
+
rl,
|
|
42594
|
+
skipKeys: ["hdr", "sep"],
|
|
42595
|
+
availableRows,
|
|
42596
|
+
onAction: (item, action) => {
|
|
42597
|
+
if (action === "space") {
|
|
42598
|
+
if (item.key === "message_toggle") {
|
|
42599
|
+
config.header.messageEnabled = !config.header.messageEnabled;
|
|
42600
|
+
item.label = `${config.header.messageEnabled ? "[x]" : "[ ]"} Header Message`;
|
|
42601
|
+
return true;
|
|
42602
|
+
}
|
|
42603
|
+
if (item.key === "link_toggle") {
|
|
42604
|
+
config.header.linkEnabled = !config.header.linkEnabled;
|
|
42605
|
+
item.label = `${config.header.linkEnabled ? "[x]" : "[ ]"} Link`;
|
|
42606
|
+
return true;
|
|
42607
|
+
}
|
|
42608
|
+
}
|
|
42609
|
+
return false;
|
|
42610
|
+
}
|
|
42611
|
+
});
|
|
42612
|
+
if (!result.confirmed)
|
|
42613
|
+
return false;
|
|
42614
|
+
if (result.key === "next")
|
|
42615
|
+
return true;
|
|
42616
|
+
if (result.key === "message_toggle") {
|
|
42617
|
+
config.header.messageEnabled = true;
|
|
42618
|
+
const msg = await promptLine(rl, "Header message: ");
|
|
42619
|
+
if (msg)
|
|
42620
|
+
config.header.message = msg.slice(0, 80);
|
|
42621
|
+
return stepHeader(config, rl, availableRows);
|
|
42622
|
+
}
|
|
42623
|
+
if (result.key === "link_toggle") {
|
|
42624
|
+
config.header.linkEnabled = true;
|
|
42625
|
+
const url = await promptLine(rl, "Link URL: ");
|
|
42626
|
+
if (url) {
|
|
42627
|
+
config.header.linkUrl = url;
|
|
42628
|
+
const text = await promptLine(rl, "Link text: ");
|
|
42629
|
+
if (text)
|
|
42630
|
+
config.header.linkText = text;
|
|
42631
|
+
}
|
|
42632
|
+
return stepHeader(config, rl, availableRows);
|
|
42633
|
+
}
|
|
42634
|
+
return false;
|
|
42635
|
+
}
|
|
42636
|
+
async function stepTransport(config, rl, availableRows) {
|
|
42637
|
+
const items = [
|
|
42638
|
+
{ key: "hdr_transport", label: "Network Transport" },
|
|
42639
|
+
{
|
|
42640
|
+
key: "cf_toggle",
|
|
42641
|
+
label: `${config.transport.cloudflared ? "[x]" : "[ ]"} Cloudflared Tunnel (HTTPS)`,
|
|
42642
|
+
detail: "Public URL via trycloudflare.com"
|
|
42643
|
+
},
|
|
42644
|
+
{
|
|
42645
|
+
key: "p2p_toggle",
|
|
42646
|
+
label: `${config.transport.libp2p ? "[x]" : "[ ]"} libp2p P2P Mesh`,
|
|
42647
|
+
detail: "Decentralized, no central relay"
|
|
42648
|
+
},
|
|
42649
|
+
{ key: "hdr_limits", label: "Rate Limits" },
|
|
42650
|
+
{
|
|
42651
|
+
key: "rpm",
|
|
42652
|
+
label: ` Max requests/min: ${config.rateLimits.maxRequestsPerMinute}`
|
|
42653
|
+
},
|
|
42654
|
+
{
|
|
42655
|
+
key: "tpd",
|
|
42656
|
+
label: ` Max tokens/day: ${config.rateLimits.maxTokensPerDay.toLocaleString()}`
|
|
42657
|
+
},
|
|
42658
|
+
{
|
|
42659
|
+
key: "conc",
|
|
42660
|
+
label: ` Max concurrent: ${config.rateLimits.maxConcurrent}`
|
|
42661
|
+
},
|
|
42662
|
+
{ key: "sep", label: "" },
|
|
42663
|
+
{ key: "next", label: selectColors.green(" Next Step \u2192") }
|
|
42664
|
+
];
|
|
42665
|
+
const result = await tuiSelect({
|
|
42666
|
+
items,
|
|
42667
|
+
title: "Step 4/5 \u2014 Transport & Rate Limits",
|
|
42668
|
+
rl,
|
|
42669
|
+
skipKeys: ["hdr_transport", "hdr_limits", "sep"],
|
|
42670
|
+
availableRows,
|
|
42671
|
+
onAction: (item, action) => {
|
|
42672
|
+
if (action === "space") {
|
|
42673
|
+
if (item.key === "cf_toggle") {
|
|
42674
|
+
config.transport.cloudflared = !config.transport.cloudflared;
|
|
42675
|
+
item.label = `${config.transport.cloudflared ? "[x]" : "[ ]"} Cloudflared Tunnel (HTTPS)`;
|
|
42676
|
+
return true;
|
|
42677
|
+
}
|
|
42678
|
+
if (item.key === "p2p_toggle") {
|
|
42679
|
+
config.transport.libp2p = !config.transport.libp2p;
|
|
42680
|
+
item.label = `${config.transport.libp2p ? "[x]" : "[ ]"} libp2p P2P Mesh`;
|
|
42681
|
+
return true;
|
|
42682
|
+
}
|
|
42683
|
+
}
|
|
42684
|
+
return false;
|
|
42685
|
+
}
|
|
42686
|
+
});
|
|
42687
|
+
if (!result.confirmed)
|
|
42688
|
+
return false;
|
|
42689
|
+
if (result.key === "next") {
|
|
42690
|
+
if (!config.transport.cloudflared && !config.transport.libp2p) {
|
|
42691
|
+
renderWarning("At least one transport must be enabled.");
|
|
42692
|
+
return stepTransport(config, rl, availableRows);
|
|
42693
|
+
}
|
|
42694
|
+
return true;
|
|
42695
|
+
}
|
|
42696
|
+
if (result.key === "rpm") {
|
|
42697
|
+
const val = await promptLine(rl, "Max requests per minute: ");
|
|
42698
|
+
const n = parseInt(val, 10);
|
|
42699
|
+
if (!isNaN(n) && n > 0)
|
|
42700
|
+
config.rateLimits.maxRequestsPerMinute = n;
|
|
42701
|
+
return stepTransport(config, rl, availableRows);
|
|
42702
|
+
}
|
|
42703
|
+
if (result.key === "tpd") {
|
|
42704
|
+
const val = await promptLine(rl, "Max tokens per day: ");
|
|
42705
|
+
const n = parseInt(val, 10);
|
|
42706
|
+
if (!isNaN(n) && n > 0)
|
|
42707
|
+
config.rateLimits.maxTokensPerDay = n;
|
|
42708
|
+
return stepTransport(config, rl, availableRows);
|
|
42709
|
+
}
|
|
42710
|
+
if (result.key === "conc") {
|
|
42711
|
+
const val = await promptLine(rl, "Max concurrent requests: ");
|
|
42712
|
+
const n = parseInt(val, 10);
|
|
42713
|
+
if (!isNaN(n) && n > 0)
|
|
42714
|
+
config.rateLimits.maxConcurrent = n;
|
|
42715
|
+
return stepTransport(config, rl, availableRows);
|
|
42716
|
+
}
|
|
42717
|
+
return false;
|
|
42718
|
+
}
|
|
42719
|
+
async function stepReview(config, rl, availableRows) {
|
|
42720
|
+
const enabledEps = config.endpoints.filter((e) => e.enabled);
|
|
42721
|
+
const epList = enabledEps.map((e) => e.label).join(", ") || "none";
|
|
42722
|
+
const transports = [];
|
|
42723
|
+
if (config.transport.cloudflared)
|
|
42724
|
+
transports.push("Cloudflared Tunnel");
|
|
42725
|
+
if (config.transport.libp2p)
|
|
42726
|
+
transports.push("libp2p P2P");
|
|
42727
|
+
const items = [
|
|
42728
|
+
{ key: "hdr", label: "Review Sponsorship Configuration" },
|
|
42729
|
+
{ key: "info_ep", label: ` Endpoints: ${epList}` },
|
|
42730
|
+
{ key: "info_anim", label: ` Banner: ${config.banner.preset}` },
|
|
42731
|
+
{ key: "info_msg", label: ` Message: ${config.header.messageEnabled ? config.header.message || "(empty)" : "(disabled)"}` },
|
|
42732
|
+
{ key: "info_link", label: ` Link: ${config.header.linkEnabled ? `${config.header.linkUrl} [${config.header.linkText}]` : "(disabled)"}` },
|
|
42733
|
+
{ key: "info_transport", label: ` Transport: ${transports.join(" + ")}` },
|
|
42734
|
+
{ key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day` },
|
|
42735
|
+
{ key: "sep", label: "" },
|
|
42736
|
+
{ key: "go_live", label: selectColors.green(" \u2726 Go Live & Sponsor Inference ") },
|
|
42737
|
+
{ key: "cancel", label: selectColors.dim(" Cancel") }
|
|
42738
|
+
];
|
|
42739
|
+
const result = await tuiSelect({
|
|
42740
|
+
items,
|
|
42741
|
+
title: "Step 5/5 \u2014 Review & Go Live",
|
|
42742
|
+
rl,
|
|
42743
|
+
skipKeys: ["hdr", "sep", "info_ep", "info_anim", "info_msg", "info_link", "info_transport", "info_limits"],
|
|
42744
|
+
availableRows
|
|
42745
|
+
});
|
|
42746
|
+
if (!result.confirmed || result.key === "cancel")
|
|
42747
|
+
return false;
|
|
42748
|
+
return result.key === "go_live";
|
|
42749
|
+
}
|
|
42750
|
+
async function showSponsorDashboard(config, projectDir, rl, availableRows) {
|
|
42751
|
+
const isPaused = config.status === "paused";
|
|
42752
|
+
const enabledEps = config.endpoints.filter((e) => e.enabled);
|
|
42753
|
+
const items = [
|
|
42754
|
+
{ key: "hdr", label: "Sponsor Dashboard" },
|
|
42755
|
+
{ key: "info_status", label: ` Status: ${isPaused ? "\u25CF PAUSED" : "\u25CF ACTIVE"}` },
|
|
42756
|
+
{ key: "info_ep", label: ` Endpoints: ${enabledEps.map((e) => e.label).join(", ")}` },
|
|
42757
|
+
{ key: "info_transport", label: ` Transport: ${[config.transport.cloudflared ? "Cloudflared" : "", config.transport.libp2p ? "libp2p" : ""].filter(Boolean).join(" + ")}` },
|
|
42758
|
+
{ key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day` },
|
|
42759
|
+
{ key: "sep", label: "" },
|
|
42760
|
+
{ key: "modify", label: " [Modify Settings]" },
|
|
42761
|
+
{ key: isPaused ? "resume" : "pause", label: isPaused ? " [Resume Sponsorship]" : " [Pause Sponsorship]" },
|
|
42762
|
+
{ key: "remove", label: selectColors.dim(" [Remove Sponsorship]") }
|
|
42763
|
+
];
|
|
42764
|
+
const result = await tuiSelect({
|
|
42765
|
+
items,
|
|
42766
|
+
title: "Sponsor Dashboard",
|
|
42767
|
+
rl,
|
|
42768
|
+
skipKeys: ["hdr", "sep", "info_status", "info_ep", "info_transport", "info_limits"],
|
|
42769
|
+
availableRows
|
|
42770
|
+
});
|
|
42771
|
+
if (!result.confirmed)
|
|
42772
|
+
return "close";
|
|
42773
|
+
return result.key || "close";
|
|
42774
|
+
}
|
|
42775
|
+
async function runSponsorWizard(ctx) {
|
|
42776
|
+
let config = loadSponsorConfig(ctx.projectDir) || defaultConfig();
|
|
42777
|
+
renderInfo("Starting sponsor onboarding wizard...\n");
|
|
42778
|
+
if (!await stepEndpoints(config, ctx.ollamaUrl, ctx.rl, ctx.availableRows)) {
|
|
42779
|
+
renderInfo("Sponsor wizard cancelled.");
|
|
42780
|
+
return null;
|
|
42781
|
+
}
|
|
42782
|
+
saveSponsorConfig(ctx.projectDir, config);
|
|
42783
|
+
if (!await stepBanner(config, ctx.rl, ctx.availableRows)) {
|
|
42784
|
+
renderInfo("Sponsor wizard cancelled.");
|
|
42785
|
+
return null;
|
|
42786
|
+
}
|
|
42787
|
+
saveSponsorConfig(ctx.projectDir, config);
|
|
42788
|
+
if (!await stepHeader(config, ctx.rl, ctx.availableRows)) {
|
|
42789
|
+
renderInfo("Sponsor wizard cancelled.");
|
|
42790
|
+
return null;
|
|
42791
|
+
}
|
|
42792
|
+
saveSponsorConfig(ctx.projectDir, config);
|
|
42793
|
+
if (!await stepTransport(config, ctx.rl, ctx.availableRows)) {
|
|
42794
|
+
renderInfo("Sponsor wizard cancelled.");
|
|
42795
|
+
return null;
|
|
42796
|
+
}
|
|
42797
|
+
saveSponsorConfig(ctx.projectDir, config);
|
|
42798
|
+
if (!await stepReview(config, ctx.rl, ctx.availableRows)) {
|
|
42799
|
+
renderInfo("Sponsor wizard cancelled.");
|
|
42800
|
+
return null;
|
|
42801
|
+
}
|
|
42802
|
+
config.status = "active";
|
|
42803
|
+
saveSponsorConfig(ctx.projectDir, config);
|
|
42804
|
+
if (ctx.onGoLive) {
|
|
42805
|
+
await ctx.onGoLive(config);
|
|
42806
|
+
}
|
|
42807
|
+
renderInfo("\u2726 Sponsorship active!");
|
|
42808
|
+
renderInfo("Toggle: /sponsor status | Pause: /sponsor pause | Remove: /sponsor remove");
|
|
42809
|
+
return config;
|
|
42810
|
+
}
|
|
42811
|
+
function promptLine(rl, prompt) {
|
|
42812
|
+
return new Promise((resolve35) => {
|
|
42813
|
+
process.stdout.write(prompt);
|
|
42814
|
+
const handler = (line) => {
|
|
42815
|
+
rl.removeListener("line", handler);
|
|
42816
|
+
resolve35(line.trim());
|
|
42817
|
+
};
|
|
42818
|
+
rl.on("line", handler);
|
|
42819
|
+
});
|
|
42820
|
+
}
|
|
42821
|
+
var ANIM_PRESETS;
|
|
42822
|
+
var init_sponsor_wizard = __esm({
|
|
42823
|
+
"packages/cli/dist/tui/sponsor-wizard.js"() {
|
|
42824
|
+
"use strict";
|
|
42825
|
+
init_tui_select();
|
|
42826
|
+
init_render();
|
|
42827
|
+
ANIM_PRESETS = [
|
|
42828
|
+
{ id: "wave", name: "Wave", desc: "Flowing wave pattern" },
|
|
42829
|
+
{ id: "pulse", name: "Pulse", desc: "Pulsing dots" },
|
|
42830
|
+
{ id: "matrix", name: "Matrix", desc: "Falling characters" },
|
|
42831
|
+
{ id: "sparkle", name: "Sparkle", desc: "Random sparkle effect" },
|
|
42832
|
+
{ id: "radar", name: "Radar", desc: "Rotating radar sweep" },
|
|
42833
|
+
{ id: "circuit", name: "Circuit", desc: "Circuit board traces" },
|
|
42834
|
+
{ id: "none", name: "No Animation", desc: "Static banner only" }
|
|
42835
|
+
];
|
|
42836
|
+
}
|
|
42837
|
+
});
|
|
42838
|
+
|
|
42328
42839
|
// packages/cli/dist/tui/voice.js
|
|
42329
42840
|
var voice_exports = {};
|
|
42330
42841
|
__export(voice_exports, {
|
|
@@ -42337,8 +42848,8 @@ __export(voice_exports, {
|
|
|
42337
42848
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
42338
42849
|
resetNarrationContext: () => resetNarrationContext
|
|
42339
42850
|
});
|
|
42340
|
-
import { existsSync as
|
|
42341
|
-
import { join as
|
|
42851
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync17, writeFileSync as writeFileSync18, readFileSync as readFileSync30, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
|
|
42852
|
+
import { join as join57, dirname as dirname18 } from "node:path";
|
|
42342
42853
|
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
42343
42854
|
import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
|
|
42344
42855
|
import { createRequire } from "node:module";
|
|
@@ -42363,40 +42874,40 @@ function listVoiceModels() {
|
|
|
42363
42874
|
}));
|
|
42364
42875
|
}
|
|
42365
42876
|
function voiceDir() {
|
|
42366
|
-
return
|
|
42877
|
+
return join57(homedir13(), ".open-agents", "voice");
|
|
42367
42878
|
}
|
|
42368
42879
|
function modelsDir() {
|
|
42369
|
-
return
|
|
42880
|
+
return join57(voiceDir(), "models");
|
|
42370
42881
|
}
|
|
42371
42882
|
function modelDir(id) {
|
|
42372
|
-
return
|
|
42883
|
+
return join57(modelsDir(), id);
|
|
42373
42884
|
}
|
|
42374
42885
|
function modelOnnxPath(id) {
|
|
42375
|
-
return
|
|
42886
|
+
return join57(modelDir(id), "model.onnx");
|
|
42376
42887
|
}
|
|
42377
42888
|
function modelConfigPath(id) {
|
|
42378
|
-
return
|
|
42889
|
+
return join57(modelDir(id), "config.json");
|
|
42379
42890
|
}
|
|
42380
42891
|
function luxttsVenvDir() {
|
|
42381
|
-
return
|
|
42892
|
+
return join57(voiceDir(), "luxtts-venv");
|
|
42382
42893
|
}
|
|
42383
42894
|
function luxttsVenvPy() {
|
|
42384
|
-
return platform3() === "win32" ?
|
|
42895
|
+
return platform3() === "win32" ? join57(luxttsVenvDir(), "Scripts", "python.exe") : join57(luxttsVenvDir(), "bin", "python3");
|
|
42385
42896
|
}
|
|
42386
42897
|
function luxttsRepoDir() {
|
|
42387
|
-
return
|
|
42898
|
+
return join57(voiceDir(), "LuxTTS");
|
|
42388
42899
|
}
|
|
42389
42900
|
function luxttsCloneRefsDir() {
|
|
42390
|
-
return
|
|
42901
|
+
return join57(voiceDir(), "clone-refs");
|
|
42391
42902
|
}
|
|
42392
42903
|
function luxttsInferScript() {
|
|
42393
|
-
return
|
|
42904
|
+
return join57(voiceDir(), "luxtts-infer.py");
|
|
42394
42905
|
}
|
|
42395
42906
|
function writeDetectTorchScript(targetPath) {
|
|
42396
|
-
if (
|
|
42907
|
+
if (existsSync41(targetPath))
|
|
42397
42908
|
return;
|
|
42398
42909
|
try {
|
|
42399
|
-
|
|
42910
|
+
mkdirSync17(dirname18(targetPath), { recursive: true });
|
|
42400
42911
|
} catch {
|
|
42401
42912
|
}
|
|
42402
42913
|
const script = `#!/usr/bin/env python3
|
|
@@ -42469,7 +42980,7 @@ def main():
|
|
|
42469
42980
|
if __name__ == "__main__": main()
|
|
42470
42981
|
`;
|
|
42471
42982
|
try {
|
|
42472
|
-
|
|
42983
|
+
writeFileSync18(targetPath, script, { mode: 493 });
|
|
42473
42984
|
} catch {
|
|
42474
42985
|
}
|
|
42475
42986
|
}
|
|
@@ -43279,8 +43790,8 @@ var init_voice = __esm({
|
|
|
43279
43790
|
const refsDir = luxttsCloneRefsDir();
|
|
43280
43791
|
const targets = ["glados", "overwatch"];
|
|
43281
43792
|
for (const modelId of targets) {
|
|
43282
|
-
const refFile =
|
|
43283
|
-
if (
|
|
43793
|
+
const refFile = join57(refsDir, `${modelId}-ref.wav`);
|
|
43794
|
+
if (existsSync41(refFile))
|
|
43284
43795
|
continue;
|
|
43285
43796
|
try {
|
|
43286
43797
|
await this.generateCloneRef(modelId);
|
|
@@ -43359,24 +43870,24 @@ var init_voice = __esm({
|
|
|
43359
43870
|
}
|
|
43360
43871
|
p = p.replace(/\\ /g, " ");
|
|
43361
43872
|
if (p.startsWith("~/") || p === "~") {
|
|
43362
|
-
p =
|
|
43873
|
+
p = join57(homedir13(), p.slice(1));
|
|
43363
43874
|
}
|
|
43364
|
-
if (!
|
|
43875
|
+
if (!existsSync41(p)) {
|
|
43365
43876
|
return `File not found: ${p}
|
|
43366
43877
|
(original input: ${audioPath})`;
|
|
43367
43878
|
}
|
|
43368
43879
|
audioPath = p;
|
|
43369
43880
|
const refsDir = luxttsCloneRefsDir();
|
|
43370
|
-
if (!
|
|
43371
|
-
|
|
43881
|
+
if (!existsSync41(refsDir))
|
|
43882
|
+
mkdirSync17(refsDir, { recursive: true });
|
|
43372
43883
|
const ext = audioPath.split(".").pop() || "wav";
|
|
43373
43884
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
43374
43885
|
const ts = Date.now().toString(36);
|
|
43375
43886
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
43376
|
-
const destPath =
|
|
43887
|
+
const destPath = join57(refsDir, destFilename);
|
|
43377
43888
|
try {
|
|
43378
|
-
const data =
|
|
43379
|
-
|
|
43889
|
+
const data = readFileSync30(audioPath);
|
|
43890
|
+
writeFileSync18(destPath, data);
|
|
43380
43891
|
} catch (err) {
|
|
43381
43892
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
43382
43893
|
}
|
|
@@ -43416,9 +43927,9 @@ var init_voice = __esm({
|
|
|
43416
43927
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
43417
43928
|
}
|
|
43418
43929
|
const refsDir = luxttsCloneRefsDir();
|
|
43419
|
-
if (!
|
|
43420
|
-
|
|
43421
|
-
const destPath =
|
|
43930
|
+
if (!existsSync41(refsDir))
|
|
43931
|
+
mkdirSync17(refsDir, { recursive: true });
|
|
43932
|
+
const destPath = join57(refsDir, `${sourceModelId}-ref.wav`);
|
|
43422
43933
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
43423
43934
|
this.writeWav(audioData, sampleRate, destPath);
|
|
43424
43935
|
this.luxttsCloneRef = destPath;
|
|
@@ -43434,23 +43945,23 @@ var init_voice = __esm({
|
|
|
43434
43945
|
// -------------------------------------------------------------------------
|
|
43435
43946
|
/** Metadata file for friendly names of clone refs */
|
|
43436
43947
|
static cloneMetaFile() {
|
|
43437
|
-
return
|
|
43948
|
+
return join57(luxttsCloneRefsDir(), "meta.json");
|
|
43438
43949
|
}
|
|
43439
43950
|
loadCloneMeta() {
|
|
43440
43951
|
const p = _VoiceEngine.cloneMetaFile();
|
|
43441
|
-
if (!
|
|
43952
|
+
if (!existsSync41(p))
|
|
43442
43953
|
return {};
|
|
43443
43954
|
try {
|
|
43444
|
-
return JSON.parse(
|
|
43955
|
+
return JSON.parse(readFileSync30(p, "utf8"));
|
|
43445
43956
|
} catch {
|
|
43446
43957
|
return {};
|
|
43447
43958
|
}
|
|
43448
43959
|
}
|
|
43449
43960
|
saveCloneMeta(meta) {
|
|
43450
43961
|
const dir = luxttsCloneRefsDir();
|
|
43451
|
-
if (!
|
|
43452
|
-
|
|
43453
|
-
|
|
43962
|
+
if (!existsSync41(dir))
|
|
43963
|
+
mkdirSync17(dir, { recursive: true });
|
|
43964
|
+
writeFileSync18(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
43454
43965
|
}
|
|
43455
43966
|
/** Audio file extensions recognized as clone references */
|
|
43456
43967
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -43460,7 +43971,7 @@ var init_voice = __esm({
|
|
|
43460
43971
|
*/
|
|
43461
43972
|
listCloneRefs() {
|
|
43462
43973
|
const dir = luxttsCloneRefsDir();
|
|
43463
|
-
if (!
|
|
43974
|
+
if (!existsSync41(dir))
|
|
43464
43975
|
return [];
|
|
43465
43976
|
const meta = this.loadCloneMeta();
|
|
43466
43977
|
const files = readdirSync11(dir).filter((f) => {
|
|
@@ -43468,7 +43979,7 @@ var init_voice = __esm({
|
|
|
43468
43979
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
43469
43980
|
});
|
|
43470
43981
|
return files.map((f) => {
|
|
43471
|
-
const p =
|
|
43982
|
+
const p = join57(dir, f);
|
|
43472
43983
|
let size = 0;
|
|
43473
43984
|
try {
|
|
43474
43985
|
size = statSync13(p).size;
|
|
@@ -43485,8 +43996,8 @@ var init_voice = __esm({
|
|
|
43485
43996
|
}
|
|
43486
43997
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
43487
43998
|
deleteCloneRef(filename) {
|
|
43488
|
-
const p =
|
|
43489
|
-
if (!
|
|
43999
|
+
const p = join57(luxttsCloneRefsDir(), filename);
|
|
44000
|
+
if (!existsSync41(p))
|
|
43490
44001
|
return false;
|
|
43491
44002
|
try {
|
|
43492
44003
|
unlinkSync9(p);
|
|
@@ -43510,8 +44021,8 @@ var init_voice = __esm({
|
|
|
43510
44021
|
}
|
|
43511
44022
|
/** Set the active clone reference by filename. */
|
|
43512
44023
|
setActiveCloneRef(filename) {
|
|
43513
|
-
const p =
|
|
43514
|
-
if (!
|
|
44024
|
+
const p = join57(luxttsCloneRefsDir(), filename);
|
|
44025
|
+
if (!existsSync41(p))
|
|
43515
44026
|
return `File not found: ${filename}`;
|
|
43516
44027
|
this.luxttsCloneRef = p;
|
|
43517
44028
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -43836,7 +44347,7 @@ var init_voice = __esm({
|
|
|
43836
44347
|
}
|
|
43837
44348
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
43838
44349
|
}
|
|
43839
|
-
const wavPath =
|
|
44350
|
+
const wavPath = join57(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
43840
44351
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
43841
44352
|
await this.playWav(wavPath);
|
|
43842
44353
|
try {
|
|
@@ -43953,7 +44464,7 @@ var init_voice = __esm({
|
|
|
43953
44464
|
buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
|
|
43954
44465
|
pos += 2;
|
|
43955
44466
|
}
|
|
43956
|
-
|
|
44467
|
+
writeFileSync18(path, buffer);
|
|
43957
44468
|
}
|
|
43958
44469
|
// -------------------------------------------------------------------------
|
|
43959
44470
|
// Phonemization
|
|
@@ -44031,7 +44542,7 @@ var init_voice = __esm({
|
|
|
44031
44542
|
return buffer;
|
|
44032
44543
|
}
|
|
44033
44544
|
writeWav(samples, sampleRate, path) {
|
|
44034
|
-
|
|
44545
|
+
writeFileSync18(path, this.buildWavBuffer(samples, sampleRate));
|
|
44035
44546
|
}
|
|
44036
44547
|
// -------------------------------------------------------------------------
|
|
44037
44548
|
// Audio playback (system default speakers)
|
|
@@ -44229,7 +44740,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44229
44740
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
44230
44741
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
44231
44742
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
44232
|
-
const wavPath =
|
|
44743
|
+
const wavPath = join57(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
44233
44744
|
const pyScript = [
|
|
44234
44745
|
"import sys, json",
|
|
44235
44746
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -44246,11 +44757,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44246
44757
|
return;
|
|
44247
44758
|
}
|
|
44248
44759
|
}
|
|
44249
|
-
if (!
|
|
44760
|
+
if (!existsSync41(wavPath))
|
|
44250
44761
|
return;
|
|
44251
44762
|
if (volume !== 1) {
|
|
44252
44763
|
try {
|
|
44253
|
-
const wavData =
|
|
44764
|
+
const wavData = readFileSync30(wavPath);
|
|
44254
44765
|
if (wavData.length > 44) {
|
|
44255
44766
|
const header = wavData.subarray(0, 44);
|
|
44256
44767
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -44258,14 +44769,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44258
44769
|
samples[i] = Math.round(samples[i] * volume);
|
|
44259
44770
|
}
|
|
44260
44771
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
44261
|
-
|
|
44772
|
+
writeFileSync18(wavPath, scaled);
|
|
44262
44773
|
}
|
|
44263
44774
|
} catch {
|
|
44264
44775
|
}
|
|
44265
44776
|
}
|
|
44266
44777
|
if (this.onPCMOutput) {
|
|
44267
44778
|
try {
|
|
44268
|
-
const wavData =
|
|
44779
|
+
const wavData = readFileSync30(wavPath);
|
|
44269
44780
|
if (wavData.length > 44) {
|
|
44270
44781
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
44271
44782
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -44297,7 +44808,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44297
44808
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
44298
44809
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
44299
44810
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
44300
|
-
const wavPath =
|
|
44811
|
+
const wavPath = join57(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
44301
44812
|
const pyScript = [
|
|
44302
44813
|
"import sys, json",
|
|
44303
44814
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -44314,10 +44825,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44314
44825
|
return null;
|
|
44315
44826
|
}
|
|
44316
44827
|
}
|
|
44317
|
-
if (!
|
|
44828
|
+
if (!existsSync41(wavPath))
|
|
44318
44829
|
return null;
|
|
44319
44830
|
try {
|
|
44320
|
-
const data =
|
|
44831
|
+
const data = readFileSync30(wavPath);
|
|
44321
44832
|
unlinkSync9(wavPath);
|
|
44322
44833
|
return data;
|
|
44323
44834
|
} catch {
|
|
@@ -44340,7 +44851,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44340
44851
|
}
|
|
44341
44852
|
const venvDir = luxttsVenvDir();
|
|
44342
44853
|
const venvPy = luxttsVenvPy();
|
|
44343
|
-
if (
|
|
44854
|
+
if (existsSync41(venvPy)) {
|
|
44344
44855
|
try {
|
|
44345
44856
|
await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
|
|
44346
44857
|
let hasCudaSys = false;
|
|
@@ -44354,7 +44865,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44354
44865
|
if (torchCheck === "cpu") {
|
|
44355
44866
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
44356
44867
|
try {
|
|
44357
|
-
const detectScript =
|
|
44868
|
+
const detectScript = join57(voiceDir(), "detect-torch.py");
|
|
44358
44869
|
writeDetectTorchScript(detectScript);
|
|
44359
44870
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
44360
44871
|
try {
|
|
@@ -44379,7 +44890,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44379
44890
|
}
|
|
44380
44891
|
}
|
|
44381
44892
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
44382
|
-
if (!
|
|
44893
|
+
if (!existsSync41(venvDir)) {
|
|
44383
44894
|
renderInfo(" Creating Python virtual environment...");
|
|
44384
44895
|
try {
|
|
44385
44896
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -44388,7 +44899,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44388
44899
|
}
|
|
44389
44900
|
}
|
|
44390
44901
|
{
|
|
44391
|
-
const detectScript =
|
|
44902
|
+
const detectScript = join57(voiceDir(), "detect-torch.py");
|
|
44392
44903
|
writeDetectTorchScript(detectScript);
|
|
44393
44904
|
let pipArgsStr = "torch torchaudio";
|
|
44394
44905
|
let torchDesc = "unknown platform";
|
|
@@ -44425,10 +44936,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44425
44936
|
}
|
|
44426
44937
|
}
|
|
44427
44938
|
const repoDir = luxttsRepoDir();
|
|
44428
|
-
if (!
|
|
44939
|
+
if (!existsSync41(join57(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
44429
44940
|
renderInfo(" Cloning LuxTTS repository...");
|
|
44430
44941
|
try {
|
|
44431
|
-
if (
|
|
44942
|
+
if (existsSync41(repoDir)) {
|
|
44432
44943
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
44433
44944
|
await this.asyncShell(rmCmd, 3e4);
|
|
44434
44945
|
}
|
|
@@ -44467,7 +44978,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44467
44978
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
44468
44979
|
}
|
|
44469
44980
|
}
|
|
44470
|
-
const isJetson = isArm && (
|
|
44981
|
+
const isJetson = isArm && (existsSync41("/etc/nv_tegra_release") || existsSync41("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
44471
44982
|
const installSteps = isArm ? [
|
|
44472
44983
|
// ARM: install individually so we get clear error messages per package.
|
|
44473
44984
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -44535,14 +45046,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44535
45046
|
}
|
|
44536
45047
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
44537
45048
|
autoDetectCloneRef() {
|
|
44538
|
-
if (this.luxttsCloneRef &&
|
|
45049
|
+
if (this.luxttsCloneRef && existsSync41(this.luxttsCloneRef))
|
|
44539
45050
|
return;
|
|
44540
45051
|
const refsDir = luxttsCloneRefsDir();
|
|
44541
|
-
if (!
|
|
45052
|
+
if (!existsSync41(refsDir))
|
|
44542
45053
|
return;
|
|
44543
45054
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
44544
|
-
const p =
|
|
44545
|
-
if (
|
|
45055
|
+
const p = join57(refsDir, name);
|
|
45056
|
+
if (existsSync41(p)) {
|
|
44546
45057
|
this.luxttsCloneRef = p;
|
|
44547
45058
|
return;
|
|
44548
45059
|
}
|
|
@@ -44642,15 +45153,15 @@ if __name__ == '__main__':
|
|
|
44642
45153
|
main()
|
|
44643
45154
|
`;
|
|
44644
45155
|
const scriptPath2 = luxttsInferScript();
|
|
44645
|
-
|
|
44646
|
-
|
|
45156
|
+
mkdirSync17(voiceDir(), { recursive: true });
|
|
45157
|
+
writeFileSync18(scriptPath2, script);
|
|
44647
45158
|
}
|
|
44648
45159
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
44649
45160
|
async ensureLuxttsDaemon() {
|
|
44650
45161
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
44651
45162
|
return true;
|
|
44652
45163
|
const venvPy = luxttsVenvPy();
|
|
44653
|
-
if (!
|
|
45164
|
+
if (!existsSync41(venvPy))
|
|
44654
45165
|
return false;
|
|
44655
45166
|
return new Promise((resolve35) => {
|
|
44656
45167
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
@@ -44734,7 +45245,7 @@ if __name__ == '__main__':
|
|
|
44734
45245
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
44735
45246
|
*/
|
|
44736
45247
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
44737
|
-
if (!this.luxttsCloneRef || !
|
|
45248
|
+
if (!this.luxttsCloneRef || !existsSync41(this.luxttsCloneRef))
|
|
44738
45249
|
return null;
|
|
44739
45250
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44740
45251
|
if (!cleaned)
|
|
@@ -44742,7 +45253,7 @@ if __name__ == '__main__':
|
|
|
44742
45253
|
const ready = await this.ensureLuxttsDaemon();
|
|
44743
45254
|
if (!ready)
|
|
44744
45255
|
return null;
|
|
44745
|
-
const wavPath =
|
|
45256
|
+
const wavPath = join57(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
44746
45257
|
try {
|
|
44747
45258
|
await this.luxttsRequest({
|
|
44748
45259
|
action: "synthesize",
|
|
@@ -44754,17 +45265,17 @@ if __name__ == '__main__':
|
|
|
44754
45265
|
} catch {
|
|
44755
45266
|
return null;
|
|
44756
45267
|
}
|
|
44757
|
-
return
|
|
45268
|
+
return existsSync41(wavPath) ? wavPath : null;
|
|
44758
45269
|
}
|
|
44759
45270
|
/**
|
|
44760
45271
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
44761
45272
|
* Cleans up the WAV file after playback.
|
|
44762
45273
|
*/
|
|
44763
45274
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
44764
|
-
if (!
|
|
45275
|
+
if (!existsSync41(wavPath))
|
|
44765
45276
|
return;
|
|
44766
45277
|
try {
|
|
44767
|
-
const wavData =
|
|
45278
|
+
const wavData = readFileSync30(wavPath);
|
|
44768
45279
|
if (wavData.length > 44) {
|
|
44769
45280
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44770
45281
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -44779,13 +45290,13 @@ if __name__ == '__main__':
|
|
|
44779
45290
|
}
|
|
44780
45291
|
const header = wavData.subarray(0, 44);
|
|
44781
45292
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
44782
|
-
|
|
45293
|
+
writeFileSync18(wavPath, scaled);
|
|
44783
45294
|
}
|
|
44784
45295
|
} catch {
|
|
44785
45296
|
}
|
|
44786
45297
|
if (pitchFactor !== 1) {
|
|
44787
45298
|
try {
|
|
44788
|
-
const wavData =
|
|
45299
|
+
const wavData = readFileSync30(wavPath);
|
|
44789
45300
|
if (wavData.length > 44) {
|
|
44790
45301
|
const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
44791
45302
|
const float32 = new Float32Array(int16.length);
|
|
@@ -44800,7 +45311,7 @@ if __name__ == '__main__':
|
|
|
44800
45311
|
}
|
|
44801
45312
|
if (this.onPCMOutput) {
|
|
44802
45313
|
try {
|
|
44803
|
-
const wavData =
|
|
45314
|
+
const wavData = readFileSync30(wavPath);
|
|
44804
45315
|
if (wavData.length > 44) {
|
|
44805
45316
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
44806
45317
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -44811,7 +45322,7 @@ if __name__ == '__main__':
|
|
|
44811
45322
|
}
|
|
44812
45323
|
if (stereoDelayMs > 0) {
|
|
44813
45324
|
try {
|
|
44814
|
-
const wavData =
|
|
45325
|
+
const wavData = readFileSync30(wavPath);
|
|
44815
45326
|
if (wavData.length > 44) {
|
|
44816
45327
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44817
45328
|
const numChannels = wavData.readUInt16LE(22);
|
|
@@ -44847,7 +45358,7 @@ if __name__ == '__main__':
|
|
|
44847
45358
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
44848
45359
|
*/
|
|
44849
45360
|
async synthesizeLuxttsToBuffer(text) {
|
|
44850
|
-
if (!this.luxttsCloneRef || !
|
|
45361
|
+
if (!this.luxttsCloneRef || !existsSync41(this.luxttsCloneRef))
|
|
44851
45362
|
return null;
|
|
44852
45363
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44853
45364
|
if (!cleaned)
|
|
@@ -44855,7 +45366,7 @@ if __name__ == '__main__':
|
|
|
44855
45366
|
const ready = await this.ensureLuxttsDaemon();
|
|
44856
45367
|
if (!ready)
|
|
44857
45368
|
return null;
|
|
44858
|
-
const wavPath =
|
|
45369
|
+
const wavPath = join57(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
44859
45370
|
try {
|
|
44860
45371
|
await this.luxttsRequest({
|
|
44861
45372
|
action: "synthesize",
|
|
@@ -44867,10 +45378,10 @@ if __name__ == '__main__':
|
|
|
44867
45378
|
} catch {
|
|
44868
45379
|
return null;
|
|
44869
45380
|
}
|
|
44870
|
-
if (!
|
|
45381
|
+
if (!existsSync41(wavPath))
|
|
44871
45382
|
return null;
|
|
44872
45383
|
try {
|
|
44873
|
-
const data =
|
|
45384
|
+
const data = readFileSync30(wavPath);
|
|
44874
45385
|
unlinkSync9(wavPath);
|
|
44875
45386
|
return data;
|
|
44876
45387
|
} catch {
|
|
@@ -44884,40 +45395,40 @@ if __name__ == '__main__':
|
|
|
44884
45395
|
if (this.ort)
|
|
44885
45396
|
return;
|
|
44886
45397
|
const arch2 = process.arch;
|
|
44887
|
-
|
|
44888
|
-
const pkgPath =
|
|
45398
|
+
mkdirSync17(voiceDir(), { recursive: true });
|
|
45399
|
+
const pkgPath = join57(voiceDir(), "package.json");
|
|
44889
45400
|
const expectedDeps = {
|
|
44890
45401
|
"onnxruntime-node": "^1.21.0",
|
|
44891
45402
|
"phonemizer": "^1.2.1"
|
|
44892
45403
|
};
|
|
44893
|
-
if (
|
|
45404
|
+
if (existsSync41(pkgPath)) {
|
|
44894
45405
|
try {
|
|
44895
|
-
const existing = JSON.parse(
|
|
45406
|
+
const existing = JSON.parse(readFileSync30(pkgPath, "utf8"));
|
|
44896
45407
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
44897
45408
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
44898
|
-
|
|
45409
|
+
writeFileSync18(pkgPath, JSON.stringify(existing, null, 2));
|
|
44899
45410
|
}
|
|
44900
45411
|
} catch {
|
|
44901
45412
|
}
|
|
44902
45413
|
}
|
|
44903
|
-
if (!
|
|
44904
|
-
|
|
45414
|
+
if (!existsSync41(pkgPath)) {
|
|
45415
|
+
writeFileSync18(pkgPath, JSON.stringify({
|
|
44905
45416
|
name: "open-agents-voice",
|
|
44906
45417
|
private: true,
|
|
44907
45418
|
dependencies: expectedDeps
|
|
44908
45419
|
}, null, 2));
|
|
44909
45420
|
}
|
|
44910
|
-
const voiceRequire = createRequire(
|
|
45421
|
+
const voiceRequire = createRequire(join57(voiceDir(), "index.js"));
|
|
44911
45422
|
const probeOnnx = async () => {
|
|
44912
45423
|
try {
|
|
44913
|
-
const output = await this.asyncShell(`NODE_PATH="${
|
|
45424
|
+
const output = await this.asyncShell(`NODE_PATH="${join57(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
|
|
44914
45425
|
return output.trim() === "OK";
|
|
44915
45426
|
} catch {
|
|
44916
45427
|
return false;
|
|
44917
45428
|
}
|
|
44918
45429
|
};
|
|
44919
|
-
const onnxNodeModules =
|
|
44920
|
-
const onnxInstalled =
|
|
45430
|
+
const onnxNodeModules = join57(voiceDir(), "node_modules", "onnxruntime-node");
|
|
45431
|
+
const onnxInstalled = existsSync41(onnxNodeModules);
|
|
44921
45432
|
if (onnxInstalled && !await probeOnnx()) {
|
|
44922
45433
|
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
|
|
44923
45434
|
}
|
|
@@ -44966,19 +45477,19 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44966
45477
|
throw new Error(`Unknown model: ${id}`);
|
|
44967
45478
|
const dir = modelDir(id);
|
|
44968
45479
|
const onnxPath = modelOnnxPath(id);
|
|
44969
|
-
const
|
|
44970
|
-
if (
|
|
45480
|
+
const configPath2 = modelConfigPath(id);
|
|
45481
|
+
if (existsSync41(onnxPath) && existsSync41(configPath2))
|
|
44971
45482
|
return;
|
|
44972
|
-
|
|
44973
|
-
if (!
|
|
45483
|
+
mkdirSync17(dir, { recursive: true });
|
|
45484
|
+
if (!existsSync41(configPath2)) {
|
|
44974
45485
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
44975
45486
|
const configResp = await fetch(model.configUrl);
|
|
44976
45487
|
if (!configResp.ok)
|
|
44977
45488
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
44978
45489
|
const configText = await configResp.text();
|
|
44979
|
-
|
|
45490
|
+
writeFileSync18(configPath2, configText);
|
|
44980
45491
|
}
|
|
44981
|
-
if (!
|
|
45492
|
+
if (!existsSync41(onnxPath)) {
|
|
44982
45493
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
44983
45494
|
const onnxResp = await fetch(model.onnxUrl);
|
|
44984
45495
|
if (!onnxResp.ok)
|
|
@@ -45003,7 +45514,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
45003
45514
|
}
|
|
45004
45515
|
}
|
|
45005
45516
|
const fullBuffer = Buffer.concat(chunks);
|
|
45006
|
-
|
|
45517
|
+
writeFileSync18(onnxPath, fullBuffer);
|
|
45007
45518
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
45008
45519
|
}
|
|
45009
45520
|
}
|
|
@@ -45014,11 +45525,11 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
45014
45525
|
if (!this.ort)
|
|
45015
45526
|
throw new Error("ONNX runtime not loaded");
|
|
45016
45527
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
45017
|
-
const
|
|
45018
|
-
if (!
|
|
45528
|
+
const configPath2 = modelConfigPath(this.modelId);
|
|
45529
|
+
if (!existsSync41(onnxPath) || !existsSync41(configPath2)) {
|
|
45019
45530
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
45020
45531
|
}
|
|
45021
|
-
this.config = JSON.parse(
|
|
45532
|
+
this.config = JSON.parse(readFileSync30(configPath2, "utf8"));
|
|
45022
45533
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
45023
45534
|
executionProviders: ["cpu"],
|
|
45024
45535
|
graphOptimizationLevel: "all"
|
|
@@ -45045,8 +45556,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
45045
45556
|
// packages/cli/dist/tui/commands.js
|
|
45046
45557
|
import * as nodeOs from "node:os";
|
|
45047
45558
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
45048
|
-
import { existsSync as
|
|
45049
|
-
import { join as
|
|
45559
|
+
import { existsSync as existsSync42, readFileSync as readFileSync31, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
|
|
45560
|
+
import { join as join58 } from "node:path";
|
|
45050
45561
|
function safeLog(text) {
|
|
45051
45562
|
if (isNeovimActive()) {
|
|
45052
45563
|
writeToNeovimOutput(text + "\n");
|
|
@@ -45655,22 +46166,22 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45655
46166
|
let content = "";
|
|
45656
46167
|
let metadata = {};
|
|
45657
46168
|
if (shareType === "tool") {
|
|
45658
|
-
const toolDir =
|
|
45659
|
-
const toolFile =
|
|
45660
|
-
if (!
|
|
46169
|
+
const toolDir = join58(ctx.repoRoot, ".oa", "tools");
|
|
46170
|
+
const toolFile = join58(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
46171
|
+
if (!existsSync42(toolFile)) {
|
|
45661
46172
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
45662
46173
|
return "handled";
|
|
45663
46174
|
}
|
|
45664
|
-
content =
|
|
46175
|
+
content = readFileSync31(toolFile, "utf8");
|
|
45665
46176
|
metadata = { type: "tool", name: shareName };
|
|
45666
46177
|
} else if (shareType === "skill") {
|
|
45667
|
-
const skillDir =
|
|
45668
|
-
const skillFile =
|
|
45669
|
-
if (!
|
|
46178
|
+
const skillDir = join58(ctx.repoRoot, ".oa", "skills", shareName);
|
|
46179
|
+
const skillFile = join58(skillDir, "SKILL.md");
|
|
46180
|
+
if (!existsSync42(skillFile)) {
|
|
45670
46181
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
45671
46182
|
return "handled";
|
|
45672
46183
|
}
|
|
45673
|
-
content =
|
|
46184
|
+
content = readFileSync31(skillFile, "utf8");
|
|
45674
46185
|
metadata = { type: "skill", name: shareName };
|
|
45675
46186
|
} else {
|
|
45676
46187
|
renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
|
|
@@ -45709,9 +46220,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45709
46220
|
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
45710
46221
|
const nexus = new NexusTool2(ctx.repoRoot);
|
|
45711
46222
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
45712
|
-
const regFile =
|
|
45713
|
-
if (
|
|
45714
|
-
const reg = JSON.parse(
|
|
46223
|
+
const regFile = join58(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
46224
|
+
if (existsSync42(regFile)) {
|
|
46225
|
+
const reg = JSON.parse(readFileSync31(regFile, "utf8"));
|
|
45715
46226
|
const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
|
|
45716
46227
|
if (pinned) {
|
|
45717
46228
|
renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
|
|
@@ -45764,33 +46275,33 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45764
46275
|
lines.push(`
|
|
45765
46276
|
${c2.bold("IPFS / Helia Status")}
|
|
45766
46277
|
`);
|
|
45767
|
-
const ipfsDir =
|
|
45768
|
-
const ipfsLocalDir =
|
|
46278
|
+
const ipfsDir = join58(ctx.repoRoot, ".oa", "ipfs");
|
|
46279
|
+
const ipfsLocalDir = join58(ipfsDir, "local");
|
|
45769
46280
|
let ipfsFiles = 0;
|
|
45770
46281
|
let ipfsBytes = 0;
|
|
45771
46282
|
let heliaBlocks = 0;
|
|
45772
46283
|
let heliaBytes = 0;
|
|
45773
46284
|
try {
|
|
45774
|
-
if (
|
|
46285
|
+
if (existsSync42(ipfsLocalDir)) {
|
|
45775
46286
|
const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
|
|
45776
46287
|
ipfsFiles = files.length;
|
|
45777
46288
|
for (const f of files) {
|
|
45778
46289
|
try {
|
|
45779
|
-
ipfsBytes += statSync14(
|
|
46290
|
+
ipfsBytes += statSync14(join58(ipfsLocalDir, f)).size;
|
|
45780
46291
|
} catch {
|
|
45781
46292
|
}
|
|
45782
46293
|
}
|
|
45783
46294
|
}
|
|
45784
|
-
const heliaBlockDir =
|
|
45785
|
-
if (
|
|
46295
|
+
const heliaBlockDir = join58(ipfsDir, "blocks");
|
|
46296
|
+
if (existsSync42(heliaBlockDir)) {
|
|
45786
46297
|
const walkDir = (dir) => {
|
|
45787
46298
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45788
46299
|
if (entry.isDirectory())
|
|
45789
|
-
walkDir(
|
|
46300
|
+
walkDir(join58(dir, entry.name));
|
|
45790
46301
|
else {
|
|
45791
46302
|
heliaBlocks++;
|
|
45792
46303
|
try {
|
|
45793
|
-
heliaBytes += statSync14(
|
|
46304
|
+
heliaBytes += statSync14(join58(dir, entry.name)).size;
|
|
45794
46305
|
} catch {
|
|
45795
46306
|
}
|
|
45796
46307
|
}
|
|
@@ -45806,9 +46317,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45806
46317
|
lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
|
|
45807
46318
|
lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
|
|
45808
46319
|
try {
|
|
45809
|
-
const statusFile =
|
|
45810
|
-
if (
|
|
45811
|
-
const status = JSON.parse(
|
|
46320
|
+
const statusFile = join58(ctx.repoRoot, ".oa", "nexus", "status.json");
|
|
46321
|
+
if (existsSync42(statusFile)) {
|
|
46322
|
+
const status = JSON.parse(readFileSync31(statusFile, "utf8"));
|
|
45812
46323
|
if (status.peerId) {
|
|
45813
46324
|
lines.push(`
|
|
45814
46325
|
${c2.bold("Peer Info")}`);
|
|
@@ -45827,11 +46338,11 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45827
46338
|
${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
45828
46339
|
lines.push(`
|
|
45829
46340
|
${c2.bold("Identity Kernel")}`);
|
|
45830
|
-
const idDir =
|
|
46341
|
+
const idDir = join58(ctx.repoRoot, ".oa", "identity");
|
|
45831
46342
|
try {
|
|
45832
|
-
const stateFile =
|
|
45833
|
-
if (
|
|
45834
|
-
const state = JSON.parse(
|
|
46343
|
+
const stateFile = join58(idDir, "self-state.json");
|
|
46344
|
+
if (existsSync42(stateFile)) {
|
|
46345
|
+
const state = JSON.parse(readFileSync31(stateFile, "utf8"));
|
|
45835
46346
|
lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
|
|
45836
46347
|
if (state.narrative_summary) {
|
|
45837
46348
|
lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
|
|
@@ -45840,9 +46351,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45840
46351
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
45841
46352
|
lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
|
|
45842
46353
|
}
|
|
45843
|
-
const cidFile =
|
|
45844
|
-
if (
|
|
45845
|
-
const cids = JSON.parse(
|
|
46354
|
+
const cidFile = join58(idDir, "cids.json");
|
|
46355
|
+
if (existsSync42(cidFile)) {
|
|
46356
|
+
const cids = JSON.parse(readFileSync31(cidFile, "utf8"));
|
|
45846
46357
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
45847
46358
|
if (lastCid)
|
|
45848
46359
|
lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -45855,9 +46366,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45855
46366
|
lines.push(`
|
|
45856
46367
|
${c2.bold("Memory Sentiment")}`);
|
|
45857
46368
|
try {
|
|
45858
|
-
const metaFile =
|
|
45859
|
-
if (
|
|
45860
|
-
const store = JSON.parse(
|
|
46369
|
+
const metaFile = join58(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
46370
|
+
if (existsSync42(metaFile)) {
|
|
46371
|
+
const store = JSON.parse(readFileSync31(metaFile, "utf8"));
|
|
45861
46372
|
const active = store.filter((m) => m.type !== "quarantine");
|
|
45862
46373
|
const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
|
|
45863
46374
|
const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
|
|
@@ -45875,8 +46386,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45875
46386
|
} catch {
|
|
45876
46387
|
}
|
|
45877
46388
|
try {
|
|
45878
|
-
const dbPath =
|
|
45879
|
-
if (
|
|
46389
|
+
const dbPath = join58(ctx.repoRoot, ".oa", "memory", "structured.db");
|
|
46390
|
+
if (existsSync42(dbPath)) {
|
|
45880
46391
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45881
46392
|
const db = initDb2(dbPath);
|
|
45882
46393
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -45897,8 +46408,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45897
46408
|
lines.push(`
|
|
45898
46409
|
${c2.bold("Storage Overview")}
|
|
45899
46410
|
`);
|
|
45900
|
-
const oaDir =
|
|
45901
|
-
if (!
|
|
46411
|
+
const oaDir = join58(ctx.repoRoot, ".oa");
|
|
46412
|
+
if (!existsSync42(oaDir)) {
|
|
45902
46413
|
lines.push(` ${c2.dim("No .oa/ directory found.")}`);
|
|
45903
46414
|
safeLog(lines.join("\n") + "\n");
|
|
45904
46415
|
return "handled";
|
|
@@ -45908,7 +46419,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45908
46419
|
const walkStorage = (dir, category) => {
|
|
45909
46420
|
try {
|
|
45910
46421
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45911
|
-
const full =
|
|
46422
|
+
const full = join58(dir, entry.name);
|
|
45912
46423
|
if (entry.isDirectory()) {
|
|
45913
46424
|
const subCat = category || entry.name;
|
|
45914
46425
|
walkStorage(full, subCat);
|
|
@@ -45944,10 +46455,10 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45944
46455
|
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45945
46456
|
const name = entry.name.toLowerCase();
|
|
45946
46457
|
if (sensitivePatterns.some((p) => name.includes(p))) {
|
|
45947
|
-
sensitiveFound.push(
|
|
46458
|
+
sensitiveFound.push(join58(dir, entry.name).replace(oaDir + "/", ""));
|
|
45948
46459
|
}
|
|
45949
46460
|
if (entry.isDirectory())
|
|
45950
|
-
checkSensitive(
|
|
46461
|
+
checkSensitive(join58(dir, entry.name));
|
|
45951
46462
|
}
|
|
45952
46463
|
} catch {
|
|
45953
46464
|
}
|
|
@@ -45975,8 +46486,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45975
46486
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
45976
46487
|
return "handled";
|
|
45977
46488
|
}
|
|
45978
|
-
const resolvedPath =
|
|
45979
|
-
if (!
|
|
46489
|
+
const resolvedPath = join58(ctx.repoRoot, filePath);
|
|
46490
|
+
if (!existsSync42(resolvedPath)) {
|
|
45980
46491
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
45981
46492
|
return "handled";
|
|
45982
46493
|
}
|
|
@@ -45992,9 +46503,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45992
46503
|
}
|
|
45993
46504
|
try {
|
|
45994
46505
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45995
|
-
const dbDir =
|
|
45996
|
-
|
|
45997
|
-
const db = initDb2(
|
|
46506
|
+
const dbDir = join58(ctx.repoRoot, ".oa", "memory");
|
|
46507
|
+
mkdirSync18(dbDir, { recursive: true });
|
|
46508
|
+
const db = initDb2(join58(dbDir, "structured.db"));
|
|
45998
46509
|
const memStore = new ProceduralMemoryStore2(db);
|
|
45999
46510
|
if (isAudio) {
|
|
46000
46511
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -46035,7 +46546,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46035
46546
|
return "handled";
|
|
46036
46547
|
}
|
|
46037
46548
|
} else {
|
|
46038
|
-
content =
|
|
46549
|
+
content = readFileSync31(resolvedPath, "utf8");
|
|
46039
46550
|
}
|
|
46040
46551
|
if (!content.trim()) {
|
|
46041
46552
|
renderWarning("No content extracted.");
|
|
@@ -46074,9 +46585,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46074
46585
|
}
|
|
46075
46586
|
case "fortemi": {
|
|
46076
46587
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
46077
|
-
const fortemiDir =
|
|
46078
|
-
const altFortemiDir =
|
|
46079
|
-
const fDir =
|
|
46588
|
+
const fortemiDir = join58(ctx.repoRoot, "..", "fortemi-react");
|
|
46589
|
+
const altFortemiDir = join58(nodeOs.homedir(), "fortemi-react");
|
|
46590
|
+
const fDir = existsSync42(fortemiDir) ? fortemiDir : existsSync42(altFortemiDir) ? altFortemiDir : null;
|
|
46080
46591
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
46081
46592
|
if (!fDir) {
|
|
46082
46593
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -46091,14 +46602,14 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46091
46602
|
// 24h
|
|
46092
46603
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
46093
46604
|
};
|
|
46094
|
-
const jwtFile =
|
|
46095
|
-
|
|
46096
|
-
|
|
46605
|
+
const jwtFile = join58(ctx.repoRoot, ".oa", "fortemi-jwt.json");
|
|
46606
|
+
mkdirSync18(join58(ctx.repoRoot, ".oa"), { recursive: true });
|
|
46607
|
+
writeFileSync19(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
46097
46608
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
46098
46609
|
try {
|
|
46099
46610
|
const { spawn: spawn22 } = __require("node:child_process");
|
|
46100
46611
|
const child = spawn22("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
46101
|
-
cwd:
|
|
46612
|
+
cwd: join58(fDir, "apps", "standalone"),
|
|
46102
46613
|
stdio: "ignore",
|
|
46103
46614
|
detached: true,
|
|
46104
46615
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -46107,8 +46618,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46107
46618
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
46108
46619
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
46109
46620
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
46110
|
-
const bridgeFile =
|
|
46111
|
-
|
|
46621
|
+
const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
46622
|
+
writeFileSync19(bridgeFile, JSON.stringify({
|
|
46112
46623
|
url: "http://localhost:3000",
|
|
46113
46624
|
pid: child.pid,
|
|
46114
46625
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -46120,12 +46631,12 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46120
46631
|
return "handled";
|
|
46121
46632
|
}
|
|
46122
46633
|
if (fortemiSubCmd === "status") {
|
|
46123
|
-
const bridgeFile =
|
|
46124
|
-
if (!
|
|
46634
|
+
const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
46635
|
+
if (!existsSync42(bridgeFile)) {
|
|
46125
46636
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
46126
46637
|
return "handled";
|
|
46127
46638
|
}
|
|
46128
|
-
const bridge = JSON.parse(
|
|
46639
|
+
const bridge = JSON.parse(readFileSync31(bridgeFile, "utf8"));
|
|
46129
46640
|
let alive = false;
|
|
46130
46641
|
try {
|
|
46131
46642
|
process.kill(bridge.pid, 0);
|
|
@@ -46145,15 +46656,15 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46145
46656
|
lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
|
|
46146
46657
|
lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
|
|
46147
46658
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
46148
|
-
lines.push(` JWT: ${
|
|
46659
|
+
lines.push(` JWT: ${existsSync42(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
|
|
46149
46660
|
lines.push("");
|
|
46150
46661
|
safeLog(lines.join("\n"));
|
|
46151
46662
|
return "handled";
|
|
46152
46663
|
}
|
|
46153
46664
|
if (fortemiSubCmd === "stop") {
|
|
46154
|
-
const bridgeFile =
|
|
46155
|
-
if (
|
|
46156
|
-
const bridge = JSON.parse(
|
|
46665
|
+
const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
46666
|
+
if (existsSync42(bridgeFile)) {
|
|
46667
|
+
const bridge = JSON.parse(readFileSync31(bridgeFile, "utf8"));
|
|
46157
46668
|
try {
|
|
46158
46669
|
process.kill(bridge.pid, "SIGTERM");
|
|
46159
46670
|
} catch {
|
|
@@ -46531,6 +47042,86 @@ async function handleSlashCommand(input, ctx) {
|
|
|
46531
47042
|
}
|
|
46532
47043
|
return "handled";
|
|
46533
47044
|
}
|
|
47045
|
+
case "sponsor": {
|
|
47046
|
+
if (!ctx.rl) {
|
|
47047
|
+
renderWarning("Sponsor wizard requires interactive mode.");
|
|
47048
|
+
return "handled";
|
|
47049
|
+
}
|
|
47050
|
+
const { loadSponsorConfig: loadSponsorConfig2, saveSponsorConfig: saveSponsorConfig2, runSponsorWizard: runSponsorWizard2, showSponsorDashboard: showSponsorDashboard2 } = await Promise.resolve().then(() => (init_sponsor_wizard(), sponsor_wizard_exports));
|
|
47051
|
+
const projectDir = process.cwd();
|
|
47052
|
+
const existingConfig = loadSponsorConfig2(projectDir);
|
|
47053
|
+
const sponsorRl = ctx.rl;
|
|
47054
|
+
if (arg === "pause" && existingConfig?.status === "active") {
|
|
47055
|
+
existingConfig.status = "paused";
|
|
47056
|
+
saveSponsorConfig2(projectDir, existingConfig);
|
|
47057
|
+
renderInfo("Sponsorship paused. /sponsor to resume.");
|
|
47058
|
+
return "handled";
|
|
47059
|
+
}
|
|
47060
|
+
if (arg === "remove" && existingConfig) {
|
|
47061
|
+
existingConfig.status = "inactive";
|
|
47062
|
+
saveSponsorConfig2(projectDir, existingConfig);
|
|
47063
|
+
renderInfo("Sponsorship removed.");
|
|
47064
|
+
return "handled";
|
|
47065
|
+
}
|
|
47066
|
+
if (arg === "status" || existingConfig && existingConfig.status !== "inactive") {
|
|
47067
|
+
if (!existingConfig || existingConfig.status === "inactive") {
|
|
47068
|
+
renderInfo("No active sponsorship. Run /sponsor to start.");
|
|
47069
|
+
return "handled";
|
|
47070
|
+
}
|
|
47071
|
+
const action = await showSponsorDashboard2(existingConfig, projectDir, sponsorRl, ctx.availableContentRows?.());
|
|
47072
|
+
switch (action) {
|
|
47073
|
+
case "modify":
|
|
47074
|
+
break;
|
|
47075
|
+
case "pause":
|
|
47076
|
+
existingConfig.status = "paused";
|
|
47077
|
+
saveSponsorConfig2(projectDir, existingConfig);
|
|
47078
|
+
renderInfo("Sponsorship paused. /sponsor to resume.");
|
|
47079
|
+
return "handled";
|
|
47080
|
+
case "resume":
|
|
47081
|
+
existingConfig.status = "active";
|
|
47082
|
+
saveSponsorConfig2(projectDir, existingConfig);
|
|
47083
|
+
renderInfo("Sponsorship resumed.");
|
|
47084
|
+
return "handled";
|
|
47085
|
+
case "remove":
|
|
47086
|
+
existingConfig.status = "inactive";
|
|
47087
|
+
saveSponsorConfig2(projectDir, existingConfig);
|
|
47088
|
+
renderInfo("Sponsorship removed.");
|
|
47089
|
+
return "handled";
|
|
47090
|
+
default:
|
|
47091
|
+
return "handled";
|
|
47092
|
+
}
|
|
47093
|
+
}
|
|
47094
|
+
const result = await runSponsorWizard2({
|
|
47095
|
+
rl: sponsorRl,
|
|
47096
|
+
projectDir,
|
|
47097
|
+
ollamaUrl: "http://localhost:11434",
|
|
47098
|
+
availableRows: ctx.availableContentRows?.(),
|
|
47099
|
+
onGoLive: async (config) => {
|
|
47100
|
+
if (config.transport.cloudflared && ctx.exposeStart) {
|
|
47101
|
+
try {
|
|
47102
|
+
const url = await ctx.exposeStart("ollama", void 0, "tunnel");
|
|
47103
|
+
if (url)
|
|
47104
|
+
renderInfo(`Tunnel: ${url}`);
|
|
47105
|
+
} catch (err) {
|
|
47106
|
+
renderError(`Tunnel start failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
47107
|
+
}
|
|
47108
|
+
}
|
|
47109
|
+
if (config.transport.libp2p && ctx.exposeStart) {
|
|
47110
|
+
try {
|
|
47111
|
+
const url = await ctx.exposeStart("ollama", void 0, "libp2p");
|
|
47112
|
+
if (url)
|
|
47113
|
+
renderInfo(`P2P: ${url}`);
|
|
47114
|
+
} catch (err) {
|
|
47115
|
+
renderError(`P2P start failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
47116
|
+
}
|
|
47117
|
+
}
|
|
47118
|
+
}
|
|
47119
|
+
});
|
|
47120
|
+
if (result) {
|
|
47121
|
+
renderInfo("Sponsor wizard completed.");
|
|
47122
|
+
}
|
|
47123
|
+
return "handled";
|
|
47124
|
+
}
|
|
46534
47125
|
case "expose": {
|
|
46535
47126
|
if (!ctx.exposeStart) {
|
|
46536
47127
|
renderWarning("Expose gateway not available in this context.");
|
|
@@ -47532,13 +48123,13 @@ async function showCohereDashboard(ctx) {
|
|
|
47532
48123
|
} else if (idResult.key === "view") {
|
|
47533
48124
|
await ik.execute({ operation: "hydrate" });
|
|
47534
48125
|
} else if (idResult.key === "history") {
|
|
47535
|
-
const snapDir =
|
|
47536
|
-
if (
|
|
48126
|
+
const snapDir = join58(ctx.repoRoot, ".oa", "identity", "snapshots");
|
|
48127
|
+
if (existsSync42(snapDir)) {
|
|
47537
48128
|
const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
47538
48129
|
const snapItems = snaps.slice(0, 20).map((f) => ({
|
|
47539
48130
|
key: f,
|
|
47540
48131
|
label: f.replace(".json", ""),
|
|
47541
|
-
detail: `${formatFileSize(statSync14(
|
|
48132
|
+
detail: `${formatFileSize(statSync14(join58(snapDir, f)).size)}`
|
|
47542
48133
|
}));
|
|
47543
48134
|
if (snapItems.length > 0) {
|
|
47544
48135
|
await tuiSelect({
|
|
@@ -47854,12 +48445,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
47854
48445
|
continue;
|
|
47855
48446
|
}
|
|
47856
48447
|
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
47857
|
-
const { copyFileSync: copyFileSync2, mkdirSync:
|
|
48448
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync27, existsSync: exists } = await import("node:fs");
|
|
47858
48449
|
const { homedir: homedir18 } = await import("node:os");
|
|
47859
48450
|
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
47860
48451
|
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
47861
48452
|
if (!exists(destDir))
|
|
47862
|
-
|
|
48453
|
+
mkdirSync27(destDir, { recursive: true });
|
|
47863
48454
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
47864
48455
|
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
47865
48456
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -48351,11 +48942,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
48351
48942
|
const models = await fetchModels(peerUrl, authKey);
|
|
48352
48943
|
if (models.length > 0) {
|
|
48353
48944
|
try {
|
|
48354
|
-
const { writeFileSync:
|
|
48355
|
-
const { join:
|
|
48356
|
-
const cachePath =
|
|
48357
|
-
|
|
48358
|
-
|
|
48945
|
+
const { writeFileSync: writeFileSync26, mkdirSync: mkdirSync27 } = await import("node:fs");
|
|
48946
|
+
const { join: join73, dirname: dirname22 } = await import("node:path");
|
|
48947
|
+
const cachePath = join73(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
48948
|
+
mkdirSync27(dirname22(cachePath), { recursive: true });
|
|
48949
|
+
writeFileSync26(cachePath, JSON.stringify({
|
|
48359
48950
|
peerId,
|
|
48360
48951
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48361
48952
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -48554,17 +49145,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48554
49145
|
try {
|
|
48555
49146
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
48556
49147
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
48557
|
-
const { dirname: dirname22, join:
|
|
48558
|
-
const { existsSync:
|
|
49148
|
+
const { dirname: dirname22, join: join73 } = await import("node:path");
|
|
49149
|
+
const { existsSync: existsSync53 } = await import("node:fs");
|
|
48559
49150
|
const req = createRequire4(import.meta.url);
|
|
48560
49151
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
48561
49152
|
const candidates = [
|
|
48562
|
-
|
|
48563
|
-
|
|
48564
|
-
|
|
49153
|
+
join73(thisDir, "..", "package.json"),
|
|
49154
|
+
join73(thisDir, "..", "..", "package.json"),
|
|
49155
|
+
join73(thisDir, "..", "..", "..", "package.json")
|
|
48565
49156
|
];
|
|
48566
49157
|
for (const pkgPath of candidates) {
|
|
48567
|
-
if (
|
|
49158
|
+
if (existsSync53(pkgPath)) {
|
|
48568
49159
|
const pkg = req(pkgPath);
|
|
48569
49160
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
48570
49161
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -49402,8 +49993,8 @@ var init_commands = __esm({
|
|
|
49402
49993
|
});
|
|
49403
49994
|
|
|
49404
49995
|
// packages/cli/dist/tui/project-context.js
|
|
49405
|
-
import { existsSync as
|
|
49406
|
-
import { join as
|
|
49996
|
+
import { existsSync as existsSync43, readFileSync as readFileSync32, readdirSync as readdirSync13 } from "node:fs";
|
|
49997
|
+
import { join as join59, basename as basename12 } from "node:path";
|
|
49407
49998
|
import { execSync as execSync30 } from "node:child_process";
|
|
49408
49999
|
import { homedir as homedir15, platform as platform4, release } from "node:os";
|
|
49409
50000
|
function getModelTier(modelName) {
|
|
@@ -49438,10 +50029,10 @@ function loadProjectMap(repoRoot) {
|
|
|
49438
50029
|
if (!hasOaDirectory(repoRoot)) {
|
|
49439
50030
|
initOaDirectory(repoRoot);
|
|
49440
50031
|
}
|
|
49441
|
-
const mapPath2 =
|
|
49442
|
-
if (
|
|
50032
|
+
const mapPath2 = join59(repoRoot, OA_DIR, "context", "project-map.md");
|
|
50033
|
+
if (existsSync43(mapPath2)) {
|
|
49443
50034
|
try {
|
|
49444
|
-
const content =
|
|
50035
|
+
const content = readFileSync32(mapPath2, "utf-8");
|
|
49445
50036
|
return content;
|
|
49446
50037
|
} catch {
|
|
49447
50038
|
}
|
|
@@ -49482,31 +50073,31 @@ ${log}`);
|
|
|
49482
50073
|
}
|
|
49483
50074
|
function loadMemoryContext(repoRoot) {
|
|
49484
50075
|
const sections = [];
|
|
49485
|
-
const oaMemDir =
|
|
50076
|
+
const oaMemDir = join59(repoRoot, OA_DIR, "memory");
|
|
49486
50077
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
49487
50078
|
if (oaEntries)
|
|
49488
50079
|
sections.push(oaEntries);
|
|
49489
|
-
const legacyMemDir =
|
|
49490
|
-
if (legacyMemDir !== oaMemDir &&
|
|
50080
|
+
const legacyMemDir = join59(repoRoot, ".open-agents", "memory");
|
|
50081
|
+
if (legacyMemDir !== oaMemDir && existsSync43(legacyMemDir)) {
|
|
49491
50082
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
49492
50083
|
if (legacyEntries)
|
|
49493
50084
|
sections.push(legacyEntries);
|
|
49494
50085
|
}
|
|
49495
|
-
const globalMemDir =
|
|
50086
|
+
const globalMemDir = join59(homedir15(), ".open-agents", "memory");
|
|
49496
50087
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
49497
50088
|
if (globalEntries)
|
|
49498
50089
|
sections.push(globalEntries);
|
|
49499
50090
|
return sections.join("\n\n");
|
|
49500
50091
|
}
|
|
49501
50092
|
function loadMemoryDir(memDir, scope) {
|
|
49502
|
-
if (!
|
|
50093
|
+
if (!existsSync43(memDir))
|
|
49503
50094
|
return "";
|
|
49504
50095
|
const lines = [];
|
|
49505
50096
|
try {
|
|
49506
50097
|
const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
|
|
49507
50098
|
for (const file of files.slice(0, 10)) {
|
|
49508
50099
|
try {
|
|
49509
|
-
const raw =
|
|
50100
|
+
const raw = readFileSync32(join59(memDir, file), "utf-8");
|
|
49510
50101
|
const entries = JSON.parse(raw);
|
|
49511
50102
|
const topic = basename12(file, ".json");
|
|
49512
50103
|
const keys = Object.keys(entries);
|
|
@@ -51025,22 +51616,22 @@ var init_banner = __esm({
|
|
|
51025
51616
|
});
|
|
51026
51617
|
|
|
51027
51618
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
51028
|
-
import { existsSync as
|
|
51029
|
-
import { join as
|
|
51619
|
+
import { existsSync as existsSync44, readFileSync as readFileSync33, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync14 } from "node:fs";
|
|
51620
|
+
import { join as join60, basename as basename13 } from "node:path";
|
|
51030
51621
|
function loadToolProfile(repoRoot) {
|
|
51031
|
-
const filePath =
|
|
51622
|
+
const filePath = join60(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
51032
51623
|
try {
|
|
51033
|
-
if (!
|
|
51624
|
+
if (!existsSync44(filePath))
|
|
51034
51625
|
return null;
|
|
51035
|
-
return JSON.parse(
|
|
51626
|
+
return JSON.parse(readFileSync33(filePath, "utf-8"));
|
|
51036
51627
|
} catch {
|
|
51037
51628
|
return null;
|
|
51038
51629
|
}
|
|
51039
51630
|
}
|
|
51040
51631
|
function saveToolProfile(repoRoot, profile) {
|
|
51041
|
-
const contextDir =
|
|
51042
|
-
|
|
51043
|
-
|
|
51632
|
+
const contextDir = join60(repoRoot, OA_DIR, "context");
|
|
51633
|
+
mkdirSync19(contextDir, { recursive: true });
|
|
51634
|
+
writeFileSync20(join60(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
51044
51635
|
}
|
|
51045
51636
|
function categorizeToolCall(toolName) {
|
|
51046
51637
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -51098,25 +51689,25 @@ function weightedColor(profile) {
|
|
|
51098
51689
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
51099
51690
|
}
|
|
51100
51691
|
function loadCachedDescriptors(repoRoot) {
|
|
51101
|
-
const filePath =
|
|
51692
|
+
const filePath = join60(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
51102
51693
|
try {
|
|
51103
|
-
if (!
|
|
51694
|
+
if (!existsSync44(filePath))
|
|
51104
51695
|
return null;
|
|
51105
|
-
const cached = JSON.parse(
|
|
51696
|
+
const cached = JSON.parse(readFileSync33(filePath, "utf-8"));
|
|
51106
51697
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
51107
51698
|
} catch {
|
|
51108
51699
|
return null;
|
|
51109
51700
|
}
|
|
51110
51701
|
}
|
|
51111
51702
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
51112
|
-
const contextDir =
|
|
51113
|
-
|
|
51703
|
+
const contextDir = join60(repoRoot, OA_DIR, "context");
|
|
51704
|
+
mkdirSync19(contextDir, { recursive: true });
|
|
51114
51705
|
const cached = {
|
|
51115
51706
|
phrases,
|
|
51116
51707
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51117
51708
|
sourceHash
|
|
51118
51709
|
};
|
|
51119
|
-
|
|
51710
|
+
writeFileSync20(join60(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
51120
51711
|
}
|
|
51121
51712
|
function generateDescriptors(repoRoot) {
|
|
51122
51713
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -51164,11 +51755,11 @@ function generateDescriptors(repoRoot) {
|
|
|
51164
51755
|
return phrases;
|
|
51165
51756
|
}
|
|
51166
51757
|
function extractFromPackageJson(repoRoot, tags) {
|
|
51167
|
-
const pkgPath =
|
|
51758
|
+
const pkgPath = join60(repoRoot, "package.json");
|
|
51168
51759
|
try {
|
|
51169
|
-
if (!
|
|
51760
|
+
if (!existsSync44(pkgPath))
|
|
51170
51761
|
return;
|
|
51171
|
-
const pkg = JSON.parse(
|
|
51762
|
+
const pkg = JSON.parse(readFileSync33(pkgPath, "utf-8"));
|
|
51172
51763
|
if (pkg.name && typeof pkg.name === "string") {
|
|
51173
51764
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
51174
51765
|
for (const p of parts)
|
|
@@ -51212,7 +51803,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
51212
51803
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
51213
51804
|
];
|
|
51214
51805
|
for (const check of manifestChecks) {
|
|
51215
|
-
if (
|
|
51806
|
+
if (existsSync44(join60(repoRoot, check.file))) {
|
|
51216
51807
|
tags.push(check.tag);
|
|
51217
51808
|
}
|
|
51218
51809
|
}
|
|
@@ -51234,16 +51825,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
51234
51825
|
}
|
|
51235
51826
|
}
|
|
51236
51827
|
function extractFromMemory(repoRoot, tags) {
|
|
51237
|
-
const memoryDir =
|
|
51828
|
+
const memoryDir = join60(repoRoot, OA_DIR, "memory");
|
|
51238
51829
|
try {
|
|
51239
|
-
if (!
|
|
51830
|
+
if (!existsSync44(memoryDir))
|
|
51240
51831
|
return;
|
|
51241
51832
|
const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
|
|
51242
51833
|
for (const file of files) {
|
|
51243
51834
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
51244
51835
|
tags.push(topic);
|
|
51245
51836
|
try {
|
|
51246
|
-
const data = JSON.parse(
|
|
51837
|
+
const data = JSON.parse(readFileSync33(join60(memoryDir, file), "utf-8"));
|
|
51247
51838
|
if (data && typeof data === "object") {
|
|
51248
51839
|
const keys = Object.keys(data).slice(0, 3);
|
|
51249
51840
|
for (const key of keys) {
|
|
@@ -51898,13 +52489,13 @@ var init_stream_renderer = __esm({
|
|
|
51898
52489
|
});
|
|
51899
52490
|
|
|
51900
52491
|
// packages/cli/dist/tui/edit-history.js
|
|
51901
|
-
import { appendFileSync as appendFileSync3, mkdirSync as
|
|
51902
|
-
import { join as
|
|
52492
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync20 } from "node:fs";
|
|
52493
|
+
import { join as join61 } from "node:path";
|
|
51903
52494
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
51904
|
-
const historyDir =
|
|
51905
|
-
const logPath2 =
|
|
52495
|
+
const historyDir = join61(repoRoot, ".oa", "history");
|
|
52496
|
+
const logPath2 = join61(historyDir, "edits.jsonl");
|
|
51906
52497
|
try {
|
|
51907
|
-
|
|
52498
|
+
mkdirSync20(historyDir, { recursive: true });
|
|
51908
52499
|
} catch {
|
|
51909
52500
|
}
|
|
51910
52501
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -52013,17 +52604,17 @@ var init_edit_history = __esm({
|
|
|
52013
52604
|
});
|
|
52014
52605
|
|
|
52015
52606
|
// packages/cli/dist/tui/promptLoader.js
|
|
52016
|
-
import { readFileSync as
|
|
52017
|
-
import { join as
|
|
52607
|
+
import { readFileSync as readFileSync34, existsSync as existsSync45 } from "node:fs";
|
|
52608
|
+
import { join as join62, dirname as dirname19 } from "node:path";
|
|
52018
52609
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
52019
52610
|
function loadPrompt3(promptPath, vars) {
|
|
52020
52611
|
let content = cache3.get(promptPath);
|
|
52021
52612
|
if (content === void 0) {
|
|
52022
|
-
const fullPath =
|
|
52023
|
-
if (!
|
|
52613
|
+
const fullPath = join62(PROMPTS_DIR3, promptPath);
|
|
52614
|
+
if (!existsSync45(fullPath)) {
|
|
52024
52615
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
52025
52616
|
}
|
|
52026
|
-
content =
|
|
52617
|
+
content = readFileSync34(fullPath, "utf-8");
|
|
52027
52618
|
cache3.set(promptPath, content);
|
|
52028
52619
|
}
|
|
52029
52620
|
if (!vars)
|
|
@@ -52036,23 +52627,23 @@ var init_promptLoader3 = __esm({
|
|
|
52036
52627
|
"use strict";
|
|
52037
52628
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
52038
52629
|
__dirname6 = dirname19(__filename3);
|
|
52039
|
-
devPath2 =
|
|
52040
|
-
publishedPath2 =
|
|
52041
|
-
PROMPTS_DIR3 =
|
|
52630
|
+
devPath2 = join62(__dirname6, "..", "..", "prompts");
|
|
52631
|
+
publishedPath2 = join62(__dirname6, "..", "prompts");
|
|
52632
|
+
PROMPTS_DIR3 = existsSync45(devPath2) ? devPath2 : publishedPath2;
|
|
52042
52633
|
cache3 = /* @__PURE__ */ new Map();
|
|
52043
52634
|
}
|
|
52044
52635
|
});
|
|
52045
52636
|
|
|
52046
52637
|
// packages/cli/dist/tui/dream-engine.js
|
|
52047
|
-
import { mkdirSync as
|
|
52048
|
-
import { join as
|
|
52638
|
+
import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync21, readFileSync as readFileSync35, existsSync as existsSync46, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
|
|
52639
|
+
import { join as join63, basename as basename14 } from "node:path";
|
|
52049
52640
|
import { execSync as execSync31 } from "node:child_process";
|
|
52050
52641
|
function loadAutoresearchMemory(repoRoot) {
|
|
52051
|
-
const memoryPath =
|
|
52052
|
-
if (!
|
|
52642
|
+
const memoryPath = join63(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
52643
|
+
if (!existsSync46(memoryPath))
|
|
52053
52644
|
return "";
|
|
52054
52645
|
try {
|
|
52055
|
-
const raw =
|
|
52646
|
+
const raw = readFileSync35(memoryPath, "utf-8");
|
|
52056
52647
|
const data = JSON.parse(raw);
|
|
52057
52648
|
const sections = [];
|
|
52058
52649
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -52242,14 +52833,14 @@ var init_dream_engine = __esm({
|
|
|
52242
52833
|
const content = String(args["content"] ?? "");
|
|
52243
52834
|
if (!rawPath)
|
|
52244
52835
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
52245
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
52836
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join63(this.autoresearchDir, basename14(rawPath)) : join63(this.autoresearchDir, rawPath);
|
|
52246
52837
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
52247
52838
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
52248
52839
|
}
|
|
52249
52840
|
try {
|
|
52250
|
-
const dir =
|
|
52251
|
-
|
|
52252
|
-
|
|
52841
|
+
const dir = join63(targetPath, "..");
|
|
52842
|
+
mkdirSync21(dir, { recursive: true });
|
|
52843
|
+
writeFileSync21(targetPath, content, "utf-8");
|
|
52253
52844
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
52254
52845
|
} catch (err) {
|
|
52255
52846
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -52277,20 +52868,20 @@ var init_dream_engine = __esm({
|
|
|
52277
52868
|
const rawPath = String(args["path"] ?? "");
|
|
52278
52869
|
const oldStr = String(args["old_string"] ?? "");
|
|
52279
52870
|
const newStr = String(args["new_string"] ?? "");
|
|
52280
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
52871
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join63(this.autoresearchDir, basename14(rawPath)) : join63(this.autoresearchDir, rawPath);
|
|
52281
52872
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
52282
52873
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
52283
52874
|
}
|
|
52284
52875
|
try {
|
|
52285
|
-
if (!
|
|
52876
|
+
if (!existsSync46(targetPath)) {
|
|
52286
52877
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
52287
52878
|
}
|
|
52288
|
-
let content =
|
|
52879
|
+
let content = readFileSync35(targetPath, "utf-8");
|
|
52289
52880
|
if (!content.includes(oldStr)) {
|
|
52290
52881
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
52291
52882
|
}
|
|
52292
52883
|
content = content.replace(oldStr, newStr);
|
|
52293
|
-
|
|
52884
|
+
writeFileSync21(targetPath, content, "utf-8");
|
|
52294
52885
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
52295
52886
|
} catch (err) {
|
|
52296
52887
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -52331,14 +52922,14 @@ var init_dream_engine = __esm({
|
|
|
52331
52922
|
const content = String(args["content"] ?? "");
|
|
52332
52923
|
if (!rawPath)
|
|
52333
52924
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
52334
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52925
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join63(this.dreamsDir, basename14(rawPath)) : join63(this.dreamsDir, rawPath);
|
|
52335
52926
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
52336
52927
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
52337
52928
|
}
|
|
52338
52929
|
try {
|
|
52339
|
-
const dir =
|
|
52340
|
-
|
|
52341
|
-
|
|
52930
|
+
const dir = join63(targetPath, "..");
|
|
52931
|
+
mkdirSync21(dir, { recursive: true });
|
|
52932
|
+
writeFileSync21(targetPath, content, "utf-8");
|
|
52342
52933
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
52343
52934
|
} catch (err) {
|
|
52344
52935
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -52366,20 +52957,20 @@ var init_dream_engine = __esm({
|
|
|
52366
52957
|
const rawPath = String(args["path"] ?? "");
|
|
52367
52958
|
const oldStr = String(args["old_string"] ?? "");
|
|
52368
52959
|
const newStr = String(args["new_string"] ?? "");
|
|
52369
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52960
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join63(this.dreamsDir, basename14(rawPath)) : join63(this.dreamsDir, rawPath);
|
|
52370
52961
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
52371
52962
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
52372
52963
|
}
|
|
52373
52964
|
try {
|
|
52374
|
-
if (!
|
|
52965
|
+
if (!existsSync46(targetPath)) {
|
|
52375
52966
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
52376
52967
|
}
|
|
52377
|
-
let content =
|
|
52968
|
+
let content = readFileSync35(targetPath, "utf-8");
|
|
52378
52969
|
if (!content.includes(oldStr)) {
|
|
52379
52970
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
52380
52971
|
}
|
|
52381
52972
|
content = content.replace(oldStr, newStr);
|
|
52382
|
-
|
|
52973
|
+
writeFileSync21(targetPath, content, "utf-8");
|
|
52383
52974
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
52384
52975
|
} catch (err) {
|
|
52385
52976
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -52433,7 +53024,7 @@ var init_dream_engine = __esm({
|
|
|
52433
53024
|
constructor(config, repoRoot) {
|
|
52434
53025
|
this.config = config;
|
|
52435
53026
|
this.repoRoot = repoRoot;
|
|
52436
|
-
this.dreamsDir =
|
|
53027
|
+
this.dreamsDir = join63(repoRoot, ".oa", "dreams");
|
|
52437
53028
|
this.state = {
|
|
52438
53029
|
mode: "default",
|
|
52439
53030
|
active: false,
|
|
@@ -52464,7 +53055,7 @@ var init_dream_engine = __esm({
|
|
|
52464
53055
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52465
53056
|
results: []
|
|
52466
53057
|
};
|
|
52467
|
-
|
|
53058
|
+
mkdirSync21(this.dreamsDir, { recursive: true });
|
|
52468
53059
|
this.saveDreamState();
|
|
52469
53060
|
try {
|
|
52470
53061
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -52517,8 +53108,8 @@ ${result.summary}`;
|
|
|
52517
53108
|
if (mode !== "default" || cycle === totalCycles) {
|
|
52518
53109
|
renderDreamContraction(cycle);
|
|
52519
53110
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
52520
|
-
const summaryPath =
|
|
52521
|
-
|
|
53111
|
+
const summaryPath = join63(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
53112
|
+
writeFileSync21(summaryPath, cycleSummary, "utf-8");
|
|
52522
53113
|
}
|
|
52523
53114
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
52524
53115
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -52730,7 +53321,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
52730
53321
|
}
|
|
52731
53322
|
/** Build role-specific tool sets for swarm agents */
|
|
52732
53323
|
buildSwarmTools(role, _workspace) {
|
|
52733
|
-
const autoresearchDir =
|
|
53324
|
+
const autoresearchDir = join63(this.repoRoot, ".oa", "autoresearch");
|
|
52734
53325
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
52735
53326
|
switch (role) {
|
|
52736
53327
|
case "researcher": {
|
|
@@ -53094,7 +53685,7 @@ INSTRUCTIONS:
|
|
|
53094
53685
|
2. Summarize the key learnings and next steps
|
|
53095
53686
|
|
|
53096
53687
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
53097
|
-
const reportPath =
|
|
53688
|
+
const reportPath = join63(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
53098
53689
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
53099
53690
|
|
|
53100
53691
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -53116,8 +53707,8 @@ ${summaryResult}
|
|
|
53116
53707
|
*Generated by open-agents autoresearch swarm*
|
|
53117
53708
|
`;
|
|
53118
53709
|
try {
|
|
53119
|
-
|
|
53120
|
-
|
|
53710
|
+
mkdirSync21(this.dreamsDir, { recursive: true });
|
|
53711
|
+
writeFileSync21(reportPath, report, "utf-8");
|
|
53121
53712
|
} catch {
|
|
53122
53713
|
}
|
|
53123
53714
|
renderSwarmComplete(workspace);
|
|
@@ -53183,9 +53774,9 @@ ${summaryResult}
|
|
|
53183
53774
|
}
|
|
53184
53775
|
/** Save workspace backup for lucid mode */
|
|
53185
53776
|
saveVersionCheckpoint(cycle) {
|
|
53186
|
-
const checkpointDir =
|
|
53777
|
+
const checkpointDir = join63(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
53187
53778
|
try {
|
|
53188
|
-
|
|
53779
|
+
mkdirSync21(checkpointDir, { recursive: true });
|
|
53189
53780
|
try {
|
|
53190
53781
|
const gitStatus = execSync31("git status --porcelain", {
|
|
53191
53782
|
cwd: this.repoRoot,
|
|
@@ -53202,10 +53793,10 @@ ${summaryResult}
|
|
|
53202
53793
|
encoding: "utf-8",
|
|
53203
53794
|
timeout: 5e3
|
|
53204
53795
|
}).trim();
|
|
53205
|
-
|
|
53206
|
-
|
|
53207
|
-
|
|
53208
|
-
|
|
53796
|
+
writeFileSync21(join63(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
53797
|
+
writeFileSync21(join63(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
53798
|
+
writeFileSync21(join63(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
53799
|
+
writeFileSync21(join63(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
53209
53800
|
cycle,
|
|
53210
53801
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
53211
53802
|
gitHash,
|
|
@@ -53213,7 +53804,7 @@ ${summaryResult}
|
|
|
53213
53804
|
}, null, 2), "utf-8");
|
|
53214
53805
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
53215
53806
|
} catch {
|
|
53216
|
-
|
|
53807
|
+
writeFileSync21(join63(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
53217
53808
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
53218
53809
|
}
|
|
53219
53810
|
} catch (err) {
|
|
@@ -53271,14 +53862,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
53271
53862
|
---
|
|
53272
53863
|
*Auto-generated by open-agents dream engine*
|
|
53273
53864
|
`;
|
|
53274
|
-
|
|
53865
|
+
writeFileSync21(join63(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
53275
53866
|
} catch {
|
|
53276
53867
|
}
|
|
53277
53868
|
}
|
|
53278
53869
|
/** Save dream state for resume/inspection */
|
|
53279
53870
|
saveDreamState() {
|
|
53280
53871
|
try {
|
|
53281
|
-
|
|
53872
|
+
writeFileSync21(join63(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
53282
53873
|
} catch {
|
|
53283
53874
|
}
|
|
53284
53875
|
}
|
|
@@ -53652,8 +54243,8 @@ var init_bless_engine = __esm({
|
|
|
53652
54243
|
});
|
|
53653
54244
|
|
|
53654
54245
|
// packages/cli/dist/tui/dmn-engine.js
|
|
53655
|
-
import { existsSync as
|
|
53656
|
-
import { join as
|
|
54246
|
+
import { existsSync as existsSync47, readFileSync as readFileSync36, writeFileSync as writeFileSync22, mkdirSync as mkdirSync22, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
|
|
54247
|
+
import { join as join64, basename as basename15 } from "node:path";
|
|
53657
54248
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
53658
54249
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
53659
54250
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -53773,9 +54364,9 @@ var init_dmn_engine = __esm({
|
|
|
53773
54364
|
constructor(config, repoRoot) {
|
|
53774
54365
|
this.config = config;
|
|
53775
54366
|
this.repoRoot = repoRoot;
|
|
53776
|
-
this.stateDir =
|
|
53777
|
-
this.historyDir =
|
|
53778
|
-
|
|
54367
|
+
this.stateDir = join64(repoRoot, ".oa", "dmn");
|
|
54368
|
+
this.historyDir = join64(repoRoot, ".oa", "dmn", "cycles");
|
|
54369
|
+
mkdirSync22(this.historyDir, { recursive: true });
|
|
53779
54370
|
this.loadState();
|
|
53780
54371
|
}
|
|
53781
54372
|
get stats() {
|
|
@@ -54364,11 +54955,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
54364
54955
|
async gatherMemoryTopics() {
|
|
54365
54956
|
const topics = [];
|
|
54366
54957
|
const dirs = [
|
|
54367
|
-
|
|
54368
|
-
|
|
54958
|
+
join64(this.repoRoot, ".oa", "memory"),
|
|
54959
|
+
join64(this.repoRoot, ".open-agents", "memory")
|
|
54369
54960
|
];
|
|
54370
54961
|
for (const dir of dirs) {
|
|
54371
|
-
if (!
|
|
54962
|
+
if (!existsSync47(dir))
|
|
54372
54963
|
continue;
|
|
54373
54964
|
try {
|
|
54374
54965
|
const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -54384,29 +54975,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
54384
54975
|
}
|
|
54385
54976
|
// ── State persistence ─────────────────────────────────────────────────
|
|
54386
54977
|
loadState() {
|
|
54387
|
-
const path =
|
|
54388
|
-
if (
|
|
54978
|
+
const path = join64(this.stateDir, "state.json");
|
|
54979
|
+
if (existsSync47(path)) {
|
|
54389
54980
|
try {
|
|
54390
|
-
this.state = JSON.parse(
|
|
54981
|
+
this.state = JSON.parse(readFileSync36(path, "utf-8"));
|
|
54391
54982
|
} catch {
|
|
54392
54983
|
}
|
|
54393
54984
|
}
|
|
54394
54985
|
}
|
|
54395
54986
|
saveState() {
|
|
54396
54987
|
try {
|
|
54397
|
-
|
|
54988
|
+
writeFileSync22(join64(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
54398
54989
|
} catch {
|
|
54399
54990
|
}
|
|
54400
54991
|
}
|
|
54401
54992
|
saveCycleResult(result) {
|
|
54402
54993
|
try {
|
|
54403
54994
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
54404
|
-
|
|
54995
|
+
writeFileSync22(join64(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
54405
54996
|
const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
54406
54997
|
if (files.length > 50) {
|
|
54407
54998
|
for (const old of files.slice(0, files.length - 50)) {
|
|
54408
54999
|
try {
|
|
54409
|
-
unlinkSync10(
|
|
55000
|
+
unlinkSync10(join64(this.historyDir, old));
|
|
54410
55001
|
} catch {
|
|
54411
55002
|
}
|
|
54412
55003
|
}
|
|
@@ -54419,8 +55010,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
54419
55010
|
});
|
|
54420
55011
|
|
|
54421
55012
|
// packages/cli/dist/tui/snr-engine.js
|
|
54422
|
-
import { existsSync as
|
|
54423
|
-
import { join as
|
|
55013
|
+
import { existsSync as existsSync48, readdirSync as readdirSync17, readFileSync as readFileSync37 } from "node:fs";
|
|
55014
|
+
import { join as join65, basename as basename16 } from "node:path";
|
|
54424
55015
|
function computeDPrime(signalScores, noiseScores) {
|
|
54425
55016
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
54426
55017
|
return 0;
|
|
@@ -54660,11 +55251,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
54660
55251
|
loadMemoryEntries(topics) {
|
|
54661
55252
|
const entries = [];
|
|
54662
55253
|
const dirs = [
|
|
54663
|
-
|
|
54664
|
-
|
|
55254
|
+
join65(this.repoRoot, ".oa", "memory"),
|
|
55255
|
+
join65(this.repoRoot, ".open-agents", "memory")
|
|
54665
55256
|
];
|
|
54666
55257
|
for (const dir of dirs) {
|
|
54667
|
-
if (!
|
|
55258
|
+
if (!existsSync48(dir))
|
|
54668
55259
|
continue;
|
|
54669
55260
|
try {
|
|
54670
55261
|
const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -54673,7 +55264,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
54673
55264
|
if (topics.length > 0 && !topics.includes(topic))
|
|
54674
55265
|
continue;
|
|
54675
55266
|
try {
|
|
54676
|
-
const data = JSON.parse(
|
|
55267
|
+
const data = JSON.parse(readFileSync37(join65(dir, f), "utf-8"));
|
|
54677
55268
|
for (const [key, val] of Object.entries(data)) {
|
|
54678
55269
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
54679
55270
|
entries.push({ topic, key, value });
|
|
@@ -55240,8 +55831,8 @@ var init_tool_policy = __esm({
|
|
|
55240
55831
|
});
|
|
55241
55832
|
|
|
55242
55833
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
55243
|
-
import { mkdirSync as
|
|
55244
|
-
import { join as
|
|
55834
|
+
import { mkdirSync as mkdirSync23, existsSync as existsSync49, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
|
|
55835
|
+
import { join as join66, resolve as resolve30 } from "node:path";
|
|
55245
55836
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
55246
55837
|
function convertMarkdownToTelegramHTML(md) {
|
|
55247
55838
|
let html = md;
|
|
@@ -55569,7 +56160,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
55569
56160
|
this.polling = true;
|
|
55570
56161
|
this.abortController = new AbortController();
|
|
55571
56162
|
try {
|
|
55572
|
-
|
|
56163
|
+
mkdirSync23(this.mediaCacheDir, { recursive: true });
|
|
55573
56164
|
} catch {
|
|
55574
56165
|
}
|
|
55575
56166
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -56006,7 +56597,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
56006
56597
|
return null;
|
|
56007
56598
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
56008
56599
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
56009
|
-
const localPath =
|
|
56600
|
+
const localPath = join66(this.mediaCacheDir, fileName);
|
|
56010
56601
|
await writeFileAsync(localPath, buffer);
|
|
56011
56602
|
return localPath;
|
|
56012
56603
|
} catch {
|
|
@@ -57362,7 +57953,7 @@ var init_text_selection = __esm({
|
|
|
57362
57953
|
});
|
|
57363
57954
|
|
|
57364
57955
|
// packages/cli/dist/tui/status-bar.js
|
|
57365
|
-
import { readFileSync as
|
|
57956
|
+
import { readFileSync as readFileSync38 } from "node:fs";
|
|
57366
57957
|
function setTerminalTitle(task, version) {
|
|
57367
57958
|
if (!process.stdout.isTTY)
|
|
57368
57959
|
return;
|
|
@@ -58044,7 +58635,7 @@ var init_status_bar = __esm({
|
|
|
58044
58635
|
if (nexusDir) {
|
|
58045
58636
|
try {
|
|
58046
58637
|
const metricsPath = nexusDir + "/remote-metrics.json";
|
|
58047
|
-
const raw =
|
|
58638
|
+
const raw = readFileSync38(metricsPath, "utf8");
|
|
58048
58639
|
const cached = JSON.parse(raw);
|
|
58049
58640
|
if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
|
|
58050
58641
|
const m = cached.data;
|
|
@@ -59643,11 +60234,11 @@ var init_mouse_filter = __esm({
|
|
|
59643
60234
|
import * as readline2 from "node:readline";
|
|
59644
60235
|
import { Writable } from "node:stream";
|
|
59645
60236
|
import { cwd } from "node:process";
|
|
59646
|
-
import { resolve as resolve31, join as
|
|
60237
|
+
import { resolve as resolve31, join as join67, dirname as dirname20, extname as extname11 } from "node:path";
|
|
59647
60238
|
import { createRequire as createRequire2 } from "node:module";
|
|
59648
60239
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
59649
|
-
import { readFileSync as
|
|
59650
|
-
import { existsSync as
|
|
60240
|
+
import { readFileSync as readFileSync39, writeFileSync as writeFileSync23, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync19, mkdirSync as mkdirSync24 } from "node:fs";
|
|
60241
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
59651
60242
|
import { execSync as execSync33 } from "node:child_process";
|
|
59652
60243
|
import { homedir as homedir16 } from "node:os";
|
|
59653
60244
|
function formatTimeAgo(date) {
|
|
@@ -59668,12 +60259,12 @@ function getVersion3() {
|
|
|
59668
60259
|
const require2 = createRequire2(import.meta.url);
|
|
59669
60260
|
const thisDir = dirname20(fileURLToPath12(import.meta.url));
|
|
59670
60261
|
const candidates = [
|
|
59671
|
-
|
|
59672
|
-
|
|
59673
|
-
|
|
60262
|
+
join67(thisDir, "..", "package.json"),
|
|
60263
|
+
join67(thisDir, "..", "..", "package.json"),
|
|
60264
|
+
join67(thisDir, "..", "..", "..", "package.json")
|
|
59674
60265
|
];
|
|
59675
60266
|
for (const pkgPath of candidates) {
|
|
59676
|
-
if (
|
|
60267
|
+
if (existsSync50(pkgPath)) {
|
|
59677
60268
|
const pkg = require2(pkgPath);
|
|
59678
60269
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
59679
60270
|
return pkg.version ?? "0.0.0";
|
|
@@ -59908,15 +60499,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
59908
60499
|
function gatherMemorySnippets(root) {
|
|
59909
60500
|
const snippets = [];
|
|
59910
60501
|
const dirs = [
|
|
59911
|
-
|
|
59912
|
-
|
|
60502
|
+
join67(root, ".oa", "memory"),
|
|
60503
|
+
join67(root, ".open-agents", "memory")
|
|
59913
60504
|
];
|
|
59914
60505
|
for (const dir of dirs) {
|
|
59915
|
-
if (!
|
|
60506
|
+
if (!existsSync50(dir))
|
|
59916
60507
|
continue;
|
|
59917
60508
|
try {
|
|
59918
60509
|
for (const f of readdirSync19(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
59919
|
-
const data = JSON.parse(
|
|
60510
|
+
const data = JSON.parse(readFileSync39(join67(dir, f), "utf-8"));
|
|
59920
60511
|
for (const val of Object.values(data)) {
|
|
59921
60512
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
59922
60513
|
if (v.length > 10)
|
|
@@ -60073,9 +60664,9 @@ ${metabolismMemories}
|
|
|
60073
60664
|
} catch {
|
|
60074
60665
|
}
|
|
60075
60666
|
try {
|
|
60076
|
-
const archeFile =
|
|
60077
|
-
if (
|
|
60078
|
-
const variants = JSON.parse(
|
|
60667
|
+
const archeFile = join67(repoRoot, ".oa", "arche", "variants.json");
|
|
60668
|
+
if (existsSync50(archeFile)) {
|
|
60669
|
+
const variants = JSON.parse(readFileSync39(archeFile, "utf8"));
|
|
60079
60670
|
if (variants.length > 0) {
|
|
60080
60671
|
let filtered = variants;
|
|
60081
60672
|
if (taskType) {
|
|
@@ -60212,9 +60803,9 @@ ${lines.join("\n")}
|
|
|
60212
60803
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
60213
60804
|
let identityInjection = "";
|
|
60214
60805
|
try {
|
|
60215
|
-
const ikStateFile =
|
|
60216
|
-
if (
|
|
60217
|
-
const selfState = JSON.parse(
|
|
60806
|
+
const ikStateFile = join67(repoRoot, ".oa", "identity", "self-state.json");
|
|
60807
|
+
if (existsSync50(ikStateFile)) {
|
|
60808
|
+
const selfState = JSON.parse(readFileSync39(ikStateFile, "utf8"));
|
|
60218
60809
|
const lines = [
|
|
60219
60810
|
`[Identity State v${selfState.version}]`,
|
|
60220
60811
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -60855,13 +61446,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60855
61446
|
});
|
|
60856
61447
|
}
|
|
60857
61448
|
try {
|
|
60858
|
-
const ikDir =
|
|
60859
|
-
const ikFile =
|
|
61449
|
+
const ikDir = join67(repoRoot, ".oa", "identity");
|
|
61450
|
+
const ikFile = join67(ikDir, "self-state.json");
|
|
60860
61451
|
let ikState;
|
|
60861
|
-
if (
|
|
60862
|
-
ikState = JSON.parse(
|
|
61452
|
+
if (existsSync50(ikFile)) {
|
|
61453
|
+
ikState = JSON.parse(readFileSync39(ikFile, "utf8"));
|
|
60863
61454
|
} else {
|
|
60864
|
-
|
|
61455
|
+
mkdirSync24(ikDir, { recursive: true });
|
|
60865
61456
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
60866
61457
|
ikState = {
|
|
60867
61458
|
self_id: `oa-${machineId}`,
|
|
@@ -60887,7 +61478,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60887
61478
|
}
|
|
60888
61479
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60889
61480
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60890
|
-
|
|
61481
|
+
writeFileSync23(ikFile, JSON.stringify(ikState, null, 2));
|
|
60891
61482
|
} catch (ikErr) {
|
|
60892
61483
|
try {
|
|
60893
61484
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -60902,14 +61493,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60902
61493
|
} else {
|
|
60903
61494
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
60904
61495
|
try {
|
|
60905
|
-
const ikFile =
|
|
60906
|
-
if (
|
|
60907
|
-
const ikState = JSON.parse(
|
|
61496
|
+
const ikFile = join67(repoRoot, ".oa", "identity", "self-state.json");
|
|
61497
|
+
if (existsSync50(ikFile)) {
|
|
61498
|
+
const ikState = JSON.parse(readFileSync39(ikFile, "utf8"));
|
|
60908
61499
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
60909
61500
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
60910
61501
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60911
61502
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60912
|
-
|
|
61503
|
+
writeFileSync23(ikFile, JSON.stringify(ikState, null, 2));
|
|
60913
61504
|
}
|
|
60914
61505
|
} catch {
|
|
60915
61506
|
}
|
|
@@ -61252,7 +61843,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
61252
61843
|
let p2pGateway = null;
|
|
61253
61844
|
let peerMesh = null;
|
|
61254
61845
|
let inferenceRouter = null;
|
|
61255
|
-
const secretVault = new SecretVault(
|
|
61846
|
+
const secretVault = new SecretVault(join67(repoRoot, ".oa", "vault.enc"));
|
|
61256
61847
|
let adminSessionKey = null;
|
|
61257
61848
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
61258
61849
|
const streamRenderer = new StreamRenderer();
|
|
@@ -61437,6 +62028,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61437
62028
|
"/p2p",
|
|
61438
62029
|
"/secrets",
|
|
61439
62030
|
"/vault",
|
|
62031
|
+
"/sponsor",
|
|
61440
62032
|
"/full-send-bless",
|
|
61441
62033
|
"/bless",
|
|
61442
62034
|
"/telegram",
|
|
@@ -61472,13 +62064,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61472
62064
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
61473
62065
|
return [hits, line];
|
|
61474
62066
|
}
|
|
61475
|
-
const HISTORY_DIR =
|
|
61476
|
-
const HISTORY_FILE =
|
|
62067
|
+
const HISTORY_DIR = join67(homedir16(), ".open-agents");
|
|
62068
|
+
const HISTORY_FILE = join67(HISTORY_DIR, "repl-history");
|
|
61477
62069
|
const MAX_HISTORY_LINES = 500;
|
|
61478
62070
|
let savedHistory = [];
|
|
61479
62071
|
try {
|
|
61480
|
-
if (
|
|
61481
|
-
const raw =
|
|
62072
|
+
if (existsSync50(HISTORY_FILE)) {
|
|
62073
|
+
const raw = readFileSync39(HISTORY_FILE, "utf8").trim();
|
|
61482
62074
|
if (raw)
|
|
61483
62075
|
savedHistory = raw.split("\n").reverse();
|
|
61484
62076
|
}
|
|
@@ -61558,12 +62150,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61558
62150
|
if (!line.trim())
|
|
61559
62151
|
return;
|
|
61560
62152
|
try {
|
|
61561
|
-
|
|
62153
|
+
mkdirSync24(HISTORY_DIR, { recursive: true });
|
|
61562
62154
|
appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
|
|
61563
62155
|
if (Math.random() < 0.02) {
|
|
61564
|
-
const all =
|
|
62156
|
+
const all = readFileSync39(HISTORY_FILE, "utf8").trim().split("\n");
|
|
61565
62157
|
if (all.length > MAX_HISTORY_LINES) {
|
|
61566
|
-
|
|
62158
|
+
writeFileSync23(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
61567
62159
|
}
|
|
61568
62160
|
}
|
|
61569
62161
|
} catch {
|
|
@@ -61739,7 +62331,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61739
62331
|
} catch {
|
|
61740
62332
|
}
|
|
61741
62333
|
try {
|
|
61742
|
-
const oaDir =
|
|
62334
|
+
const oaDir = join67(repoRoot, ".oa");
|
|
61743
62335
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
61744
62336
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61745
62337
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -61762,7 +62354,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61762
62354
|
} catch {
|
|
61763
62355
|
}
|
|
61764
62356
|
try {
|
|
61765
|
-
const oaDir =
|
|
62357
|
+
const oaDir = join67(repoRoot, ".oa");
|
|
61766
62358
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
61767
62359
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61768
62360
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -62646,7 +63238,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62646
63238
|
kind,
|
|
62647
63239
|
targetUrl,
|
|
62648
63240
|
authKey,
|
|
62649
|
-
stateDir:
|
|
63241
|
+
stateDir: join67(repoRoot, ".oa"),
|
|
62650
63242
|
passthrough: passthrough ?? false,
|
|
62651
63243
|
loadbalance: loadbalance ?? false,
|
|
62652
63244
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -62694,7 +63286,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62694
63286
|
await tunnelGateway.stop();
|
|
62695
63287
|
tunnelGateway = null;
|
|
62696
63288
|
}
|
|
62697
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
63289
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join67(repoRoot, ".oa") });
|
|
62698
63290
|
newTunnel.on("stats", (stats) => {
|
|
62699
63291
|
statusBar.setExposeStatus({
|
|
62700
63292
|
status: stats.status,
|
|
@@ -62963,10 +63555,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62963
63555
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
62964
63556
|
}
|
|
62965
63557
|
try {
|
|
62966
|
-
const nexusDir =
|
|
62967
|
-
const pidFile =
|
|
62968
|
-
if (
|
|
62969
|
-
const pid = parseInt(
|
|
63558
|
+
const nexusDir = join67(repoRoot, OA_DIR, "nexus");
|
|
63559
|
+
const pidFile = join67(nexusDir, "daemon.pid");
|
|
63560
|
+
if (existsSync50(pidFile)) {
|
|
63561
|
+
const pid = parseInt(readFileSync39(pidFile, "utf8").trim(), 10);
|
|
62970
63562
|
if (pid > 0) {
|
|
62971
63563
|
try {
|
|
62972
63564
|
if (process.platform === "win32") {
|
|
@@ -62988,13 +63580,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62988
63580
|
} catch {
|
|
62989
63581
|
}
|
|
62990
63582
|
try {
|
|
62991
|
-
const voiceDir2 =
|
|
63583
|
+
const voiceDir2 = join67(homedir16(), ".open-agents", "voice");
|
|
62992
63584
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
62993
63585
|
for (const pf of voicePidFiles) {
|
|
62994
|
-
const pidPath =
|
|
62995
|
-
if (
|
|
63586
|
+
const pidPath = join67(voiceDir2, pf);
|
|
63587
|
+
if (existsSync50(pidPath)) {
|
|
62996
63588
|
try {
|
|
62997
|
-
const pid = parseInt(
|
|
63589
|
+
const pid = parseInt(readFileSync39(pidPath, "utf8").trim(), 10);
|
|
62998
63590
|
if (pid > 0) {
|
|
62999
63591
|
if (process.platform === "win32") {
|
|
63000
63592
|
try {
|
|
@@ -63018,8 +63610,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
63018
63610
|
execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
63019
63611
|
} catch {
|
|
63020
63612
|
}
|
|
63021
|
-
const oaPath =
|
|
63022
|
-
if (
|
|
63613
|
+
const oaPath = join67(repoRoot, OA_DIR);
|
|
63614
|
+
if (existsSync50(oaPath)) {
|
|
63023
63615
|
let deleted = false;
|
|
63024
63616
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
63025
63617
|
try {
|
|
@@ -63391,8 +63983,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
63391
63983
|
}
|
|
63392
63984
|
}
|
|
63393
63985
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
63394
|
-
const isImage = isImagePath(cleanPath) &&
|
|
63395
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
63986
|
+
const isImage = isImagePath(cleanPath) && existsSync50(resolve31(repoRoot, cleanPath));
|
|
63987
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync50(resolve31(repoRoot, cleanPath));
|
|
63396
63988
|
if (activeTask) {
|
|
63397
63989
|
if (activeTask.runner.isPaused) {
|
|
63398
63990
|
activeTask.runner.resume();
|
|
@@ -63401,7 +63993,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
63401
63993
|
if (isImage) {
|
|
63402
63994
|
try {
|
|
63403
63995
|
const imgPath = resolve31(repoRoot, cleanPath);
|
|
63404
|
-
const imgBuffer =
|
|
63996
|
+
const imgBuffer = readFileSync39(imgPath);
|
|
63405
63997
|
const base64 = imgBuffer.toString("base64");
|
|
63406
63998
|
const ext = extname11(cleanPath).toLowerCase();
|
|
63407
63999
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -63900,13 +64492,13 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63900
64492
|
const handle = startTask(task, config, repoRoot);
|
|
63901
64493
|
await handle.promise;
|
|
63902
64494
|
try {
|
|
63903
|
-
const ikDir =
|
|
63904
|
-
const ikFile =
|
|
64495
|
+
const ikDir = join67(repoRoot, ".oa", "identity");
|
|
64496
|
+
const ikFile = join67(ikDir, "self-state.json");
|
|
63905
64497
|
let ikState;
|
|
63906
|
-
if (
|
|
63907
|
-
ikState = JSON.parse(
|
|
64498
|
+
if (existsSync50(ikFile)) {
|
|
64499
|
+
ikState = JSON.parse(readFileSync39(ikFile, "utf8"));
|
|
63908
64500
|
} else {
|
|
63909
|
-
|
|
64501
|
+
mkdirSync24(ikDir, { recursive: true });
|
|
63910
64502
|
ikState = {
|
|
63911
64503
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
63912
64504
|
version: 1,
|
|
@@ -63928,7 +64520,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63928
64520
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
63929
64521
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
63930
64522
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
63931
|
-
|
|
64523
|
+
writeFileSync23(ikFile, JSON.stringify(ikState, null, 2));
|
|
63932
64524
|
} catch (ikErr) {
|
|
63933
64525
|
}
|
|
63934
64526
|
try {
|
|
@@ -63937,12 +64529,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63937
64529
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
63938
64530
|
} catch {
|
|
63939
64531
|
try {
|
|
63940
|
-
const archeDir =
|
|
63941
|
-
const archeFile =
|
|
64532
|
+
const archeDir = join67(repoRoot, ".oa", "arche");
|
|
64533
|
+
const archeFile = join67(archeDir, "variants.json");
|
|
63942
64534
|
let variants = [];
|
|
63943
64535
|
try {
|
|
63944
|
-
if (
|
|
63945
|
-
variants = JSON.parse(
|
|
64536
|
+
if (existsSync50(archeFile))
|
|
64537
|
+
variants = JSON.parse(readFileSync39(archeFile, "utf8"));
|
|
63946
64538
|
} catch {
|
|
63947
64539
|
}
|
|
63948
64540
|
variants.push({
|
|
@@ -63957,15 +64549,15 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63957
64549
|
});
|
|
63958
64550
|
if (variants.length > 50)
|
|
63959
64551
|
variants = variants.slice(-50);
|
|
63960
|
-
|
|
63961
|
-
|
|
64552
|
+
mkdirSync24(archeDir, { recursive: true });
|
|
64553
|
+
writeFileSync23(archeFile, JSON.stringify(variants, null, 2));
|
|
63962
64554
|
} catch {
|
|
63963
64555
|
}
|
|
63964
64556
|
}
|
|
63965
64557
|
try {
|
|
63966
|
-
const metaFile =
|
|
63967
|
-
if (
|
|
63968
|
-
const store = JSON.parse(
|
|
64558
|
+
const metaFile = join67(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
64559
|
+
if (existsSync50(metaFile)) {
|
|
64560
|
+
const store = JSON.parse(readFileSync39(metaFile, "utf8"));
|
|
63969
64561
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
63970
64562
|
let updated = false;
|
|
63971
64563
|
for (const item of surfaced) {
|
|
@@ -63976,7 +64568,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63976
64568
|
updated = true;
|
|
63977
64569
|
}
|
|
63978
64570
|
if (updated) {
|
|
63979
|
-
|
|
64571
|
+
writeFileSync23(metaFile, JSON.stringify(store, null, 2));
|
|
63980
64572
|
}
|
|
63981
64573
|
}
|
|
63982
64574
|
} catch {
|
|
@@ -64029,9 +64621,9 @@ Rules:
|
|
|
64029
64621
|
try {
|
|
64030
64622
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
64031
64623
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
64032
|
-
const dbDir =
|
|
64033
|
-
|
|
64034
|
-
const db = initDb2(
|
|
64624
|
+
const dbDir = join67(repoRoot, ".oa", "memory");
|
|
64625
|
+
mkdirSync24(dbDir, { recursive: true });
|
|
64626
|
+
const db = initDb2(join67(dbDir, "structured.db"));
|
|
64035
64627
|
const memStore = new ProceduralMemoryStore2(db);
|
|
64036
64628
|
memStore.createWithEmbedding({
|
|
64037
64629
|
content: content.slice(0, 600),
|
|
@@ -64046,12 +64638,12 @@ Rules:
|
|
|
64046
64638
|
db.close();
|
|
64047
64639
|
} catch {
|
|
64048
64640
|
}
|
|
64049
|
-
const metaDir =
|
|
64050
|
-
const storeFile =
|
|
64641
|
+
const metaDir = join67(repoRoot, ".oa", "memory", "metabolism");
|
|
64642
|
+
const storeFile = join67(metaDir, "store.json");
|
|
64051
64643
|
let store = [];
|
|
64052
64644
|
try {
|
|
64053
|
-
if (
|
|
64054
|
-
store = JSON.parse(
|
|
64645
|
+
if (existsSync50(storeFile))
|
|
64646
|
+
store = JSON.parse(readFileSync39(storeFile, "utf8"));
|
|
64055
64647
|
} catch {
|
|
64056
64648
|
}
|
|
64057
64649
|
store.push({
|
|
@@ -64067,26 +64659,26 @@ Rules:
|
|
|
64067
64659
|
});
|
|
64068
64660
|
if (store.length > 100)
|
|
64069
64661
|
store = store.slice(-100);
|
|
64070
|
-
|
|
64071
|
-
|
|
64662
|
+
mkdirSync24(metaDir, { recursive: true });
|
|
64663
|
+
writeFileSync23(storeFile, JSON.stringify(store, null, 2));
|
|
64072
64664
|
}
|
|
64073
64665
|
}
|
|
64074
64666
|
} catch {
|
|
64075
64667
|
}
|
|
64076
64668
|
try {
|
|
64077
|
-
const cohereSettingsFile =
|
|
64669
|
+
const cohereSettingsFile = join67(repoRoot, ".oa", "settings.json");
|
|
64078
64670
|
let cohereActive = false;
|
|
64079
64671
|
try {
|
|
64080
|
-
if (
|
|
64081
|
-
const settings = JSON.parse(
|
|
64672
|
+
if (existsSync50(cohereSettingsFile)) {
|
|
64673
|
+
const settings = JSON.parse(readFileSync39(cohereSettingsFile, "utf8"));
|
|
64082
64674
|
cohereActive = settings.cohere === true;
|
|
64083
64675
|
}
|
|
64084
64676
|
} catch {
|
|
64085
64677
|
}
|
|
64086
64678
|
if (cohereActive) {
|
|
64087
|
-
const metaFile =
|
|
64088
|
-
if (
|
|
64089
|
-
const store = JSON.parse(
|
|
64679
|
+
const metaFile = join67(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
64680
|
+
if (existsSync50(metaFile)) {
|
|
64681
|
+
const store = JSON.parse(readFileSync39(metaFile, "utf8"));
|
|
64090
64682
|
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
64091
64683
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
64092
64684
|
try {
|
|
@@ -64111,18 +64703,18 @@ Rules:
|
|
|
64111
64703
|
}
|
|
64112
64704
|
} catch (err) {
|
|
64113
64705
|
try {
|
|
64114
|
-
const ikFile =
|
|
64115
|
-
if (
|
|
64116
|
-
const ikState = JSON.parse(
|
|
64706
|
+
const ikFile = join67(repoRoot, ".oa", "identity", "self-state.json");
|
|
64707
|
+
if (existsSync50(ikFile)) {
|
|
64708
|
+
const ikState = JSON.parse(readFileSync39(ikFile, "utf8"));
|
|
64117
64709
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
64118
64710
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
64119
64711
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
64120
64712
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
64121
|
-
|
|
64713
|
+
writeFileSync23(ikFile, JSON.stringify(ikState, null, 2));
|
|
64122
64714
|
}
|
|
64123
|
-
const metaFile =
|
|
64124
|
-
if (
|
|
64125
|
-
const store = JSON.parse(
|
|
64715
|
+
const metaFile = join67(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
64716
|
+
if (existsSync50(metaFile)) {
|
|
64717
|
+
const store = JSON.parse(readFileSync39(metaFile, "utf8"));
|
|
64126
64718
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
64127
64719
|
for (const item of surfaced) {
|
|
64128
64720
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -64130,15 +64722,15 @@ Rules:
|
|
|
64130
64722
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
64131
64723
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
64132
64724
|
}
|
|
64133
|
-
|
|
64725
|
+
writeFileSync23(metaFile, JSON.stringify(store, null, 2));
|
|
64134
64726
|
}
|
|
64135
64727
|
try {
|
|
64136
|
-
const archeDir =
|
|
64137
|
-
const archeFile =
|
|
64728
|
+
const archeDir = join67(repoRoot, ".oa", "arche");
|
|
64729
|
+
const archeFile = join67(archeDir, "variants.json");
|
|
64138
64730
|
let variants = [];
|
|
64139
64731
|
try {
|
|
64140
|
-
if (
|
|
64141
|
-
variants = JSON.parse(
|
|
64732
|
+
if (existsSync50(archeFile))
|
|
64733
|
+
variants = JSON.parse(readFileSync39(archeFile, "utf8"));
|
|
64142
64734
|
} catch {
|
|
64143
64735
|
}
|
|
64144
64736
|
variants.push({
|
|
@@ -64153,8 +64745,8 @@ Rules:
|
|
|
64153
64745
|
});
|
|
64154
64746
|
if (variants.length > 50)
|
|
64155
64747
|
variants = variants.slice(-50);
|
|
64156
|
-
|
|
64157
|
-
|
|
64748
|
+
mkdirSync24(archeDir, { recursive: true });
|
|
64749
|
+
writeFileSync23(archeFile, JSON.stringify(variants, null, 2));
|
|
64158
64750
|
} catch {
|
|
64159
64751
|
}
|
|
64160
64752
|
} catch {
|
|
@@ -64221,13 +64813,13 @@ __export(run_exports, {
|
|
|
64221
64813
|
});
|
|
64222
64814
|
import { resolve as resolve32 } from "node:path";
|
|
64223
64815
|
import { spawn as spawn20 } from "node:child_process";
|
|
64224
|
-
import { mkdirSync as
|
|
64816
|
+
import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync24, readFileSync as readFileSync40, readdirSync as readdirSync20, existsSync as existsSync51 } from "node:fs";
|
|
64225
64817
|
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
64226
|
-
import { join as
|
|
64818
|
+
import { join as join68 } from "node:path";
|
|
64227
64819
|
function jobsDir(repoPath) {
|
|
64228
64820
|
const root = resolve32(repoPath ?? process.cwd());
|
|
64229
|
-
const dir =
|
|
64230
|
-
|
|
64821
|
+
const dir = join68(root, ".oa", "jobs");
|
|
64822
|
+
mkdirSync25(dir, { recursive: true });
|
|
64231
64823
|
return dir;
|
|
64232
64824
|
}
|
|
64233
64825
|
async function runCommand(opts, config) {
|
|
@@ -64312,7 +64904,7 @@ async function runBackground(task, config, opts) {
|
|
|
64312
64904
|
});
|
|
64313
64905
|
child.unref();
|
|
64314
64906
|
job.pid = child.pid ?? 0;
|
|
64315
|
-
|
|
64907
|
+
writeFileSync24(join68(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64316
64908
|
let output = "";
|
|
64317
64909
|
child.stdout?.on("data", (chunk) => {
|
|
64318
64910
|
output += chunk.toString();
|
|
@@ -64328,7 +64920,7 @@ async function runBackground(task, config, opts) {
|
|
|
64328
64920
|
job.summary = result.summary;
|
|
64329
64921
|
job.durationMs = result.durationMs;
|
|
64330
64922
|
job.error = result.error;
|
|
64331
|
-
|
|
64923
|
+
writeFileSync24(join68(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64332
64924
|
} catch {
|
|
64333
64925
|
}
|
|
64334
64926
|
});
|
|
@@ -64344,13 +64936,13 @@ async function runBackground(task, config, opts) {
|
|
|
64344
64936
|
}
|
|
64345
64937
|
function statusCommand(jobId, repoPath) {
|
|
64346
64938
|
const dir = jobsDir(repoPath);
|
|
64347
|
-
const file =
|
|
64348
|
-
if (!
|
|
64939
|
+
const file = join68(dir, `${jobId}.json`);
|
|
64940
|
+
if (!existsSync51(file)) {
|
|
64349
64941
|
console.error(`Job not found: ${jobId}`);
|
|
64350
64942
|
console.log(`Available jobs: oa jobs`);
|
|
64351
64943
|
process.exit(1);
|
|
64352
64944
|
}
|
|
64353
|
-
const job = JSON.parse(
|
|
64945
|
+
const job = JSON.parse(readFileSync40(file, "utf-8"));
|
|
64354
64946
|
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`;
|
|
64355
64947
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
64356
64948
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -64373,7 +64965,7 @@ function jobsCommand(repoPath) {
|
|
|
64373
64965
|
console.log("Jobs:");
|
|
64374
64966
|
for (const file of files) {
|
|
64375
64967
|
try {
|
|
64376
|
-
const job = JSON.parse(
|
|
64968
|
+
const job = JSON.parse(readFileSync40(join68(dir, file), "utf-8"));
|
|
64377
64969
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
64378
64970
|
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`;
|
|
64379
64971
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -64393,7 +64985,7 @@ import { glob } from "glob";
|
|
|
64393
64985
|
import ignore from "ignore";
|
|
64394
64986
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
64395
64987
|
import { createHash as createHash5 } from "node:crypto";
|
|
64396
|
-
import { join as
|
|
64988
|
+
import { join as join69, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
64397
64989
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
64398
64990
|
var init_codebase_indexer = __esm({
|
|
64399
64991
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -64437,7 +65029,7 @@ var init_codebase_indexer = __esm({
|
|
|
64437
65029
|
const ig = ignore.default();
|
|
64438
65030
|
if (this.config.respectGitignore) {
|
|
64439
65031
|
try {
|
|
64440
|
-
const gitignoreContent = await readFile23(
|
|
65032
|
+
const gitignoreContent = await readFile23(join69(this.config.rootDir, ".gitignore"), "utf-8");
|
|
64441
65033
|
ig.add(gitignoreContent);
|
|
64442
65034
|
} catch {
|
|
64443
65035
|
}
|
|
@@ -64452,7 +65044,7 @@ var init_codebase_indexer = __esm({
|
|
|
64452
65044
|
for (const relativePath of files) {
|
|
64453
65045
|
if (ig.ignores(relativePath))
|
|
64454
65046
|
continue;
|
|
64455
|
-
const fullPath =
|
|
65047
|
+
const fullPath = join69(this.config.rootDir, relativePath);
|
|
64456
65048
|
try {
|
|
64457
65049
|
const fileStat = await stat4(fullPath);
|
|
64458
65050
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -64498,7 +65090,7 @@ var init_codebase_indexer = __esm({
|
|
|
64498
65090
|
if (!child) {
|
|
64499
65091
|
child = {
|
|
64500
65092
|
name: part,
|
|
64501
|
-
path:
|
|
65093
|
+
path: join69(current.path, part),
|
|
64502
65094
|
type: "directory",
|
|
64503
65095
|
children: []
|
|
64504
65096
|
};
|
|
@@ -64581,13 +65173,13 @@ __export(index_repo_exports, {
|
|
|
64581
65173
|
indexRepoCommand: () => indexRepoCommand
|
|
64582
65174
|
});
|
|
64583
65175
|
import { resolve as resolve33 } from "node:path";
|
|
64584
|
-
import { existsSync as
|
|
65176
|
+
import { existsSync as existsSync52, statSync as statSync16 } from "node:fs";
|
|
64585
65177
|
import { cwd as cwd2 } from "node:process";
|
|
64586
65178
|
async function indexRepoCommand(opts, _config) {
|
|
64587
65179
|
const repoRoot = resolve33(opts.repoPath ?? cwd2());
|
|
64588
65180
|
printHeader("Index Repository");
|
|
64589
65181
|
printInfo(`Indexing: ${repoRoot}`);
|
|
64590
|
-
if (!
|
|
65182
|
+
if (!existsSync52(repoRoot)) {
|
|
64591
65183
|
printError(`Path does not exist: ${repoRoot}`);
|
|
64592
65184
|
process.exit(1);
|
|
64593
65185
|
}
|
|
@@ -64839,7 +65431,7 @@ var config_exports = {};
|
|
|
64839
65431
|
__export(config_exports, {
|
|
64840
65432
|
configCommand: () => configCommand
|
|
64841
65433
|
});
|
|
64842
|
-
import { join as
|
|
65434
|
+
import { join as join70, resolve as resolve34 } from "node:path";
|
|
64843
65435
|
import { homedir as homedir17 } from "node:os";
|
|
64844
65436
|
import { cwd as cwd3 } from "node:process";
|
|
64845
65437
|
function redactIfSensitive(key, value) {
|
|
@@ -64922,7 +65514,7 @@ function handleShow(opts, config) {
|
|
|
64922
65514
|
}
|
|
64923
65515
|
}
|
|
64924
65516
|
printSection("Config File");
|
|
64925
|
-
printInfo(`~/.open-agents/config.json (${
|
|
65517
|
+
printInfo(`~/.open-agents/config.json (${join70(homedir17(), ".open-agents", "config.json")})`);
|
|
64926
65518
|
printSection("Priority Chain");
|
|
64927
65519
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
64928
65520
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -64961,7 +65553,7 @@ function handleSet(opts, _config) {
|
|
|
64961
65553
|
const coerced = coerceForSettings(key, value);
|
|
64962
65554
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
64963
65555
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
64964
|
-
printInfo(`Saved to ${
|
|
65556
|
+
printInfo(`Saved to ${join70(repoRoot, ".oa", "settings.json")}`);
|
|
64965
65557
|
printInfo("This override applies only when running in this workspace.");
|
|
64966
65558
|
} catch (err) {
|
|
64967
65559
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -65219,8 +65811,8 @@ __export(eval_exports, {
|
|
|
65219
65811
|
evalCommand: () => evalCommand
|
|
65220
65812
|
});
|
|
65221
65813
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
65222
|
-
import { mkdirSync as
|
|
65223
|
-
import { join as
|
|
65814
|
+
import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync25 } from "node:fs";
|
|
65815
|
+
import { join as join71 } from "node:path";
|
|
65224
65816
|
async function evalCommand(opts, config) {
|
|
65225
65817
|
const suiteName = opts.suite ?? "basic";
|
|
65226
65818
|
const suite = SUITES[suiteName];
|
|
@@ -65345,9 +65937,9 @@ async function evalCommand(opts, config) {
|
|
|
65345
65937
|
process.exit(failed > 0 ? 1 : 0);
|
|
65346
65938
|
}
|
|
65347
65939
|
function createTempEvalRepo() {
|
|
65348
|
-
const dir =
|
|
65349
|
-
|
|
65350
|
-
|
|
65940
|
+
const dir = join71(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
65941
|
+
mkdirSync26(dir, { recursive: true });
|
|
65942
|
+
writeFileSync25(join71(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
65351
65943
|
return dir;
|
|
65352
65944
|
}
|
|
65353
65945
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -65407,7 +65999,7 @@ init_updater();
|
|
|
65407
65999
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
65408
66000
|
import { createRequire as createRequire3 } from "node:module";
|
|
65409
66001
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
65410
|
-
import { dirname as dirname21, join as
|
|
66002
|
+
import { dirname as dirname21, join as join72 } from "node:path";
|
|
65411
66003
|
|
|
65412
66004
|
// packages/cli/dist/cli.js
|
|
65413
66005
|
import { createInterface } from "node:readline";
|
|
@@ -65514,7 +66106,7 @@ init_output();
|
|
|
65514
66106
|
function getVersion4() {
|
|
65515
66107
|
try {
|
|
65516
66108
|
const require2 = createRequire3(import.meta.url);
|
|
65517
|
-
const pkgPath =
|
|
66109
|
+
const pkgPath = join72(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
65518
66110
|
const pkg = require2(pkgPath);
|
|
65519
66111
|
return pkg.version;
|
|
65520
66112
|
} catch {
|