open-agents-ai 0.187.15 → 0.187.17
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 +1092 -699
- package/package.json +1 -1
- package/prompts/tui/dream-consolidate.md +48 -0
package/dist/index.js
CHANGED
|
@@ -12136,8 +12136,8 @@ function deleteCustomToolDefinition(name10, scope, repoRoot) {
|
|
|
12136
12136
|
const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
|
|
12137
12137
|
const filePath = join16(dir, `${name10}.json`);
|
|
12138
12138
|
if (existsSync13(filePath)) {
|
|
12139
|
-
const { unlinkSync:
|
|
12140
|
-
|
|
12139
|
+
const { unlinkSync: unlinkSync14 } = __require("node:fs");
|
|
12140
|
+
unlinkSync14(filePath);
|
|
12141
12141
|
return true;
|
|
12142
12142
|
}
|
|
12143
12143
|
return false;
|
|
@@ -13111,6 +13111,10 @@ var init_skill_builder = __esm({
|
|
|
13111
13111
|
validate: {
|
|
13112
13112
|
type: "boolean",
|
|
13113
13113
|
description: "Whether to run the validation phase (default: true). Validation scores the generated skill and suggests improvements."
|
|
13114
|
+
},
|
|
13115
|
+
session_corrections: {
|
|
13116
|
+
type: "string",
|
|
13117
|
+
description: "Optional: corrections and failed approaches from the current session. Each correction becomes a hard rule in the generated SKILL.md. Format: one correction per line, e.g. 'FAILED: file_write too large \u2014 use file_edit instead'"
|
|
13114
13118
|
}
|
|
13115
13119
|
},
|
|
13116
13120
|
required: ["skill_request"]
|
|
@@ -13134,9 +13138,10 @@ var init_skill_builder = __esm({
|
|
|
13134
13138
|
durationMs: performance.now() - start2
|
|
13135
13139
|
};
|
|
13136
13140
|
}
|
|
13141
|
+
const sessionCorrections = String(args["session_corrections"] ?? "").trim();
|
|
13137
13142
|
try {
|
|
13138
13143
|
const seed = await this.analyzeSeed(skillRequest);
|
|
13139
|
-
let skillContent = await this.expandSkill(seed);
|
|
13144
|
+
let skillContent = await this.expandSkill(seed, sessionCorrections);
|
|
13140
13145
|
let validationInfo = "";
|
|
13141
13146
|
if (shouldValidate) {
|
|
13142
13147
|
const validation = await this.validateSkill(skillContent);
|
|
@@ -13205,15 +13210,21 @@ Validation: ${validation.pass ? "PASS" : "NEEDS IMPROVEMENT"} (${validation.over
|
|
|
13205
13210
|
// -------------------------------------------------------------------------
|
|
13206
13211
|
// Phase 2: Skill Expansion
|
|
13207
13212
|
// -------------------------------------------------------------------------
|
|
13208
|
-
async expandSkill(seed) {
|
|
13213
|
+
async expandSkill(seed, sessionCorrections) {
|
|
13209
13214
|
const prompt = loadBuilderPrompt("skill-expansion.md", {
|
|
13210
13215
|
seed_json: JSON.stringify(seed, null, 2)
|
|
13211
13216
|
});
|
|
13217
|
+
const correctionBlock = sessionCorrections ? `
|
|
13218
|
+
|
|
13219
|
+
IMPORTANT \u2014 Session Corrections (encode as hard rules in the Rules section):
|
|
13220
|
+
These represent things that FAILED or were CORRECTED during the reference session.
|
|
13221
|
+
Each MUST appear as a rule in the generated SKILL.md:
|
|
13222
|
+
${sessionCorrections}` : "";
|
|
13212
13223
|
const response = await this.llmCall([
|
|
13213
13224
|
{ role: "system", content: prompt },
|
|
13214
13225
|
{
|
|
13215
13226
|
role: "user",
|
|
13216
|
-
content: `Generate the complete SKILL.md for the "${seed.name}" skill
|
|
13227
|
+
content: `Generate the complete SKILL.md for the "${seed.name}" skill.${correctionBlock}`
|
|
13217
13228
|
}
|
|
13218
13229
|
]);
|
|
13219
13230
|
let content = response.trim();
|
|
@@ -123831,7 +123842,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
123831
123842
|
"../node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
123832
123843
|
"use strict";
|
|
123833
123844
|
var { writeFile: writeFile21, readFile: readFile24, mkdir: mkdir16 } = __require("node:fs/promises");
|
|
123834
|
-
var { dirname:
|
|
123845
|
+
var { dirname: dirname27, resolve: resolve39 } = __require("node:path");
|
|
123835
123846
|
var { setTimeout: setTimeout3, clearTimeout: clearTimeout3 } = __require("node:timers");
|
|
123836
123847
|
var { InvalidArgumentError, UndiciError } = require_errors2();
|
|
123837
123848
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -124062,7 +124073,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
124062
124073
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
124063
124074
|
}
|
|
124064
124075
|
const resolvedPath = resolve39(path5);
|
|
124065
|
-
await mkdir16(
|
|
124076
|
+
await mkdir16(dirname27(resolvedPath), { recursive: true });
|
|
124066
124077
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
124067
124078
|
hash,
|
|
124068
124079
|
snapshot
|
|
@@ -237724,15 +237735,15 @@ var init_ls = __esm({
|
|
|
237724
237735
|
});
|
|
237725
237736
|
|
|
237726
237737
|
// ../node_modules/@helia/unixfs/dist/src/commands/mkdir.js
|
|
237727
|
-
async function mkdir5(parentCid,
|
|
237728
|
-
if (
|
|
237738
|
+
async function mkdir5(parentCid, dirname27, blockstore, options2 = {}) {
|
|
237739
|
+
if (dirname27.includes("/")) {
|
|
237729
237740
|
throw new InvalidParametersError4("Path must not have slashes");
|
|
237730
237741
|
}
|
|
237731
237742
|
const entry = await exporter2(parentCid, blockstore, options2);
|
|
237732
237743
|
if (entry.type !== "directory") {
|
|
237733
237744
|
throw new NotADirectoryError(`${parentCid.toString()} was not a UnixFS directory`);
|
|
237734
237745
|
}
|
|
237735
|
-
log16("creating %s",
|
|
237746
|
+
log16("creating %s", dirname27);
|
|
237736
237747
|
const metadata = new UnixFS({
|
|
237737
237748
|
type: "directory",
|
|
237738
237749
|
mode: options2.mode,
|
|
@@ -237748,9 +237759,9 @@ async function mkdir5(parentCid, dirname26, blockstore, options2 = {}) {
|
|
|
237748
237759
|
await blockstore.put(emptyDirCid, buf);
|
|
237749
237760
|
const [directory, pblink] = await Promise.all([
|
|
237750
237761
|
cidToDirectory(parentCid, blockstore, options2),
|
|
237751
|
-
cidToPBLink(emptyDirCid,
|
|
237762
|
+
cidToPBLink(emptyDirCid, dirname27, blockstore, options2)
|
|
237752
237763
|
]);
|
|
237753
|
-
log16("adding empty dir called %s to %c",
|
|
237764
|
+
log16("adding empty dir called %s to %c", dirname27, parentCid);
|
|
237754
237765
|
const result = await addLink(directory, pblink, blockstore, {
|
|
237755
237766
|
...options2,
|
|
237756
237767
|
allowOverwriting: options2.force
|
|
@@ -238249,8 +238260,8 @@ var init_unixfs2 = __esm({
|
|
|
238249
238260
|
async *ls(cid, options2 = {}) {
|
|
238250
238261
|
yield* ls(cid, this.components.blockstore, options2);
|
|
238251
238262
|
}
|
|
238252
|
-
async mkdir(cid,
|
|
238253
|
-
return mkdir5(cid,
|
|
238263
|
+
async mkdir(cid, dirname27, options2 = {}) {
|
|
238264
|
+
return mkdir5(cid, dirname27, this.components.blockstore, options2);
|
|
238254
238265
|
}
|
|
238255
238266
|
async rm(cid, path5, options2 = {}) {
|
|
238256
238267
|
return rm2(cid, path5, this.components.blockstore, options2);
|
|
@@ -245494,9 +245505,9 @@ print("${sentinel}")
|
|
|
245494
245505
|
if (!this.proc || this.proc.killed) {
|
|
245495
245506
|
return { success: false, path: "" };
|
|
245496
245507
|
}
|
|
245497
|
-
const { mkdirSync:
|
|
245508
|
+
const { mkdirSync: mkdirSync37, writeFileSync: writeFileSync35 } = await import("node:fs");
|
|
245498
245509
|
const sessionDir = join23(this.cwd, ".oa", "rlm");
|
|
245499
|
-
|
|
245510
|
+
mkdirSync37(sessionDir, { recursive: true });
|
|
245500
245511
|
const sessionPath = join23(sessionDir, "session.json");
|
|
245501
245512
|
try {
|
|
245502
245513
|
const inspectCode = `
|
|
@@ -245520,7 +245531,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
245520
245531
|
trajectoryCount: this.trajectory.length,
|
|
245521
245532
|
subCallCount: this.subCallCount
|
|
245522
245533
|
};
|
|
245523
|
-
|
|
245534
|
+
writeFileSync35(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
245524
245535
|
return { success: true, path: sessionPath };
|
|
245525
245536
|
}
|
|
245526
245537
|
} catch {
|
|
@@ -245532,11 +245543,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
245532
245543
|
* what was previously computed. */
|
|
245533
245544
|
async loadSessionInfo() {
|
|
245534
245545
|
try {
|
|
245535
|
-
const { readFileSync:
|
|
245546
|
+
const { readFileSync: readFileSync53, existsSync: existsSync67 } = await import("node:fs");
|
|
245536
245547
|
const sessionPath = join23(this.cwd, ".oa", "rlm", "session.json");
|
|
245537
|
-
if (!
|
|
245548
|
+
if (!existsSync67(sessionPath))
|
|
245538
245549
|
return null;
|
|
245539
|
-
return JSON.parse(
|
|
245550
|
+
return JSON.parse(readFileSync53(sessionPath, "utf8"));
|
|
245540
245551
|
} catch {
|
|
245541
245552
|
return null;
|
|
245542
245553
|
}
|
|
@@ -245713,10 +245724,10 @@ var init_memory_metabolism = __esm({
|
|
|
245713
245724
|
const trajDir = join24(this.cwd, ".oa", "rlm-trajectories");
|
|
245714
245725
|
let lessons = [];
|
|
245715
245726
|
try {
|
|
245716
|
-
const { readdirSync: readdirSync26, readFileSync:
|
|
245727
|
+
const { readdirSync: readdirSync26, readFileSync: readFileSync53 } = await import("node:fs");
|
|
245717
245728
|
const files = readdirSync26(trajDir).filter((f2) => f2.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
245718
245729
|
for (const file of files) {
|
|
245719
|
-
const lines =
|
|
245730
|
+
const lines = readFileSync53(join24(trajDir, file), "utf8").split("\n").filter((l2) => l2.trim());
|
|
245720
245731
|
for (const line of lines) {
|
|
245721
245732
|
try {
|
|
245722
245733
|
const entry = JSON.parse(line);
|
|
@@ -246100,14 +246111,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246100
246111
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
246101
246112
|
*/
|
|
246102
246113
|
getTopMemoriesSync(k = 5, taskType) {
|
|
246103
|
-
const { readFileSync:
|
|
246114
|
+
const { readFileSync: readFileSync53, existsSync: existsSync67 } = __require("node:fs");
|
|
246104
246115
|
const metaDir = join24(this.cwd, ".oa", "memory", "metabolism");
|
|
246105
246116
|
const storeFile = join24(metaDir, "store.json");
|
|
246106
|
-
if (!
|
|
246117
|
+
if (!existsSync67(storeFile))
|
|
246107
246118
|
return "";
|
|
246108
246119
|
let store2 = [];
|
|
246109
246120
|
try {
|
|
246110
|
-
store2 = JSON.parse(
|
|
246121
|
+
store2 = JSON.parse(readFileSync53(storeFile, "utf8"));
|
|
246111
246122
|
} catch {
|
|
246112
246123
|
return "";
|
|
246113
246124
|
}
|
|
@@ -246129,14 +246140,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246129
246140
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
246130
246141
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
246131
246142
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
246132
|
-
const { readFileSync:
|
|
246143
|
+
const { readFileSync: readFileSync53, writeFileSync: writeFileSync35, existsSync: existsSync67, mkdirSync: mkdirSync37 } = __require("node:fs");
|
|
246133
246144
|
const metaDir = join24(this.cwd, ".oa", "memory", "metabolism");
|
|
246134
246145
|
const storeFile = join24(metaDir, "store.json");
|
|
246135
|
-
if (!
|
|
246146
|
+
if (!existsSync67(storeFile))
|
|
246136
246147
|
return;
|
|
246137
246148
|
let store2 = [];
|
|
246138
246149
|
try {
|
|
246139
|
-
store2 = JSON.parse(
|
|
246150
|
+
store2 = JSON.parse(readFileSync53(storeFile, "utf8"));
|
|
246140
246151
|
} catch {
|
|
246141
246152
|
return;
|
|
246142
246153
|
}
|
|
@@ -246160,8 +246171,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
|
|
|
246160
246171
|
updated = true;
|
|
246161
246172
|
}
|
|
246162
246173
|
if (updated) {
|
|
246163
|
-
|
|
246164
|
-
|
|
246174
|
+
mkdirSync37(metaDir, { recursive: true });
|
|
246175
|
+
writeFileSync35(storeFile, JSON.stringify(store2, null, 2));
|
|
246165
246176
|
}
|
|
246166
246177
|
}
|
|
246167
246178
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -246583,13 +246594,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246583
246594
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
246584
246595
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
246585
246596
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
246586
|
-
const { readFileSync:
|
|
246597
|
+
const { readFileSync: readFileSync53, existsSync: existsSync67 } = __require("node:fs");
|
|
246587
246598
|
const archiveFile = join26(this.cwd, ".oa", "arche", "variants.json");
|
|
246588
|
-
if (!
|
|
246599
|
+
if (!existsSync67(archiveFile))
|
|
246589
246600
|
return "";
|
|
246590
246601
|
let variants = [];
|
|
246591
246602
|
try {
|
|
246592
|
-
variants = JSON.parse(
|
|
246603
|
+
variants = JSON.parse(readFileSync53(archiveFile, "utf8"));
|
|
246593
246604
|
} catch {
|
|
246594
246605
|
return "";
|
|
246595
246606
|
}
|
|
@@ -246607,13 +246618,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246607
246618
|
}
|
|
246608
246619
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
246609
246620
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
246610
|
-
const { readFileSync:
|
|
246621
|
+
const { readFileSync: readFileSync53, writeFileSync: writeFileSync35, existsSync: existsSync67, mkdirSync: mkdirSync37 } = __require("node:fs");
|
|
246611
246622
|
const dir = join26(this.cwd, ".oa", "arche");
|
|
246612
246623
|
const archiveFile = join26(dir, "variants.json");
|
|
246613
246624
|
let variants = [];
|
|
246614
246625
|
try {
|
|
246615
|
-
if (
|
|
246616
|
-
variants = JSON.parse(
|
|
246626
|
+
if (existsSync67(archiveFile))
|
|
246627
|
+
variants = JSON.parse(readFileSync53(archiveFile, "utf8"));
|
|
246617
246628
|
} catch {
|
|
246618
246629
|
}
|
|
246619
246630
|
variants.push({
|
|
@@ -246628,8 +246639,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
246628
246639
|
});
|
|
246629
246640
|
if (variants.length > 50)
|
|
246630
246641
|
variants = variants.slice(-50);
|
|
246631
|
-
|
|
246632
|
-
|
|
246642
|
+
mkdirSync37(dir, { recursive: true });
|
|
246643
|
+
writeFileSync35(archiveFile, JSON.stringify(variants, null, 2));
|
|
246633
246644
|
}
|
|
246634
246645
|
async saveArchive(variants) {
|
|
246635
246646
|
const dir = join26(this.cwd, ".oa", "arche");
|
|
@@ -249445,8 +249456,8 @@ var init_browser_action = __esm({
|
|
|
249445
249456
|
const afterDom = await apiCall("/dom", "GET");
|
|
249446
249457
|
const afterTitle = (afterDom.dom || "").match(/<title[^>]*>([^<]*)<\/title>/i)?.[1] || "";
|
|
249447
249458
|
try {
|
|
249448
|
-
const { unlinkSync:
|
|
249449
|
-
|
|
249459
|
+
const { unlinkSync: unlinkSync14 } = await import("node:fs");
|
|
249460
|
+
unlinkSync14(imagePath);
|
|
249450
249461
|
} catch {
|
|
249451
249462
|
}
|
|
249452
249463
|
return {
|
|
@@ -253603,7 +253614,7 @@ var init_agent_tool = __esm({
|
|
|
253603
253614
|
const label = description ?? `${subagentType}: ${prompt.slice(0, 40)}`;
|
|
253604
253615
|
if (isolation === "worktree") {
|
|
253605
253616
|
this.callbacks.onViewRegister?.(agentId, label);
|
|
253606
|
-
const
|
|
253617
|
+
const spawn26 = this.callbacks.spawnSubprocess({
|
|
253607
253618
|
id: agentId,
|
|
253608
253619
|
task: prompt,
|
|
253609
253620
|
model,
|
|
@@ -253613,7 +253624,7 @@ var init_agent_tool = __esm({
|
|
|
253613
253624
|
success: true,
|
|
253614
253625
|
output: `Agent spawned (subprocess, worktree): ${agentId}
|
|
253615
253626
|
Type: ${subagentType}
|
|
253616
|
-
PID: ${
|
|
253627
|
+
PID: ${spawn26.pid}
|
|
253617
253628
|
Task: ${prompt.slice(0, 100)}
|
|
253618
253629
|
Use task_status("${agentId}") to check progress.`,
|
|
253619
253630
|
durationMs: performance.now() - start2
|
|
@@ -260098,6 +260109,10 @@ var init_agenticRunner = __esm({
|
|
|
260098
260109
|
// WO-E26: prevent double-emit
|
|
260099
260110
|
_recentEnoents = [];
|
|
260100
260111
|
// sliding window of last 8 tool calls
|
|
260112
|
+
_microcompactHintEmitted = false;
|
|
260113
|
+
// WO-LL-02: one memory hint per session
|
|
260114
|
+
_hookDenyHintCount = 0;
|
|
260115
|
+
// WO-LL-02: cap hint injection at 3 per session
|
|
260101
260116
|
// -- Session Checkpointing (Priority 5) --
|
|
260102
260117
|
_sessionId = `session-${Date.now()}`;
|
|
260103
260118
|
_workingDirectory = "";
|
|
@@ -260326,6 +260341,10 @@ ${ctx3}`,
|
|
|
260326
260341
|
content: `Microcompact: cleared ${cleared} old tool result(s), keeping ${keepResults} recent`,
|
|
260327
260342
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
260328
260343
|
});
|
|
260344
|
+
if (!this._microcompactHintEmitted) {
|
|
260345
|
+
this._microcompactHintEmitted = true;
|
|
260346
|
+
this.pendingUserMessages.push(`[SYSTEM] Older tool results have been cleared to save context. If you discovered important patterns or facts, use memory_write to persist them before they are lost from context.`);
|
|
260347
|
+
}
|
|
260329
260348
|
}
|
|
260330
260349
|
}
|
|
260331
260350
|
/** Register a tool for the agent to use */
|
|
@@ -260577,6 +260596,8 @@ TASK: ${task}` : task;
|
|
|
260577
260596
|
let summary = "";
|
|
260578
260597
|
let bruteForceCycle = 0;
|
|
260579
260598
|
this._assistantTextEmitted = false;
|
|
260599
|
+
this._microcompactHintEmitted = false;
|
|
260600
|
+
this._hookDenyHintCount = 0;
|
|
260580
260601
|
let pendingConstraintWarnings = [];
|
|
260581
260602
|
let consecutiveTextOnly = 0;
|
|
260582
260603
|
let loopInterventionCount = 0;
|
|
@@ -261094,6 +261115,10 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
261094
261115
|
reason: hookCheck.reason ?? "hook",
|
|
261095
261116
|
source: "hook"
|
|
261096
261117
|
});
|
|
261118
|
+
if (this._hookDenyHintCount < 3) {
|
|
261119
|
+
this._hookDenyHintCount++;
|
|
261120
|
+
this.pendingUserMessages.push(`[SYSTEM] Tool "${tc.name}" was blocked: ${hookCheck.reason}. If this constraint should persist across sessions, use memory_write to save it (e.g., memory_write(topic="constraints", key="${tc.name}_blocked", value="${(hookCheck.reason ?? "hook").slice(0, 80)}")).`);
|
|
261121
|
+
}
|
|
261097
261122
|
} else {
|
|
261098
261123
|
const finalArgs = hookCheck.modifiedArgs ?? tc.arguments;
|
|
261099
261124
|
try {
|
|
@@ -261189,6 +261214,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
261189
261214
|
if (this._taskState.failedApproaches.length > 10) {
|
|
261190
261215
|
this._taskState.failedApproaches.shift();
|
|
261191
261216
|
}
|
|
261217
|
+
if (this._taskState.failedApproaches.length === 3) {
|
|
261218
|
+
this.pendingUserMessages.push(`[SYSTEM] You have ${this._taskState.failedApproaches.length} failed approaches this session. Consider using memory_write to save these failure patterns so you avoid them in future sessions:
|
|
261219
|
+
` + this._taskState.failedApproaches.map((f2) => `- ${f2}`).join("\n"));
|
|
261220
|
+
}
|
|
261192
261221
|
}
|
|
261193
261222
|
}
|
|
261194
261223
|
if (filePath && (tc.name === "file_read" || tc.name === "file_write" || tc.name === "file_edit" || tc.name === "batch_edit" || tc.name === "file_patch")) {
|
|
@@ -261926,10 +261955,10 @@ ${marker}` : marker);
|
|
|
261926
261955
|
if (!this._workingDirectory)
|
|
261927
261956
|
return;
|
|
261928
261957
|
try {
|
|
261929
|
-
const { mkdirSync:
|
|
261930
|
-
const { join:
|
|
261931
|
-
const sessionDir =
|
|
261932
|
-
|
|
261958
|
+
const { mkdirSync: mkdirSync37, writeFileSync: writeFileSync35 } = __require("node:fs");
|
|
261959
|
+
const { join: join87 } = __require("node:path");
|
|
261960
|
+
const sessionDir = join87(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
261961
|
+
mkdirSync37(sessionDir, { recursive: true });
|
|
261933
261962
|
const checkpoint = {
|
|
261934
261963
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
261935
261964
|
sessionId: this._sessionId,
|
|
@@ -261941,7 +261970,7 @@ ${marker}` : marker);
|
|
|
261941
261970
|
memexEntryCount: this._memexArchive.size,
|
|
261942
261971
|
fileRegistrySize: this._fileRegistry.size
|
|
261943
261972
|
};
|
|
261944
|
-
|
|
261973
|
+
writeFileSync35(join87(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
261945
261974
|
} catch {
|
|
261946
261975
|
}
|
|
261947
261976
|
}
|
|
@@ -262178,8 +262207,8 @@ System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
|
|
|
262178
262207
|
let recoveredTokens = 0;
|
|
262179
262208
|
for (const [filePath, entry] of entries) {
|
|
262180
262209
|
try {
|
|
262181
|
-
const { readFileSync:
|
|
262182
|
-
const content =
|
|
262210
|
+
const { readFileSync: readFileSync53 } = await import("node:fs");
|
|
262211
|
+
const content = readFileSync53(filePath, "utf8");
|
|
262183
262212
|
const tokenEst = Math.ceil(content.length / 4);
|
|
262184
262213
|
if (recoveredTokens + tokenEst > fileRecoveryBudget)
|
|
262185
262214
|
break;
|
|
@@ -263195,24 +263224,24 @@ ${result}`
|
|
|
263195
263224
|
let resizedBase64 = null;
|
|
263196
263225
|
try {
|
|
263197
263226
|
const { execSync: execSync40 } = await import("node:child_process");
|
|
263198
|
-
const { writeFileSync:
|
|
263199
|
-
const { join:
|
|
263227
|
+
const { writeFileSync: writeFileSync35, readFileSync: readFileSync53, unlinkSync: unlinkSync14 } = await import("node:fs");
|
|
263228
|
+
const { join: join87 } = await import("node:path");
|
|
263200
263229
|
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
263201
|
-
const tmpIn =
|
|
263202
|
-
const tmpOut =
|
|
263203
|
-
|
|
263230
|
+
const tmpIn = join87(tmpdir11(), `oa_img_in_${Date.now()}.png`);
|
|
263231
|
+
const tmpOut = join87(tmpdir11(), `oa_img_out_${Date.now()}.jpg`);
|
|
263232
|
+
writeFileSync35(tmpIn, buffer2);
|
|
263204
263233
|
const pyBin = process.platform === "win32" ? "python" : "python3";
|
|
263205
263234
|
const escapedIn = tmpIn.replace(/\\/g, "\\\\");
|
|
263206
263235
|
const escapedOut = tmpOut.replace(/\\/g, "\\\\");
|
|
263207
263236
|
execSync40(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
|
|
263208
|
-
const resizedBuf =
|
|
263237
|
+
const resizedBuf = readFileSync53(tmpOut);
|
|
263209
263238
|
resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
|
|
263210
263239
|
try {
|
|
263211
|
-
|
|
263240
|
+
unlinkSync14(tmpIn);
|
|
263212
263241
|
} catch {
|
|
263213
263242
|
}
|
|
263214
263243
|
try {
|
|
263215
|
-
|
|
263244
|
+
unlinkSync14(tmpOut);
|
|
263216
263245
|
} catch {
|
|
263217
263246
|
}
|
|
263218
263247
|
} catch {
|
|
@@ -274849,26 +274878,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
274849
274878
|
async function fetchPeerModels(peerId, authKey) {
|
|
274850
274879
|
try {
|
|
274851
274880
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
|
|
274852
|
-
const { existsSync:
|
|
274853
|
-
const { join:
|
|
274881
|
+
const { existsSync: existsSync67, readFileSync: readFileSync53 } = await import("node:fs");
|
|
274882
|
+
const { join: join87 } = await import("node:path");
|
|
274854
274883
|
const cwd4 = process.cwd();
|
|
274855
274884
|
const nexusTool = new NexusTool2(cwd4);
|
|
274856
274885
|
const nexusDir = nexusTool.getNexusDir();
|
|
274857
274886
|
let isLocalPeer = false;
|
|
274858
274887
|
try {
|
|
274859
|
-
const statusPath =
|
|
274860
|
-
if (
|
|
274861
|
-
const status = JSON.parse(
|
|
274888
|
+
const statusPath = join87(nexusDir, "status.json");
|
|
274889
|
+
if (existsSync67(statusPath)) {
|
|
274890
|
+
const status = JSON.parse(readFileSync53(statusPath, "utf8"));
|
|
274862
274891
|
if (status.peerId === peerId)
|
|
274863
274892
|
isLocalPeer = true;
|
|
274864
274893
|
}
|
|
274865
274894
|
} catch {
|
|
274866
274895
|
}
|
|
274867
274896
|
if (isLocalPeer) {
|
|
274868
|
-
const pricingPath =
|
|
274869
|
-
if (
|
|
274897
|
+
const pricingPath = join87(nexusDir, "pricing.json");
|
|
274898
|
+
if (existsSync67(pricingPath)) {
|
|
274870
274899
|
try {
|
|
274871
|
-
const pricing = JSON.parse(
|
|
274900
|
+
const pricing = JSON.parse(readFileSync53(pricingPath, "utf8"));
|
|
274872
274901
|
const localModels = (pricing.models || []).map((m2) => ({
|
|
274873
274902
|
name: m2.model || "unknown",
|
|
274874
274903
|
size: m2.parameterSize || "",
|
|
@@ -274882,10 +274911,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
274882
274911
|
}
|
|
274883
274912
|
}
|
|
274884
274913
|
}
|
|
274885
|
-
const cachePath =
|
|
274886
|
-
if (
|
|
274914
|
+
const cachePath = join87(nexusDir, "peer-models-cache.json");
|
|
274915
|
+
if (existsSync67(cachePath)) {
|
|
274887
274916
|
try {
|
|
274888
|
-
const cache7 = JSON.parse(
|
|
274917
|
+
const cache7 = JSON.parse(readFileSync53(cachePath, "utf8"));
|
|
274889
274918
|
if (cache7.peerId === peerId && cache7.models?.length > 0) {
|
|
274890
274919
|
const age = Date.now() - new Date(cache7.cachedAt).getTime();
|
|
274891
274920
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -275000,10 +275029,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
275000
275029
|
} catch {
|
|
275001
275030
|
}
|
|
275002
275031
|
if (isLocalPeer) {
|
|
275003
|
-
const pricingPath =
|
|
275004
|
-
if (
|
|
275032
|
+
const pricingPath = join87(nexusDir, "pricing.json");
|
|
275033
|
+
if (existsSync67(pricingPath)) {
|
|
275005
275034
|
try {
|
|
275006
|
-
const pricing = JSON.parse(
|
|
275035
|
+
const pricing = JSON.parse(readFileSync53(pricingPath, "utf8"));
|
|
275007
275036
|
return (pricing.models || []).map((m2) => ({
|
|
275008
275037
|
name: m2.model || "unknown",
|
|
275009
275038
|
size: m2.parameterSize || "",
|
|
@@ -280351,6 +280380,185 @@ var init_neovim_mode = __esm({
|
|
|
280351
280380
|
}
|
|
280352
280381
|
});
|
|
280353
280382
|
|
|
280383
|
+
// packages/cli/dist/daemon.js
|
|
280384
|
+
var daemon_exports = {};
|
|
280385
|
+
__export(daemon_exports, {
|
|
280386
|
+
ensureDaemon: () => ensureDaemon,
|
|
280387
|
+
getDaemonPid: () => getDaemonPid,
|
|
280388
|
+
getDaemonStatus: () => getDaemonStatus,
|
|
280389
|
+
isDaemonRunning: () => isDaemonRunning,
|
|
280390
|
+
startDaemon: () => startDaemon,
|
|
280391
|
+
stopDaemon: () => stopDaemon
|
|
280392
|
+
});
|
|
280393
|
+
import { spawn as spawn22 } from "node:child_process";
|
|
280394
|
+
import { existsSync as existsSync46, readFileSync as readFileSync34, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, unlinkSync as unlinkSync9 } from "node:fs";
|
|
280395
|
+
import { join as join62 } from "node:path";
|
|
280396
|
+
import { homedir as homedir18 } from "node:os";
|
|
280397
|
+
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
280398
|
+
import { dirname as dirname20 } from "node:path";
|
|
280399
|
+
function getDaemonPort() {
|
|
280400
|
+
const env2 = process.env["OA_HOST"];
|
|
280401
|
+
if (env2) {
|
|
280402
|
+
const parts = env2.split(":");
|
|
280403
|
+
const last2 = parts[parts.length - 1];
|
|
280404
|
+
if (last2 && /^\d+$/.test(last2))
|
|
280405
|
+
return parseInt(last2, 10);
|
|
280406
|
+
}
|
|
280407
|
+
return parseInt(process.env["OA_PORT"] ?? String(DEFAULT_PORT2), 10);
|
|
280408
|
+
}
|
|
280409
|
+
async function isDaemonRunning(port) {
|
|
280410
|
+
const p2 = port ?? getDaemonPort();
|
|
280411
|
+
try {
|
|
280412
|
+
const resp = await fetch(`http://127.0.0.1:${p2}/health`, {
|
|
280413
|
+
signal: AbortSignal.timeout(2e3)
|
|
280414
|
+
});
|
|
280415
|
+
return resp.ok;
|
|
280416
|
+
} catch {
|
|
280417
|
+
return false;
|
|
280418
|
+
}
|
|
280419
|
+
}
|
|
280420
|
+
function getDaemonPid() {
|
|
280421
|
+
if (!existsSync46(PID_FILE2))
|
|
280422
|
+
return null;
|
|
280423
|
+
try {
|
|
280424
|
+
const pid = parseInt(readFileSync34(PID_FILE2, "utf8").trim(), 10);
|
|
280425
|
+
if (!pid || pid <= 0)
|
|
280426
|
+
return null;
|
|
280427
|
+
process.kill(pid, 0);
|
|
280428
|
+
return pid;
|
|
280429
|
+
} catch {
|
|
280430
|
+
try {
|
|
280431
|
+
unlinkSync9(PID_FILE2);
|
|
280432
|
+
} catch {
|
|
280433
|
+
}
|
|
280434
|
+
return null;
|
|
280435
|
+
}
|
|
280436
|
+
}
|
|
280437
|
+
async function startDaemon() {
|
|
280438
|
+
mkdirSync19(OA_DIR2, { recursive: true });
|
|
280439
|
+
const nodeExe = process.execPath;
|
|
280440
|
+
let oaScript = process.argv[1];
|
|
280441
|
+
if (!oaScript) {
|
|
280442
|
+
try {
|
|
280443
|
+
const { execSync: execSync40 } = await import("node:child_process");
|
|
280444
|
+
const whichOa = execSync40("which oa 2>/dev/null || where oa 2>nul", { encoding: "utf8" }).trim();
|
|
280445
|
+
if (whichOa)
|
|
280446
|
+
oaScript = whichOa;
|
|
280447
|
+
} catch {
|
|
280448
|
+
}
|
|
280449
|
+
}
|
|
280450
|
+
if (!oaScript) {
|
|
280451
|
+
const thisDir = dirname20(fileURLToPath13(import.meta.url));
|
|
280452
|
+
const indexJs = join62(thisDir, "index.js");
|
|
280453
|
+
if (existsSync46(indexJs))
|
|
280454
|
+
oaScript = indexJs;
|
|
280455
|
+
}
|
|
280456
|
+
if (!oaScript)
|
|
280457
|
+
return null;
|
|
280458
|
+
try {
|
|
280459
|
+
const child = spawn22(nodeExe, [oaScript, "serve", "--quiet", "--daemon"], {
|
|
280460
|
+
detached: true,
|
|
280461
|
+
stdio: "ignore",
|
|
280462
|
+
env: {
|
|
280463
|
+
...process.env,
|
|
280464
|
+
OA_DAEMON: "1"
|
|
280465
|
+
// signal to serve.ts that it's running as daemon
|
|
280466
|
+
}
|
|
280467
|
+
});
|
|
280468
|
+
child.unref();
|
|
280469
|
+
const pid = child.pid ?? null;
|
|
280470
|
+
if (pid) {
|
|
280471
|
+
writeFileSync20(PID_FILE2, String(pid), "utf8");
|
|
280472
|
+
}
|
|
280473
|
+
return pid;
|
|
280474
|
+
} catch {
|
|
280475
|
+
return null;
|
|
280476
|
+
}
|
|
280477
|
+
}
|
|
280478
|
+
function stopDaemon() {
|
|
280479
|
+
const pid = getDaemonPid();
|
|
280480
|
+
if (!pid)
|
|
280481
|
+
return false;
|
|
280482
|
+
try {
|
|
280483
|
+
process.kill(pid, "SIGTERM");
|
|
280484
|
+
try {
|
|
280485
|
+
unlinkSync9(PID_FILE2);
|
|
280486
|
+
} catch {
|
|
280487
|
+
}
|
|
280488
|
+
return true;
|
|
280489
|
+
} catch {
|
|
280490
|
+
try {
|
|
280491
|
+
unlinkSync9(PID_FILE2);
|
|
280492
|
+
} catch {
|
|
280493
|
+
}
|
|
280494
|
+
return false;
|
|
280495
|
+
}
|
|
280496
|
+
}
|
|
280497
|
+
async function ensureDaemon() {
|
|
280498
|
+
const port = getDaemonPort();
|
|
280499
|
+
if (await isDaemonRunning(port)) {
|
|
280500
|
+
return true;
|
|
280501
|
+
}
|
|
280502
|
+
const stalePid = getDaemonPid();
|
|
280503
|
+
if (stalePid) {
|
|
280504
|
+
try {
|
|
280505
|
+
process.kill(stalePid, "SIGTERM");
|
|
280506
|
+
} catch {
|
|
280507
|
+
}
|
|
280508
|
+
try {
|
|
280509
|
+
unlinkSync9(PID_FILE2);
|
|
280510
|
+
} catch {
|
|
280511
|
+
}
|
|
280512
|
+
}
|
|
280513
|
+
const pid = await startDaemon();
|
|
280514
|
+
if (!pid)
|
|
280515
|
+
return false;
|
|
280516
|
+
for (let i2 = 0; i2 < 20; i2++) {
|
|
280517
|
+
await new Promise((r2) => setTimeout(r2, 500));
|
|
280518
|
+
if (await isDaemonRunning(port)) {
|
|
280519
|
+
return true;
|
|
280520
|
+
}
|
|
280521
|
+
}
|
|
280522
|
+
try {
|
|
280523
|
+
process.kill(pid, "SIGTERM");
|
|
280524
|
+
} catch {
|
|
280525
|
+
}
|
|
280526
|
+
try {
|
|
280527
|
+
unlinkSync9(PID_FILE2);
|
|
280528
|
+
} catch {
|
|
280529
|
+
}
|
|
280530
|
+
return false;
|
|
280531
|
+
}
|
|
280532
|
+
async function getDaemonStatus() {
|
|
280533
|
+
const port = getDaemonPort();
|
|
280534
|
+
const pid = getDaemonPid();
|
|
280535
|
+
const running = await isDaemonRunning(port);
|
|
280536
|
+
let uptime2;
|
|
280537
|
+
if (running) {
|
|
280538
|
+
try {
|
|
280539
|
+
const resp = await fetch(`http://127.0.0.1:${port}/health`, {
|
|
280540
|
+
signal: AbortSignal.timeout(2e3)
|
|
280541
|
+
});
|
|
280542
|
+
if (resp.ok) {
|
|
280543
|
+
const data = await resp.json();
|
|
280544
|
+
if (data.uptime)
|
|
280545
|
+
uptime2 = data.uptime;
|
|
280546
|
+
}
|
|
280547
|
+
} catch {
|
|
280548
|
+
}
|
|
280549
|
+
}
|
|
280550
|
+
return { running, pid, port, uptime: uptime2, pidFile: PID_FILE2 };
|
|
280551
|
+
}
|
|
280552
|
+
var OA_DIR2, PID_FILE2, DEFAULT_PORT2;
|
|
280553
|
+
var init_daemon = __esm({
|
|
280554
|
+
"packages/cli/dist/daemon.js"() {
|
|
280555
|
+
"use strict";
|
|
280556
|
+
OA_DIR2 = join62(homedir18(), ".open-agents");
|
|
280557
|
+
PID_FILE2 = join62(OA_DIR2, "daemon.pid");
|
|
280558
|
+
DEFAULT_PORT2 = 11435;
|
|
280559
|
+
}
|
|
280560
|
+
});
|
|
280561
|
+
|
|
280354
280562
|
// packages/cli/dist/tui/sponsor-anims.js
|
|
280355
280563
|
var sponsor_anims_exports = {};
|
|
280356
280564
|
__export(sponsor_anims_exports, {
|
|
@@ -280741,8 +280949,8 @@ __export(sponsor_wizard_exports, {
|
|
|
280741
280949
|
saveSponsorConfig: () => saveSponsorConfig,
|
|
280742
280950
|
showSponsorDashboard: () => showSponsorDashboard
|
|
280743
280951
|
});
|
|
280744
|
-
import { existsSync as
|
|
280745
|
-
import { join as
|
|
280952
|
+
import { existsSync as existsSync47, readFileSync as readFileSync35, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20 } from "node:fs";
|
|
280953
|
+
import { join as join63 } from "node:path";
|
|
280746
280954
|
function colorPreview(code8) {
|
|
280747
280955
|
return `\x1B[38;5;${code8}m\u2588\u2588\u2588\u2588\x1B[0m (${code8})`;
|
|
280748
280956
|
}
|
|
@@ -280755,26 +280963,26 @@ function gradientPreview(start2, end) {
|
|
|
280755
280963
|
return s2;
|
|
280756
280964
|
}
|
|
280757
280965
|
function sponsorDir(projectDir) {
|
|
280758
|
-
return
|
|
280966
|
+
return join63(projectDir, ".oa", "sponsor");
|
|
280759
280967
|
}
|
|
280760
280968
|
function configPath(projectDir) {
|
|
280761
|
-
return
|
|
280969
|
+
return join63(sponsorDir(projectDir), "config.json");
|
|
280762
280970
|
}
|
|
280763
280971
|
function loadSponsorConfig(projectDir) {
|
|
280764
280972
|
const p2 = configPath(projectDir);
|
|
280765
|
-
if (!
|
|
280973
|
+
if (!existsSync47(p2))
|
|
280766
280974
|
return null;
|
|
280767
280975
|
try {
|
|
280768
|
-
return JSON.parse(
|
|
280976
|
+
return JSON.parse(readFileSync35(p2, "utf8"));
|
|
280769
280977
|
} catch {
|
|
280770
280978
|
return null;
|
|
280771
280979
|
}
|
|
280772
280980
|
}
|
|
280773
280981
|
function saveSponsorConfig(projectDir, config) {
|
|
280774
280982
|
const dir = sponsorDir(projectDir);
|
|
280775
|
-
|
|
280983
|
+
mkdirSync20(dir, { recursive: true });
|
|
280776
280984
|
config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
280777
|
-
|
|
280985
|
+
writeFileSync21(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
|
|
280778
280986
|
}
|
|
280779
280987
|
function defaultConfig2() {
|
|
280780
280988
|
return {
|
|
@@ -281665,9 +281873,9 @@ __export(voice_exports, {
|
|
|
281665
281873
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
281666
281874
|
resetNarrationContext: () => resetNarrationContext
|
|
281667
281875
|
});
|
|
281668
|
-
import { existsSync as
|
|
281669
|
-
import { join as
|
|
281670
|
-
import { homedir as
|
|
281876
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync21, writeFileSync as writeFileSync22, readFileSync as readFileSync36, unlinkSync as unlinkSync10, readdirSync as readdirSync13, renameSync, statSync as statSync14 } from "node:fs";
|
|
281877
|
+
import { join as join64, dirname as dirname21 } from "node:path";
|
|
281878
|
+
import { homedir as homedir19, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
281671
281879
|
import { execSync as execSync33, spawn as nodeSpawn } from "node:child_process";
|
|
281672
281880
|
import { createRequire as createRequire2 } from "node:module";
|
|
281673
281881
|
function sanitizeForTTS(text) {
|
|
@@ -281691,40 +281899,40 @@ function listVoiceModels() {
|
|
|
281691
281899
|
}));
|
|
281692
281900
|
}
|
|
281693
281901
|
function voiceDir() {
|
|
281694
|
-
return
|
|
281902
|
+
return join64(homedir19(), ".open-agents", "voice");
|
|
281695
281903
|
}
|
|
281696
281904
|
function modelsDir() {
|
|
281697
|
-
return
|
|
281905
|
+
return join64(voiceDir(), "models");
|
|
281698
281906
|
}
|
|
281699
281907
|
function modelDir(id) {
|
|
281700
|
-
return
|
|
281908
|
+
return join64(modelsDir(), id);
|
|
281701
281909
|
}
|
|
281702
281910
|
function modelOnnxPath(id) {
|
|
281703
|
-
return
|
|
281911
|
+
return join64(modelDir(id), "model.onnx");
|
|
281704
281912
|
}
|
|
281705
281913
|
function modelConfigPath(id) {
|
|
281706
|
-
return
|
|
281914
|
+
return join64(modelDir(id), "config.json");
|
|
281707
281915
|
}
|
|
281708
281916
|
function luxttsVenvDir() {
|
|
281709
|
-
return
|
|
281917
|
+
return join64(voiceDir(), "luxtts-venv");
|
|
281710
281918
|
}
|
|
281711
281919
|
function luxttsVenvPy() {
|
|
281712
|
-
return platform3() === "win32" ?
|
|
281920
|
+
return platform3() === "win32" ? join64(luxttsVenvDir(), "Scripts", "python.exe") : join64(luxttsVenvDir(), "bin", "python3");
|
|
281713
281921
|
}
|
|
281714
281922
|
function luxttsRepoDir() {
|
|
281715
|
-
return
|
|
281923
|
+
return join64(voiceDir(), "LuxTTS");
|
|
281716
281924
|
}
|
|
281717
281925
|
function luxttsCloneRefsDir() {
|
|
281718
|
-
return
|
|
281926
|
+
return join64(voiceDir(), "clone-refs");
|
|
281719
281927
|
}
|
|
281720
281928
|
function luxttsInferScript() {
|
|
281721
|
-
return
|
|
281929
|
+
return join64(voiceDir(), "luxtts-infer.py");
|
|
281722
281930
|
}
|
|
281723
281931
|
function writeDetectTorchScript(targetPath) {
|
|
281724
|
-
if (
|
|
281932
|
+
if (existsSync48(targetPath))
|
|
281725
281933
|
return;
|
|
281726
281934
|
try {
|
|
281727
|
-
|
|
281935
|
+
mkdirSync21(dirname21(targetPath), { recursive: true });
|
|
281728
281936
|
} catch {
|
|
281729
281937
|
}
|
|
281730
281938
|
const script = `#!/usr/bin/env python3
|
|
@@ -281797,7 +282005,7 @@ def main():
|
|
|
281797
282005
|
if __name__ == "__main__": main()
|
|
281798
282006
|
`;
|
|
281799
282007
|
try {
|
|
281800
|
-
|
|
282008
|
+
writeFileSync22(targetPath, script, { mode: 493 });
|
|
281801
282009
|
} catch {
|
|
281802
282010
|
}
|
|
281803
282011
|
}
|
|
@@ -282608,8 +282816,8 @@ var init_voice = __esm({
|
|
|
282608
282816
|
const refsDir = luxttsCloneRefsDir();
|
|
282609
282817
|
const targets = ["glados", "overwatch"];
|
|
282610
282818
|
for (const modelId of targets) {
|
|
282611
|
-
const refFile =
|
|
282612
|
-
if (
|
|
282819
|
+
const refFile = join64(refsDir, `${modelId}-ref.wav`);
|
|
282820
|
+
if (existsSync48(refFile))
|
|
282613
282821
|
continue;
|
|
282614
282822
|
try {
|
|
282615
282823
|
await this.generateCloneRef(modelId);
|
|
@@ -282688,24 +282896,24 @@ var init_voice = __esm({
|
|
|
282688
282896
|
}
|
|
282689
282897
|
p2 = p2.replace(/\\ /g, " ");
|
|
282690
282898
|
if (p2.startsWith("~/") || p2 === "~") {
|
|
282691
|
-
p2 =
|
|
282899
|
+
p2 = join64(homedir19(), p2.slice(1));
|
|
282692
282900
|
}
|
|
282693
|
-
if (!
|
|
282901
|
+
if (!existsSync48(p2)) {
|
|
282694
282902
|
return `File not found: ${p2}
|
|
282695
282903
|
(original input: ${audioPath})`;
|
|
282696
282904
|
}
|
|
282697
282905
|
audioPath = p2;
|
|
282698
282906
|
const refsDir = luxttsCloneRefsDir();
|
|
282699
|
-
if (!
|
|
282700
|
-
|
|
282907
|
+
if (!existsSync48(refsDir))
|
|
282908
|
+
mkdirSync21(refsDir, { recursive: true });
|
|
282701
282909
|
const ext = audioPath.split(".").pop() || "wav";
|
|
282702
282910
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
282703
282911
|
const ts = Date.now().toString(36);
|
|
282704
282912
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
282705
|
-
const destPath =
|
|
282913
|
+
const destPath = join64(refsDir, destFilename);
|
|
282706
282914
|
try {
|
|
282707
|
-
const data =
|
|
282708
|
-
|
|
282915
|
+
const data = readFileSync36(audioPath);
|
|
282916
|
+
writeFileSync22(destPath, data);
|
|
282709
282917
|
} catch (err) {
|
|
282710
282918
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
282711
282919
|
}
|
|
@@ -282745,9 +282953,9 @@ var init_voice = __esm({
|
|
|
282745
282953
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
282746
282954
|
}
|
|
282747
282955
|
const refsDir = luxttsCloneRefsDir();
|
|
282748
|
-
if (!
|
|
282749
|
-
|
|
282750
|
-
const destPath =
|
|
282956
|
+
if (!existsSync48(refsDir))
|
|
282957
|
+
mkdirSync21(refsDir, { recursive: true });
|
|
282958
|
+
const destPath = join64(refsDir, `${sourceModelId}-ref.wav`);
|
|
282751
282959
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
282752
282960
|
this.writeWav(audioData, sampleRate, destPath);
|
|
282753
282961
|
this.luxttsCloneRef = destPath;
|
|
@@ -282763,23 +282971,23 @@ var init_voice = __esm({
|
|
|
282763
282971
|
// -------------------------------------------------------------------------
|
|
282764
282972
|
/** Metadata file for friendly names of clone refs */
|
|
282765
282973
|
static cloneMetaFile() {
|
|
282766
|
-
return
|
|
282974
|
+
return join64(luxttsCloneRefsDir(), "meta.json");
|
|
282767
282975
|
}
|
|
282768
282976
|
loadCloneMeta() {
|
|
282769
282977
|
const p2 = _VoiceEngine.cloneMetaFile();
|
|
282770
|
-
if (!
|
|
282978
|
+
if (!existsSync48(p2))
|
|
282771
282979
|
return {};
|
|
282772
282980
|
try {
|
|
282773
|
-
return JSON.parse(
|
|
282981
|
+
return JSON.parse(readFileSync36(p2, "utf8"));
|
|
282774
282982
|
} catch {
|
|
282775
282983
|
return {};
|
|
282776
282984
|
}
|
|
282777
282985
|
}
|
|
282778
282986
|
saveCloneMeta(meta) {
|
|
282779
282987
|
const dir = luxttsCloneRefsDir();
|
|
282780
|
-
if (!
|
|
282781
|
-
|
|
282782
|
-
|
|
282988
|
+
if (!existsSync48(dir))
|
|
282989
|
+
mkdirSync21(dir, { recursive: true });
|
|
282990
|
+
writeFileSync22(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
282783
282991
|
}
|
|
282784
282992
|
/** Audio file extensions recognized as clone references */
|
|
282785
282993
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -282789,7 +282997,7 @@ var init_voice = __esm({
|
|
|
282789
282997
|
*/
|
|
282790
282998
|
listCloneRefs() {
|
|
282791
282999
|
const dir = luxttsCloneRefsDir();
|
|
282792
|
-
if (!
|
|
283000
|
+
if (!existsSync48(dir))
|
|
282793
283001
|
return [];
|
|
282794
283002
|
const meta = this.loadCloneMeta();
|
|
282795
283003
|
const files = readdirSync13(dir).filter((f2) => {
|
|
@@ -282797,7 +283005,7 @@ var init_voice = __esm({
|
|
|
282797
283005
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
282798
283006
|
});
|
|
282799
283007
|
return files.map((f2) => {
|
|
282800
|
-
const p2 =
|
|
283008
|
+
const p2 = join64(dir, f2);
|
|
282801
283009
|
let size = 0;
|
|
282802
283010
|
try {
|
|
282803
283011
|
size = statSync14(p2).size;
|
|
@@ -282814,11 +283022,11 @@ var init_voice = __esm({
|
|
|
282814
283022
|
}
|
|
282815
283023
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
282816
283024
|
deleteCloneRef(filename) {
|
|
282817
|
-
const p2 =
|
|
282818
|
-
if (!
|
|
283025
|
+
const p2 = join64(luxttsCloneRefsDir(), filename);
|
|
283026
|
+
if (!existsSync48(p2))
|
|
282819
283027
|
return false;
|
|
282820
283028
|
try {
|
|
282821
|
-
|
|
283029
|
+
unlinkSync10(p2);
|
|
282822
283030
|
const meta = this.loadCloneMeta();
|
|
282823
283031
|
delete meta[filename];
|
|
282824
283032
|
this.saveCloneMeta(meta);
|
|
@@ -282839,8 +283047,8 @@ var init_voice = __esm({
|
|
|
282839
283047
|
}
|
|
282840
283048
|
/** Set the active clone reference by filename. */
|
|
282841
283049
|
setActiveCloneRef(filename) {
|
|
282842
|
-
const p2 =
|
|
282843
|
-
if (!
|
|
283050
|
+
const p2 = join64(luxttsCloneRefsDir(), filename);
|
|
283051
|
+
if (!existsSync48(p2))
|
|
282844
283052
|
return `File not found: ${filename}`;
|
|
282845
283053
|
this.luxttsCloneRef = p2;
|
|
282846
283054
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -283096,7 +283304,7 @@ var init_voice = __esm({
|
|
|
283096
283304
|
}
|
|
283097
283305
|
if (prefetchedWav) {
|
|
283098
283306
|
try {
|
|
283099
|
-
|
|
283307
|
+
unlinkSync10(prefetchedWav.path);
|
|
283100
283308
|
} catch {
|
|
283101
283309
|
}
|
|
283102
283310
|
}
|
|
@@ -283165,11 +283373,11 @@ var init_voice = __esm({
|
|
|
283165
283373
|
}
|
|
283166
283374
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
283167
283375
|
}
|
|
283168
|
-
const wavPath =
|
|
283376
|
+
const wavPath = join64(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
283169
283377
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
283170
283378
|
await this.playWav(wavPath);
|
|
283171
283379
|
try {
|
|
283172
|
-
|
|
283380
|
+
unlinkSync10(wavPath);
|
|
283173
283381
|
} catch {
|
|
283174
283382
|
}
|
|
283175
283383
|
}
|
|
@@ -283282,7 +283490,7 @@ var init_voice = __esm({
|
|
|
283282
283490
|
buffer2.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
|
|
283283
283491
|
pos += 2;
|
|
283284
283492
|
}
|
|
283285
|
-
|
|
283493
|
+
writeFileSync22(path5, buffer2);
|
|
283286
283494
|
}
|
|
283287
283495
|
// -------------------------------------------------------------------------
|
|
283288
283496
|
// Phonemization
|
|
@@ -283360,7 +283568,7 @@ var init_voice = __esm({
|
|
|
283360
283568
|
return buffer2;
|
|
283361
283569
|
}
|
|
283362
283570
|
writeWav(samples, sampleRate, path5) {
|
|
283363
|
-
|
|
283571
|
+
writeFileSync22(path5, this.buildWavBuffer(samples, sampleRate));
|
|
283364
283572
|
}
|
|
283365
283573
|
// -------------------------------------------------------------------------
|
|
283366
283574
|
// Audio playback (system default speakers)
|
|
@@ -283558,7 +283766,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283558
283766
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
283559
283767
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
283560
283768
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
283561
|
-
const wavPath =
|
|
283769
|
+
const wavPath = join64(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
283562
283770
|
const pyScript = [
|
|
283563
283771
|
"import sys, json",
|
|
283564
283772
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -283575,11 +283783,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283575
283783
|
return;
|
|
283576
283784
|
}
|
|
283577
283785
|
}
|
|
283578
|
-
if (!
|
|
283786
|
+
if (!existsSync48(wavPath))
|
|
283579
283787
|
return;
|
|
283580
283788
|
if (volume !== 1) {
|
|
283581
283789
|
try {
|
|
283582
|
-
const wavData =
|
|
283790
|
+
const wavData = readFileSync36(wavPath);
|
|
283583
283791
|
if (wavData.length > 44) {
|
|
283584
283792
|
const header = wavData.subarray(0, 44);
|
|
283585
283793
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -283587,14 +283795,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283587
283795
|
samples[i2] = Math.round(samples[i2] * volume);
|
|
283588
283796
|
}
|
|
283589
283797
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
283590
|
-
|
|
283798
|
+
writeFileSync22(wavPath, scaled);
|
|
283591
283799
|
}
|
|
283592
283800
|
} catch {
|
|
283593
283801
|
}
|
|
283594
283802
|
}
|
|
283595
283803
|
if (this.onPCMOutput) {
|
|
283596
283804
|
try {
|
|
283597
|
-
const wavData =
|
|
283805
|
+
const wavData = readFileSync36(wavPath);
|
|
283598
283806
|
if (wavData.length > 44) {
|
|
283599
283807
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
283600
283808
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -283605,7 +283813,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283605
283813
|
}
|
|
283606
283814
|
await this.playWav(wavPath);
|
|
283607
283815
|
try {
|
|
283608
|
-
|
|
283816
|
+
unlinkSync10(wavPath);
|
|
283609
283817
|
} catch {
|
|
283610
283818
|
}
|
|
283611
283819
|
}
|
|
@@ -283626,7 +283834,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283626
283834
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
283627
283835
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
283628
283836
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
283629
|
-
const wavPath =
|
|
283837
|
+
const wavPath = join64(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
283630
283838
|
const pyScript = [
|
|
283631
283839
|
"import sys, json",
|
|
283632
283840
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -283643,11 +283851,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283643
283851
|
return null;
|
|
283644
283852
|
}
|
|
283645
283853
|
}
|
|
283646
|
-
if (!
|
|
283854
|
+
if (!existsSync48(wavPath))
|
|
283647
283855
|
return null;
|
|
283648
283856
|
try {
|
|
283649
|
-
const data =
|
|
283650
|
-
|
|
283857
|
+
const data = readFileSync36(wavPath);
|
|
283858
|
+
unlinkSync10(wavPath);
|
|
283651
283859
|
return data;
|
|
283652
283860
|
} catch {
|
|
283653
283861
|
return null;
|
|
@@ -283669,7 +283877,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283669
283877
|
}
|
|
283670
283878
|
const venvDir = luxttsVenvDir();
|
|
283671
283879
|
const venvPy = luxttsVenvPy();
|
|
283672
|
-
if (
|
|
283880
|
+
if (existsSync48(venvPy)) {
|
|
283673
283881
|
try {
|
|
283674
283882
|
const quotedPy = `"${venvPy}"`;
|
|
283675
283883
|
const repoPath = luxttsRepoDir().replace(/\\/g, "/");
|
|
@@ -283685,7 +283893,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283685
283893
|
if (torchCheck === "cpu") {
|
|
283686
283894
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
283687
283895
|
try {
|
|
283688
|
-
const detectScript =
|
|
283896
|
+
const detectScript = join64(voiceDir(), "detect-torch.py");
|
|
283689
283897
|
writeDetectTorchScript(detectScript);
|
|
283690
283898
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
283691
283899
|
try {
|
|
@@ -283710,7 +283918,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283710
283918
|
}
|
|
283711
283919
|
}
|
|
283712
283920
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
283713
|
-
if (!
|
|
283921
|
+
if (!existsSync48(venvDir)) {
|
|
283714
283922
|
renderInfo(" Creating Python virtual environment...");
|
|
283715
283923
|
try {
|
|
283716
283924
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -283719,7 +283927,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283719
283927
|
}
|
|
283720
283928
|
}
|
|
283721
283929
|
{
|
|
283722
|
-
const detectScript =
|
|
283930
|
+
const detectScript = join64(voiceDir(), "detect-torch.py");
|
|
283723
283931
|
writeDetectTorchScript(detectScript);
|
|
283724
283932
|
let pipArgsStr = "torch torchaudio";
|
|
283725
283933
|
let torchDesc = "unknown platform";
|
|
@@ -283756,10 +283964,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283756
283964
|
}
|
|
283757
283965
|
}
|
|
283758
283966
|
const repoDir = luxttsRepoDir();
|
|
283759
|
-
if (!
|
|
283967
|
+
if (!existsSync48(join64(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
283760
283968
|
renderInfo(" Cloning LuxTTS repository...");
|
|
283761
283969
|
try {
|
|
283762
|
-
if (
|
|
283970
|
+
if (existsSync48(repoDir)) {
|
|
283763
283971
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
283764
283972
|
await this.asyncShell(rmCmd, 3e4);
|
|
283765
283973
|
}
|
|
@@ -283838,7 +284046,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283838
284046
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
283839
284047
|
}
|
|
283840
284048
|
}
|
|
283841
|
-
const isJetson = isArm && (
|
|
284049
|
+
const isJetson = isArm && (existsSync48("/etc/nv_tegra_release") || existsSync48("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
283842
284050
|
const installSteps = isArm ? [
|
|
283843
284051
|
// ARM: install individually so we get clear error messages per package.
|
|
283844
284052
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -283908,14 +284116,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
283908
284116
|
}
|
|
283909
284117
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
283910
284118
|
autoDetectCloneRef() {
|
|
283911
|
-
if (this.luxttsCloneRef &&
|
|
284119
|
+
if (this.luxttsCloneRef && existsSync48(this.luxttsCloneRef))
|
|
283912
284120
|
return;
|
|
283913
284121
|
const refsDir = luxttsCloneRefsDir();
|
|
283914
|
-
if (!
|
|
284122
|
+
if (!existsSync48(refsDir))
|
|
283915
284123
|
return;
|
|
283916
284124
|
for (const name10 of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
283917
|
-
const p2 =
|
|
283918
|
-
if (
|
|
284125
|
+
const p2 = join64(refsDir, name10);
|
|
284126
|
+
if (existsSync48(p2)) {
|
|
283919
284127
|
this.luxttsCloneRef = p2;
|
|
283920
284128
|
return;
|
|
283921
284129
|
}
|
|
@@ -284015,15 +284223,15 @@ if __name__ == '__main__':
|
|
|
284015
284223
|
main()
|
|
284016
284224
|
`;
|
|
284017
284225
|
const scriptPath2 = luxttsInferScript();
|
|
284018
|
-
|
|
284019
|
-
|
|
284226
|
+
mkdirSync21(voiceDir(), { recursive: true });
|
|
284227
|
+
writeFileSync22(scriptPath2, script);
|
|
284020
284228
|
}
|
|
284021
284229
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
284022
284230
|
async ensureLuxttsDaemon() {
|
|
284023
284231
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
284024
284232
|
return true;
|
|
284025
284233
|
const venvPy = luxttsVenvPy();
|
|
284026
|
-
if (!
|
|
284234
|
+
if (!existsSync48(venvPy))
|
|
284027
284235
|
return false;
|
|
284028
284236
|
return new Promise((resolve39) => {
|
|
284029
284237
|
const env2 = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
@@ -284116,7 +284324,7 @@ if __name__ == '__main__':
|
|
|
284116
284324
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
284117
284325
|
*/
|
|
284118
284326
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
284119
|
-
if (!this.luxttsCloneRef || !
|
|
284327
|
+
if (!this.luxttsCloneRef || !existsSync48(this.luxttsCloneRef))
|
|
284120
284328
|
return null;
|
|
284121
284329
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
284122
284330
|
if (!cleaned)
|
|
@@ -284124,7 +284332,7 @@ if __name__ == '__main__':
|
|
|
284124
284332
|
const ready = await this.ensureLuxttsDaemon();
|
|
284125
284333
|
if (!ready)
|
|
284126
284334
|
return null;
|
|
284127
|
-
const wavPath =
|
|
284335
|
+
const wavPath = join64(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
284128
284336
|
try {
|
|
284129
284337
|
await this.luxttsRequest({
|
|
284130
284338
|
action: "synthesize",
|
|
@@ -284136,17 +284344,17 @@ if __name__ == '__main__':
|
|
|
284136
284344
|
} catch {
|
|
284137
284345
|
return null;
|
|
284138
284346
|
}
|
|
284139
|
-
return
|
|
284347
|
+
return existsSync48(wavPath) ? wavPath : null;
|
|
284140
284348
|
}
|
|
284141
284349
|
/**
|
|
284142
284350
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
284143
284351
|
* Cleans up the WAV file after playback.
|
|
284144
284352
|
*/
|
|
284145
284353
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
284146
|
-
if (!
|
|
284354
|
+
if (!existsSync48(wavPath))
|
|
284147
284355
|
return;
|
|
284148
284356
|
try {
|
|
284149
|
-
const wavData =
|
|
284357
|
+
const wavData = readFileSync36(wavPath);
|
|
284150
284358
|
if (wavData.length > 44) {
|
|
284151
284359
|
const sampleRate = wavData.readUInt32LE(24);
|
|
284152
284360
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -284161,13 +284369,13 @@ if __name__ == '__main__':
|
|
|
284161
284369
|
}
|
|
284162
284370
|
const header = wavData.subarray(0, 44);
|
|
284163
284371
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
284164
|
-
|
|
284372
|
+
writeFileSync22(wavPath, scaled);
|
|
284165
284373
|
}
|
|
284166
284374
|
} catch {
|
|
284167
284375
|
}
|
|
284168
284376
|
if (pitchFactor !== 1) {
|
|
284169
284377
|
try {
|
|
284170
|
-
const wavData =
|
|
284378
|
+
const wavData = readFileSync36(wavPath);
|
|
284171
284379
|
if (wavData.length > 44) {
|
|
284172
284380
|
const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
284173
284381
|
const float32 = new Float32Array(int16.length);
|
|
@@ -284182,7 +284390,7 @@ if __name__ == '__main__':
|
|
|
284182
284390
|
}
|
|
284183
284391
|
if (this.onPCMOutput) {
|
|
284184
284392
|
try {
|
|
284185
|
-
const wavData =
|
|
284393
|
+
const wavData = readFileSync36(wavPath);
|
|
284186
284394
|
if (wavData.length > 44) {
|
|
284187
284395
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
284188
284396
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -284193,7 +284401,7 @@ if __name__ == '__main__':
|
|
|
284193
284401
|
}
|
|
284194
284402
|
if (stereoDelayMs > 0) {
|
|
284195
284403
|
try {
|
|
284196
|
-
const wavData =
|
|
284404
|
+
const wavData = readFileSync36(wavPath);
|
|
284197
284405
|
if (wavData.length > 44) {
|
|
284198
284406
|
const sampleRate = wavData.readUInt32LE(24);
|
|
284199
284407
|
const numChannels = wavData.readUInt16LE(22);
|
|
@@ -284213,7 +284421,7 @@ if __name__ == '__main__':
|
|
|
284213
284421
|
await this.playWav(wavPath);
|
|
284214
284422
|
await this.sleep(150);
|
|
284215
284423
|
try {
|
|
284216
|
-
|
|
284424
|
+
unlinkSync10(wavPath);
|
|
284217
284425
|
} catch {
|
|
284218
284426
|
}
|
|
284219
284427
|
}
|
|
@@ -284229,7 +284437,7 @@ if __name__ == '__main__':
|
|
|
284229
284437
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
284230
284438
|
*/
|
|
284231
284439
|
async synthesizeLuxttsToBuffer(text) {
|
|
284232
|
-
if (!this.luxttsCloneRef || !
|
|
284440
|
+
if (!this.luxttsCloneRef || !existsSync48(this.luxttsCloneRef))
|
|
284233
284441
|
return null;
|
|
284234
284442
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
284235
284443
|
if (!cleaned)
|
|
@@ -284237,7 +284445,7 @@ if __name__ == '__main__':
|
|
|
284237
284445
|
const ready = await this.ensureLuxttsDaemon();
|
|
284238
284446
|
if (!ready)
|
|
284239
284447
|
return null;
|
|
284240
|
-
const wavPath =
|
|
284448
|
+
const wavPath = join64(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
284241
284449
|
try {
|
|
284242
284450
|
await this.luxttsRequest({
|
|
284243
284451
|
action: "synthesize",
|
|
@@ -284249,11 +284457,11 @@ if __name__ == '__main__':
|
|
|
284249
284457
|
} catch {
|
|
284250
284458
|
return null;
|
|
284251
284459
|
}
|
|
284252
|
-
if (!
|
|
284460
|
+
if (!existsSync48(wavPath))
|
|
284253
284461
|
return null;
|
|
284254
284462
|
try {
|
|
284255
|
-
const data =
|
|
284256
|
-
|
|
284463
|
+
const data = readFileSync36(wavPath);
|
|
284464
|
+
unlinkSync10(wavPath);
|
|
284257
284465
|
return data;
|
|
284258
284466
|
} catch {
|
|
284259
284467
|
return null;
|
|
@@ -284266,40 +284474,40 @@ if __name__ == '__main__':
|
|
|
284266
284474
|
if (this.ort)
|
|
284267
284475
|
return;
|
|
284268
284476
|
const arch2 = process.arch;
|
|
284269
|
-
|
|
284270
|
-
const pkgPath =
|
|
284477
|
+
mkdirSync21(voiceDir(), { recursive: true });
|
|
284478
|
+
const pkgPath = join64(voiceDir(), "package.json");
|
|
284271
284479
|
const expectedDeps = {
|
|
284272
284480
|
"onnxruntime-node": "^1.21.0",
|
|
284273
284481
|
"phonemizer": "^1.2.1"
|
|
284274
284482
|
};
|
|
284275
|
-
if (
|
|
284483
|
+
if (existsSync48(pkgPath)) {
|
|
284276
284484
|
try {
|
|
284277
|
-
const existing = JSON.parse(
|
|
284485
|
+
const existing = JSON.parse(readFileSync36(pkgPath, "utf8"));
|
|
284278
284486
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
284279
284487
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
284280
|
-
|
|
284488
|
+
writeFileSync22(pkgPath, JSON.stringify(existing, null, 2));
|
|
284281
284489
|
}
|
|
284282
284490
|
} catch {
|
|
284283
284491
|
}
|
|
284284
284492
|
}
|
|
284285
|
-
if (!
|
|
284286
|
-
|
|
284493
|
+
if (!existsSync48(pkgPath)) {
|
|
284494
|
+
writeFileSync22(pkgPath, JSON.stringify({
|
|
284287
284495
|
name: "open-agents-voice",
|
|
284288
284496
|
private: true,
|
|
284289
284497
|
dependencies: expectedDeps
|
|
284290
284498
|
}, null, 2));
|
|
284291
284499
|
}
|
|
284292
|
-
const voiceRequire = createRequire2(
|
|
284500
|
+
const voiceRequire = createRequire2(join64(voiceDir(), "index.js"));
|
|
284293
284501
|
const probeOnnx = async () => {
|
|
284294
284502
|
try {
|
|
284295
|
-
const output = await this.asyncShell(`NODE_PATH="${
|
|
284503
|
+
const output = await this.asyncShell(`NODE_PATH="${join64(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
|
|
284296
284504
|
return output.trim() === "OK";
|
|
284297
284505
|
} catch {
|
|
284298
284506
|
return false;
|
|
284299
284507
|
}
|
|
284300
284508
|
};
|
|
284301
|
-
const onnxNodeModules =
|
|
284302
|
-
const onnxInstalled =
|
|
284509
|
+
const onnxNodeModules = join64(voiceDir(), "node_modules", "onnxruntime-node");
|
|
284510
|
+
const onnxInstalled = existsSync48(onnxNodeModules);
|
|
284303
284511
|
if (onnxInstalled && !await probeOnnx()) {
|
|
284304
284512
|
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.`);
|
|
284305
284513
|
}
|
|
@@ -284349,18 +284557,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
284349
284557
|
const dir = modelDir(id);
|
|
284350
284558
|
const onnxPath = modelOnnxPath(id);
|
|
284351
284559
|
const configPath2 = modelConfigPath(id);
|
|
284352
|
-
if (
|
|
284560
|
+
if (existsSync48(onnxPath) && existsSync48(configPath2))
|
|
284353
284561
|
return;
|
|
284354
|
-
|
|
284355
|
-
if (!
|
|
284562
|
+
mkdirSync21(dir, { recursive: true });
|
|
284563
|
+
if (!existsSync48(configPath2)) {
|
|
284356
284564
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
284357
284565
|
const configResp = await fetch(model.configUrl);
|
|
284358
284566
|
if (!configResp.ok)
|
|
284359
284567
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
284360
284568
|
const configText = await configResp.text();
|
|
284361
|
-
|
|
284569
|
+
writeFileSync22(configPath2, configText);
|
|
284362
284570
|
}
|
|
284363
|
-
if (!
|
|
284571
|
+
if (!existsSync48(onnxPath)) {
|
|
284364
284572
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
284365
284573
|
const onnxResp = await fetch(model.onnxUrl);
|
|
284366
284574
|
if (!onnxResp.ok)
|
|
@@ -284385,7 +284593,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
284385
284593
|
}
|
|
284386
284594
|
}
|
|
284387
284595
|
const fullBuffer = Buffer.concat(chunks);
|
|
284388
|
-
|
|
284596
|
+
writeFileSync22(onnxPath, fullBuffer);
|
|
284389
284597
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
284390
284598
|
}
|
|
284391
284599
|
}
|
|
@@ -284397,10 +284605,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
284397
284605
|
throw new Error("ONNX runtime not loaded");
|
|
284398
284606
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
284399
284607
|
const configPath2 = modelConfigPath(this.modelId);
|
|
284400
|
-
if (!
|
|
284608
|
+
if (!existsSync48(onnxPath) || !existsSync48(configPath2)) {
|
|
284401
284609
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
284402
284610
|
}
|
|
284403
|
-
this.config = JSON.parse(
|
|
284611
|
+
this.config = JSON.parse(readFileSync36(configPath2, "utf8"));
|
|
284404
284612
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
284405
284613
|
executionProviders: ["cpu"],
|
|
284406
284614
|
graphOptimizationLevel: "all"
|
|
@@ -284427,8 +284635,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
284427
284635
|
// packages/cli/dist/tui/commands.js
|
|
284428
284636
|
import * as nodeOs from "node:os";
|
|
284429
284637
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
284430
|
-
import { existsSync as
|
|
284431
|
-
import { join as
|
|
284638
|
+
import { existsSync as existsSync49, readFileSync as readFileSync37, writeFileSync as writeFileSync23, mkdirSync as mkdirSync22, readdirSync as readdirSync14, statSync as statSync15, rmSync as rmSync2, appendFileSync as appendFileSync3 } from "node:fs";
|
|
284639
|
+
import { join as join65 } from "node:path";
|
|
284432
284640
|
async function _immediateReregister(newUrl) {
|
|
284433
284641
|
if (!_lastRegisteredSponsorPayload)
|
|
284434
284642
|
return;
|
|
@@ -284929,9 +285137,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
284929
285137
|
if (out.includes("Connected") || out.includes("Already connected")) {
|
|
284930
285138
|
renderInfo(out.split("\n").slice(0, 4).join("\n"));
|
|
284931
285139
|
try {
|
|
284932
|
-
const pidFile =
|
|
284933
|
-
if (
|
|
284934
|
-
const pid = parseInt(
|
|
285140
|
+
const pidFile = join65(ctx3.repoRoot ?? process.cwd(), ".oa", "nexus", "daemon.pid");
|
|
285141
|
+
if (existsSync49(pidFile)) {
|
|
285142
|
+
const pid = parseInt(readFileSync37(pidFile, "utf8").trim(), 10);
|
|
284935
285143
|
if (pid > 0 && !registry2.daemons.has("Nexus")) {
|
|
284936
285144
|
registry2.register({ name: "Nexus", pid, startedAt: Date.now(), status: "running" });
|
|
284937
285145
|
}
|
|
@@ -284971,9 +285179,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
284971
285179
|
renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
|
|
284972
285180
|
}
|
|
284973
285181
|
} else if (sub === "name") {
|
|
284974
|
-
const { homedir:
|
|
285182
|
+
const { homedir: homedir26 } = __require("node:os");
|
|
284975
285183
|
const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
|
|
284976
|
-
const namePath = __require("node:path").join(
|
|
285184
|
+
const namePath = __require("node:path").join(homedir26(), ".open-agents", "agent-name");
|
|
284977
285185
|
if (rest2) {
|
|
284978
285186
|
const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
|
|
284979
285187
|
if (!customName) {
|
|
@@ -285166,7 +285374,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285166
285374
|
const ipfsSubCmd = (arg || "").trim().split(/\s+/);
|
|
285167
285375
|
const ipfsAction = ipfsSubCmd[0]?.toLowerCase() || "";
|
|
285168
285376
|
const ipfsArg = ipfsSubCmd.slice(1).join(" ");
|
|
285169
|
-
const
|
|
285377
|
+
const ensureDaemon2 = async () => {
|
|
285170
285378
|
try {
|
|
285171
285379
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
285172
285380
|
const statusResult = await nexus.execute({ action: "status" });
|
|
@@ -285192,7 +285400,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285192
285400
|
return "handled";
|
|
285193
285401
|
}
|
|
285194
285402
|
try {
|
|
285195
|
-
if (!await
|
|
285403
|
+
if (!await ensureDaemon2())
|
|
285196
285404
|
return "handled";
|
|
285197
285405
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
285198
285406
|
const result = await nexus.execute({ action: "ipfs_pin", cid: cidToPin, source: "user-pin" });
|
|
@@ -285239,22 +285447,22 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285239
285447
|
let content = "";
|
|
285240
285448
|
let metadata = {};
|
|
285241
285449
|
if (shareType === "tool") {
|
|
285242
|
-
const toolDir =
|
|
285243
|
-
const toolFile =
|
|
285244
|
-
if (!
|
|
285450
|
+
const toolDir = join65(ctx3.repoRoot, ".oa", "tools");
|
|
285451
|
+
const toolFile = join65(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
285452
|
+
if (!existsSync49(toolFile)) {
|
|
285245
285453
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
285246
285454
|
return "handled";
|
|
285247
285455
|
}
|
|
285248
|
-
content =
|
|
285456
|
+
content = readFileSync37(toolFile, "utf8");
|
|
285249
285457
|
metadata = { type: "tool", name: shareName };
|
|
285250
285458
|
} else if (shareType === "skill") {
|
|
285251
|
-
const skillDir =
|
|
285252
|
-
const skillFile =
|
|
285253
|
-
if (!
|
|
285459
|
+
const skillDir = join65(ctx3.repoRoot, ".oa", "skills", shareName);
|
|
285460
|
+
const skillFile = join65(skillDir, "SKILL.md");
|
|
285461
|
+
if (!existsSync49(skillFile)) {
|
|
285254
285462
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
285255
285463
|
return "handled";
|
|
285256
285464
|
}
|
|
285257
|
-
content =
|
|
285465
|
+
content = readFileSync37(skillFile, "utf8");
|
|
285258
285466
|
metadata = { type: "skill", name: shareName };
|
|
285259
285467
|
} else {
|
|
285260
285468
|
renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
|
|
@@ -285291,9 +285499,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285291
285499
|
try {
|
|
285292
285500
|
const nexus = new NexusTool(ctx3.repoRoot);
|
|
285293
285501
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
285294
|
-
const regFile =
|
|
285295
|
-
if (
|
|
285296
|
-
const reg = JSON.parse(
|
|
285502
|
+
const regFile = join65(ctx3.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
285503
|
+
if (existsSync49(regFile)) {
|
|
285504
|
+
const reg = JSON.parse(readFileSync37(regFile, "utf8"));
|
|
285297
285505
|
const pinned = Object.values(reg).some((e2) => e2.cid === importCid && e2.pinned);
|
|
285298
285506
|
if (pinned) {
|
|
285299
285507
|
renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
|
|
@@ -285340,38 +285548,38 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285340
285548
|
}
|
|
285341
285549
|
return "handled";
|
|
285342
285550
|
}
|
|
285343
|
-
await
|
|
285551
|
+
await ensureDaemon2();
|
|
285344
285552
|
const lines = [];
|
|
285345
285553
|
lines.push(`
|
|
285346
285554
|
${c3.bold("IPFS / Helia Status")}
|
|
285347
285555
|
`);
|
|
285348
|
-
const ipfsDir =
|
|
285349
|
-
const ipfsLocalDir =
|
|
285556
|
+
const ipfsDir = join65(ctx3.repoRoot, ".oa", "ipfs");
|
|
285557
|
+
const ipfsLocalDir = join65(ipfsDir, "local");
|
|
285350
285558
|
let ipfsFiles = 0;
|
|
285351
285559
|
let ipfsBytes = 0;
|
|
285352
285560
|
let heliaBlocks = 0;
|
|
285353
285561
|
let heliaBytes = 0;
|
|
285354
285562
|
try {
|
|
285355
|
-
if (
|
|
285563
|
+
if (existsSync49(ipfsLocalDir)) {
|
|
285356
285564
|
const files = readdirSync14(ipfsLocalDir).filter((f2) => f2.endsWith(".json"));
|
|
285357
285565
|
ipfsFiles = files.length;
|
|
285358
285566
|
for (const f2 of files) {
|
|
285359
285567
|
try {
|
|
285360
|
-
ipfsBytes += statSync15(
|
|
285568
|
+
ipfsBytes += statSync15(join65(ipfsLocalDir, f2)).size;
|
|
285361
285569
|
} catch {
|
|
285362
285570
|
}
|
|
285363
285571
|
}
|
|
285364
285572
|
}
|
|
285365
|
-
const heliaBlockDir =
|
|
285366
|
-
if (
|
|
285573
|
+
const heliaBlockDir = join65(ipfsDir, "blocks");
|
|
285574
|
+
if (existsSync49(heliaBlockDir)) {
|
|
285367
285575
|
const walkDir = (dir) => {
|
|
285368
285576
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
285369
285577
|
if (entry.isDirectory())
|
|
285370
|
-
walkDir(
|
|
285578
|
+
walkDir(join65(dir, entry.name));
|
|
285371
285579
|
else {
|
|
285372
285580
|
heliaBlocks++;
|
|
285373
285581
|
try {
|
|
285374
|
-
heliaBytes += statSync15(
|
|
285582
|
+
heliaBytes += statSync15(join65(dir, entry.name)).size;
|
|
285375
285583
|
} catch {
|
|
285376
285584
|
}
|
|
285377
285585
|
}
|
|
@@ -285387,9 +285595,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285387
285595
|
lines.push(` Blocks: ${c3.bold(String(heliaBlocks))} Size: ${c3.bold(formatFileSize(heliaBytes))}`);
|
|
285388
285596
|
lines.push(` Backend: ${heliaBlocks > 0 ? c3.green("helia-ipfs") : c3.yellow("sha256-local (Helia not initialized)")}`);
|
|
285389
285597
|
try {
|
|
285390
|
-
const statusFile =
|
|
285391
|
-
if (
|
|
285392
|
-
const status = JSON.parse(
|
|
285598
|
+
const statusFile = join65(ctx3.repoRoot, ".oa", "nexus", "status.json");
|
|
285599
|
+
if (existsSync49(statusFile)) {
|
|
285600
|
+
const status = JSON.parse(readFileSync37(statusFile, "utf8"));
|
|
285393
285601
|
if (status.peerId) {
|
|
285394
285602
|
lines.push(`
|
|
285395
285603
|
${c3.bold("Peer Info")}`);
|
|
@@ -285408,11 +285616,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285408
285616
|
${c3.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
285409
285617
|
lines.push(`
|
|
285410
285618
|
${c3.bold("Identity Kernel")}`);
|
|
285411
|
-
const idDir =
|
|
285619
|
+
const idDir = join65(ctx3.repoRoot, ".oa", "identity");
|
|
285412
285620
|
try {
|
|
285413
|
-
const stateFile =
|
|
285414
|
-
if (
|
|
285415
|
-
const state = JSON.parse(
|
|
285621
|
+
const stateFile = join65(idDir, "self-state.json");
|
|
285622
|
+
if (existsSync49(stateFile)) {
|
|
285623
|
+
const state = JSON.parse(readFileSync37(stateFile, "utf8"));
|
|
285416
285624
|
lines.push(` Version: ${c3.bold("v" + (state.version ?? "?"))} Sessions: ${c3.bold(String(state.session_count ?? 0))}`);
|
|
285417
285625
|
if (state.narrative_summary) {
|
|
285418
285626
|
lines.push(` Narrative: ${c3.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
|
|
@@ -285421,9 +285629,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285421
285629
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
285422
285630
|
lines.push(` Traits: ${c3.dim(traits.slice(0, 60))}`);
|
|
285423
285631
|
}
|
|
285424
|
-
const cidFile =
|
|
285425
|
-
if (
|
|
285426
|
-
const cids = JSON.parse(
|
|
285632
|
+
const cidFile = join65(idDir, "cids.json");
|
|
285633
|
+
if (existsSync49(cidFile)) {
|
|
285634
|
+
const cids = JSON.parse(readFileSync37(cidFile, "utf8"));
|
|
285427
285635
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
285428
285636
|
if (lastCid)
|
|
285429
285637
|
lines.push(` Last CID: ${c3.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -285436,9 +285644,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285436
285644
|
lines.push(`
|
|
285437
285645
|
${c3.bold("Memory Sentiment")}`);
|
|
285438
285646
|
try {
|
|
285439
|
-
const metaFile =
|
|
285440
|
-
if (
|
|
285441
|
-
const store2 = JSON.parse(
|
|
285647
|
+
const metaFile = join65(ctx3.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
285648
|
+
if (existsSync49(metaFile)) {
|
|
285649
|
+
const store2 = JSON.parse(readFileSync37(metaFile, "utf8"));
|
|
285442
285650
|
const active = store2.filter((m2) => m2.type !== "quarantine");
|
|
285443
285651
|
const recoveries = active.filter((m2) => m2.content?.startsWith("[recovery]")).length;
|
|
285444
285652
|
const strategies = active.filter((m2) => m2.content?.startsWith("[strategy]")).length;
|
|
@@ -285456,8 +285664,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285456
285664
|
} catch {
|
|
285457
285665
|
}
|
|
285458
285666
|
try {
|
|
285459
|
-
const dbPath =
|
|
285460
|
-
if (
|
|
285667
|
+
const dbPath = join65(ctx3.repoRoot, ".oa", "memory", "structured.db");
|
|
285668
|
+
if (existsSync49(dbPath)) {
|
|
285461
285669
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
285462
285670
|
const db = initDb2(dbPath);
|
|
285463
285671
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -285478,8 +285686,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285478
285686
|
lines.push(`
|
|
285479
285687
|
${c3.bold("Storage Overview")}
|
|
285480
285688
|
`);
|
|
285481
|
-
const oaDir =
|
|
285482
|
-
if (!
|
|
285689
|
+
const oaDir = join65(ctx3.repoRoot, ".oa");
|
|
285690
|
+
if (!existsSync49(oaDir)) {
|
|
285483
285691
|
lines.push(` ${c3.dim("No .oa/ directory found.")}`);
|
|
285484
285692
|
safeLog(lines.join("\n") + "\n");
|
|
285485
285693
|
return "handled";
|
|
@@ -285489,7 +285697,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285489
285697
|
const walkStorage = (dir, category) => {
|
|
285490
285698
|
try {
|
|
285491
285699
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
285492
|
-
const full =
|
|
285700
|
+
const full = join65(dir, entry.name);
|
|
285493
285701
|
if (entry.isDirectory()) {
|
|
285494
285702
|
const subCat = category || entry.name;
|
|
285495
285703
|
walkStorage(full, subCat);
|
|
@@ -285525,10 +285733,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285525
285733
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
285526
285734
|
const name10 = entry.name.toLowerCase();
|
|
285527
285735
|
if (sensitivePatterns.some((p2) => name10.includes(p2))) {
|
|
285528
|
-
sensitiveFound.push(
|
|
285736
|
+
sensitiveFound.push(join65(dir, entry.name).replace(oaDir + "/", ""));
|
|
285529
285737
|
}
|
|
285530
285738
|
if (entry.isDirectory())
|
|
285531
|
-
checkSensitive(
|
|
285739
|
+
checkSensitive(join65(dir, entry.name));
|
|
285532
285740
|
}
|
|
285533
285741
|
} catch {
|
|
285534
285742
|
}
|
|
@@ -285556,8 +285764,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285556
285764
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
285557
285765
|
return "handled";
|
|
285558
285766
|
}
|
|
285559
|
-
const resolvedPath =
|
|
285560
|
-
if (!
|
|
285767
|
+
const resolvedPath = join65(ctx3.repoRoot, filePath);
|
|
285768
|
+
if (!existsSync49(resolvedPath)) {
|
|
285561
285769
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
285562
285770
|
return "handled";
|
|
285563
285771
|
}
|
|
@@ -285573,9 +285781,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285573
285781
|
}
|
|
285574
285782
|
try {
|
|
285575
285783
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
285576
|
-
const dbDir =
|
|
285577
|
-
|
|
285578
|
-
const db = initDb2(
|
|
285784
|
+
const dbDir = join65(ctx3.repoRoot, ".oa", "memory");
|
|
285785
|
+
mkdirSync22(dbDir, { recursive: true });
|
|
285786
|
+
const db = initDb2(join65(dbDir, "structured.db"));
|
|
285579
285787
|
const memStore = new ProceduralMemoryStore2(db);
|
|
285580
285788
|
if (isAudio) {
|
|
285581
285789
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -285616,7 +285824,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285616
285824
|
return "handled";
|
|
285617
285825
|
}
|
|
285618
285826
|
} else {
|
|
285619
|
-
content =
|
|
285827
|
+
content = readFileSync37(resolvedPath, "utf8");
|
|
285620
285828
|
}
|
|
285621
285829
|
if (!content.trim()) {
|
|
285622
285830
|
renderWarning("No content extracted.");
|
|
@@ -285655,9 +285863,9 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285655
285863
|
}
|
|
285656
285864
|
case "fortemi": {
|
|
285657
285865
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
285658
|
-
const fortemiDir =
|
|
285659
|
-
const altFortemiDir =
|
|
285660
|
-
const fDir =
|
|
285866
|
+
const fortemiDir = join65(ctx3.repoRoot, "..", "fortemi-react");
|
|
285867
|
+
const altFortemiDir = join65(nodeOs.homedir(), "fortemi-react");
|
|
285868
|
+
const fDir = existsSync49(fortemiDir) ? fortemiDir : existsSync49(altFortemiDir) ? altFortemiDir : null;
|
|
285661
285869
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
285662
285870
|
if (!fDir) {
|
|
285663
285871
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -285672,14 +285880,14 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285672
285880
|
// 24h
|
|
285673
285881
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
285674
285882
|
};
|
|
285675
|
-
const jwtFile =
|
|
285676
|
-
|
|
285677
|
-
|
|
285883
|
+
const jwtFile = join65(ctx3.repoRoot, ".oa", "fortemi-jwt.json");
|
|
285884
|
+
mkdirSync22(join65(ctx3.repoRoot, ".oa"), { recursive: true });
|
|
285885
|
+
writeFileSync23(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
285678
285886
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
285679
285887
|
try {
|
|
285680
|
-
const { spawn:
|
|
285681
|
-
const child =
|
|
285682
|
-
cwd:
|
|
285888
|
+
const { spawn: spawn26 } = __require("node:child_process");
|
|
285889
|
+
const child = spawn26("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
285890
|
+
cwd: join65(fDir, "apps", "standalone"),
|
|
285683
285891
|
stdio: "ignore",
|
|
285684
285892
|
detached: true,
|
|
285685
285893
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -285688,8 +285896,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285688
285896
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
285689
285897
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
285690
285898
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
285691
|
-
const bridgeFile =
|
|
285692
|
-
|
|
285899
|
+
const bridgeFile = join65(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
285900
|
+
writeFileSync23(bridgeFile, JSON.stringify({
|
|
285693
285901
|
url: "http://localhost:3000",
|
|
285694
285902
|
pid: child.pid,
|
|
285695
285903
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -285701,12 +285909,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285701
285909
|
return "handled";
|
|
285702
285910
|
}
|
|
285703
285911
|
if (fortemiSubCmd === "status") {
|
|
285704
|
-
const bridgeFile =
|
|
285705
|
-
if (!
|
|
285912
|
+
const bridgeFile = join65(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
285913
|
+
if (!existsSync49(bridgeFile)) {
|
|
285706
285914
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
285707
285915
|
return "handled";
|
|
285708
285916
|
}
|
|
285709
|
-
const bridge = JSON.parse(
|
|
285917
|
+
const bridge = JSON.parse(readFileSync37(bridgeFile, "utf8"));
|
|
285710
285918
|
let alive = false;
|
|
285711
285919
|
try {
|
|
285712
285920
|
process.kill(bridge.pid, 0);
|
|
@@ -285726,15 +285934,15 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
285726
285934
|
lines.push(` Process: ${alive ? c3.green("running") : c3.yellow("not running")} (PID ${bridge.pid})`);
|
|
285727
285935
|
lines.push(` HTTP: ${httpOk ? c3.green("connected") : c3.yellow("unreachable")}`);
|
|
285728
285936
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
285729
|
-
lines.push(` JWT: ${
|
|
285937
|
+
lines.push(` JWT: ${existsSync49(bridge.jwtFile) ? c3.green("valid") : c3.yellow("missing")}`);
|
|
285730
285938
|
lines.push("");
|
|
285731
285939
|
safeLog(lines.join("\n"));
|
|
285732
285940
|
return "handled";
|
|
285733
285941
|
}
|
|
285734
285942
|
if (fortemiSubCmd === "stop") {
|
|
285735
|
-
const bridgeFile =
|
|
285736
|
-
if (
|
|
285737
|
-
const bridge = JSON.parse(
|
|
285943
|
+
const bridgeFile = join65(ctx3.repoRoot, ".oa", "fortemi-bridge.json");
|
|
285944
|
+
if (existsSync49(bridgeFile)) {
|
|
285945
|
+
const bridge = JSON.parse(readFileSync37(bridgeFile, "utf8"));
|
|
285738
285946
|
try {
|
|
285739
285947
|
process.kill(bridge.pid, "SIGTERM");
|
|
285740
285948
|
} catch {
|
|
@@ -286218,15 +286426,68 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
286218
286426
|
} else if (ctx3.isDreaming?.()) {
|
|
286219
286427
|
renderWarning("Already dreaming. Use /dream stop to wake up first.");
|
|
286220
286428
|
} else {
|
|
286221
|
-
const mode = arg === "lucid" ? "lucid" : arg === "deep" ? "deep" : "default";
|
|
286429
|
+
const mode = arg === "lucid" ? "lucid" : arg === "deep" ? "deep" : arg === "consolidate" ? "consolidate" : "default";
|
|
286222
286430
|
ctx3.dreamStart?.(mode);
|
|
286223
286431
|
}
|
|
286224
286432
|
return "handled";
|
|
286225
286433
|
}
|
|
286434
|
+
case "skillify": {
|
|
286435
|
+
const runner = ctx3.getRunner?.();
|
|
286436
|
+
if (!runner) {
|
|
286437
|
+
renderWarning("No active task session. Run a task first, then /skillify.");
|
|
286438
|
+
return "handled";
|
|
286439
|
+
}
|
|
286440
|
+
const taskState = runner._taskState;
|
|
286441
|
+
const corrections = [];
|
|
286442
|
+
if (taskState?.failedApproaches?.length > 0) {
|
|
286443
|
+
for (const f2 of taskState.failedApproaches) {
|
|
286444
|
+
corrections.push(`FAILED: ${f2}`);
|
|
286445
|
+
}
|
|
286446
|
+
}
|
|
286447
|
+
if (taskState?.completedSteps?.length > 0) {
|
|
286448
|
+
for (const s2 of taskState.completedSteps.slice(-5)) {
|
|
286449
|
+
corrections.push(`SUCCEEDED: ${s2}`);
|
|
286450
|
+
}
|
|
286451
|
+
}
|
|
286452
|
+
const skillRequest = arg || taskState?.goal || "workflow from this session";
|
|
286453
|
+
const correctionStr = corrections.length > 0 ? corrections.join("\n") : "";
|
|
286454
|
+
renderInfo(`Extracting skill from session (${corrections.length} corrections/steps)...`);
|
|
286455
|
+
const skillifyPrompt = `Use the skill_build tool to create a skill from this session:
|
|
286456
|
+
skill_build(skill_request="${skillRequest}"` + (correctionStr ? `, session_corrections="${correctionStr.replace(/"/g, '\\"')}"` : "") + `)
|
|
286457
|
+
|
|
286458
|
+
The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
286459
|
+
ctx3.injectMessage?.(skillifyPrompt);
|
|
286460
|
+
return "handled";
|
|
286461
|
+
}
|
|
286226
286462
|
case "cohere": {
|
|
286227
286463
|
await showCohereDashboard(ctx3);
|
|
286228
286464
|
return "handled";
|
|
286229
286465
|
}
|
|
286466
|
+
case "daemon": {
|
|
286467
|
+
const { getDaemonStatus: getDaemonStatus2, stopDaemon: stopDaemon2, ensureDaemon: ensureDaemon2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
|
|
286468
|
+
if (arg === "status" || !arg) {
|
|
286469
|
+
const status = await getDaemonStatus2();
|
|
286470
|
+
if (status.running) {
|
|
286471
|
+
renderInfo(`Daemon: running (PID ${status.pid}, port ${status.port})`);
|
|
286472
|
+
} else {
|
|
286473
|
+
renderInfo(`Daemon: not running (port ${status.port})`);
|
|
286474
|
+
}
|
|
286475
|
+
} else if (arg === "stop") {
|
|
286476
|
+
const stopped = stopDaemon2();
|
|
286477
|
+
renderInfo(stopped ? "Daemon stopped." : "Daemon was not running.");
|
|
286478
|
+
} else if (arg === "restart") {
|
|
286479
|
+
stopDaemon2();
|
|
286480
|
+
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
286481
|
+
const ok = await ensureDaemon2();
|
|
286482
|
+
renderInfo(ok ? "Daemon restarted." : "Daemon failed to restart.");
|
|
286483
|
+
} else if (arg === "start") {
|
|
286484
|
+
const ok = await ensureDaemon2();
|
|
286485
|
+
renderInfo(ok ? "Daemon started." : "Daemon already running or failed to start.");
|
|
286486
|
+
} else {
|
|
286487
|
+
renderInfo("Usage: /daemon [status|start|stop|restart]");
|
|
286488
|
+
}
|
|
286489
|
+
return "handled";
|
|
286490
|
+
}
|
|
286230
286491
|
case "listen":
|
|
286231
286492
|
case "mic": {
|
|
286232
286493
|
if (!ctx3.listenToggle) {
|
|
@@ -286483,9 +286744,9 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
286483
286744
|
}
|
|
286484
286745
|
}
|
|
286485
286746
|
}
|
|
286486
|
-
const _spLogDir =
|
|
286487
|
-
|
|
286488
|
-
const _spLogFile =
|
|
286747
|
+
const _spLogDir = join65(projectDir, ".oa", "sponsor");
|
|
286748
|
+
mkdirSync22(_spLogDir, { recursive: true });
|
|
286749
|
+
const _spLogFile = join65(_spLogDir, "sponsor-startup.log");
|
|
286489
286750
|
const _spLog = (msg) => {
|
|
286490
286751
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}
|
|
286491
286752
|
`;
|
|
@@ -286598,17 +286859,17 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
286598
286859
|
}
|
|
286599
286860
|
if (!sponsorUrl && !sponsorPeerId) {
|
|
286600
286861
|
_spLog("FAILED \u2014 no tunnelUrl and no peerId");
|
|
286601
|
-
_spLog(`nexusDir checked: ${
|
|
286602
|
-
_spLog(`status.json exists: ${
|
|
286603
|
-
_spLog(`daemon.pid exists: ${
|
|
286862
|
+
_spLog(`nexusDir checked: ${join65(projectDir, ".oa", "nexus")}`);
|
|
286863
|
+
_spLog(`status.json exists: ${existsSync49(join65(projectDir, ".oa", "nexus", "status.json"))}`);
|
|
286864
|
+
_spLog(`daemon.pid exists: ${existsSync49(join65(projectDir, ".oa", "nexus", "daemon.pid"))}`);
|
|
286604
286865
|
try {
|
|
286605
|
-
const _statusRaw =
|
|
286866
|
+
const _statusRaw = readFileSync37(join65(projectDir, ".oa", "nexus", "status.json"), "utf8");
|
|
286606
286867
|
_spLog(`status.json content: ${_statusRaw.slice(0, 300)}`);
|
|
286607
286868
|
} catch (e2) {
|
|
286608
286869
|
_spLog(`status.json read error: ${e2}`);
|
|
286609
286870
|
}
|
|
286610
286871
|
try {
|
|
286611
|
-
const _errRaw =
|
|
286872
|
+
const _errRaw = readFileSync37(join65(projectDir, ".oa", "nexus", "daemon.err"), "utf8");
|
|
286612
286873
|
_spLog(`daemon.err (last 500): ${_errRaw.slice(-500)}`);
|
|
286613
286874
|
} catch (e2) {
|
|
286614
286875
|
_spLog(`daemon.err read error: ${e2}`);
|
|
@@ -286625,10 +286886,10 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
286625
286886
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
286626
286887
|
if (!sponsorName || sponsorName.length < 2) {
|
|
286627
286888
|
try {
|
|
286628
|
-
const { homedir:
|
|
286629
|
-
const namePath = __require("path").join(
|
|
286630
|
-
if (
|
|
286631
|
-
sponsorName =
|
|
286889
|
+
const { homedir: homedir26 } = __require("os");
|
|
286890
|
+
const namePath = __require("path").join(homedir26(), ".open-agents", "agent-name");
|
|
286891
|
+
if (existsSync49(namePath))
|
|
286892
|
+
sponsorName = readFileSync37(namePath, "utf8").trim();
|
|
286632
286893
|
} catch {
|
|
286633
286894
|
}
|
|
286634
286895
|
if (!sponsorName)
|
|
@@ -286704,9 +286965,9 @@ Clone a new voice: /voice clone <wav-file> [name]`);
|
|
|
286704
286965
|
if (result) {
|
|
286705
286966
|
renderInfo("Sponsor wizard completed.");
|
|
286706
286967
|
try {
|
|
286707
|
-
const nexusPidFile =
|
|
286708
|
-
if (
|
|
286709
|
-
const nPid = parseInt(
|
|
286968
|
+
const nexusPidFile = join65(projectDir, ".oa", "nexus", "daemon.pid");
|
|
286969
|
+
if (existsSync49(nexusPidFile)) {
|
|
286970
|
+
const nPid = parseInt(readFileSync37(nexusPidFile, "utf8").trim(), 10);
|
|
286710
286971
|
if (nPid > 0) {
|
|
286711
286972
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
286712
286973
|
}
|
|
@@ -287714,13 +287975,13 @@ async function showCohereDashboard(ctx3) {
|
|
|
287714
287975
|
} else if (idResult.key === "view") {
|
|
287715
287976
|
await ik.execute({ operation: "hydrate" });
|
|
287716
287977
|
} else if (idResult.key === "history") {
|
|
287717
|
-
const snapDir =
|
|
287718
|
-
if (
|
|
287978
|
+
const snapDir = join65(ctx3.repoRoot, ".oa", "identity", "snapshots");
|
|
287979
|
+
if (existsSync49(snapDir)) {
|
|
287719
287980
|
const snaps = readdirSync14(snapDir).filter((f2) => f2.endsWith(".json")).sort().reverse();
|
|
287720
287981
|
const snapItems = snaps.slice(0, 20).map((f2) => ({
|
|
287721
287982
|
key: f2,
|
|
287722
287983
|
label: f2.replace(".json", ""),
|
|
287723
|
-
detail: `${formatFileSize(statSync15(
|
|
287984
|
+
detail: `${formatFileSize(statSync15(join65(snapDir, f2)).size)}`
|
|
287724
287985
|
}));
|
|
287725
287986
|
if (snapItems.length > 0) {
|
|
287726
287987
|
await tuiSelect({
|
|
@@ -288031,12 +288292,12 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
288031
288292
|
continue;
|
|
288032
288293
|
}
|
|
288033
288294
|
const { basename: basename19, join: pathJoin } = await import("node:path");
|
|
288034
|
-
const { copyFileSync: copyFileSync3, mkdirSync:
|
|
288035
|
-
const { homedir:
|
|
288295
|
+
const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync37, existsSync: exists2 } = await import("node:fs");
|
|
288296
|
+
const { homedir: homedir26 } = await import("node:os");
|
|
288036
288297
|
const modelName = basename19(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
288037
|
-
const destDir = pathJoin(
|
|
288298
|
+
const destDir = pathJoin(homedir26(), ".open-agents", "voice", "models", modelName);
|
|
288038
288299
|
if (!exists2(destDir))
|
|
288039
|
-
|
|
288300
|
+
mkdirSync37(destDir, { recursive: true });
|
|
288040
288301
|
copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
288041
288302
|
copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
288042
288303
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -288670,11 +288931,11 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
288670
288931
|
}
|
|
288671
288932
|
} catch {
|
|
288672
288933
|
}
|
|
288673
|
-
const sponsorDir2 =
|
|
288674
|
-
const knownFile =
|
|
288934
|
+
const sponsorDir2 = join65(ctx3.repoRoot ?? process.cwd(), ".oa", "sponsor");
|
|
288935
|
+
const knownFile = join65(sponsorDir2, "known-sponsors.json");
|
|
288675
288936
|
try {
|
|
288676
|
-
if (
|
|
288677
|
-
const saved = JSON.parse(
|
|
288937
|
+
if (existsSync49(knownFile)) {
|
|
288938
|
+
const saved = JSON.parse(readFileSync37(knownFile, "utf8"));
|
|
288678
288939
|
for (const s2 of saved) {
|
|
288679
288940
|
if (!sponsors.some((sp) => sp.url === s2.url)) {
|
|
288680
288941
|
sponsors.push({ ...s2, source: "saved" });
|
|
@@ -288729,10 +288990,10 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
288729
288990
|
sponsors.push(...verified);
|
|
288730
288991
|
if (verified.length > 0) {
|
|
288731
288992
|
try {
|
|
288732
|
-
const { mkdirSync:
|
|
288733
|
-
|
|
288993
|
+
const { mkdirSync: mkdirSync37, writeFileSync: writeFileSync35 } = __require("node:fs");
|
|
288994
|
+
mkdirSync37(sponsorDir2, { recursive: true });
|
|
288734
288995
|
const cached = verified.map((s2) => ({ ...s2, lastVerified: Date.now() }));
|
|
288735
|
-
|
|
288996
|
+
writeFileSync35(knownFile, JSON.stringify(cached, null, 2));
|
|
288736
288997
|
} catch {
|
|
288737
288998
|
}
|
|
288738
288999
|
}
|
|
@@ -288823,11 +289084,11 @@ async function handleSponsoredEndpoint(ctx3, local) {
|
|
|
288823
289084
|
}
|
|
288824
289085
|
const saveKey = selected.url || selected.peerId || selected.name;
|
|
288825
289086
|
try {
|
|
288826
|
-
|
|
288827
|
-
const existing =
|
|
289087
|
+
mkdirSync22(sponsorDir2, { recursive: true });
|
|
289088
|
+
const existing = existsSync49(knownFile) ? JSON.parse(readFileSync37(knownFile, "utf8")) : [];
|
|
288828
289089
|
const updated = existing.filter((s2) => (s2.url || s2.peerId || s2.name) !== saveKey);
|
|
288829
289090
|
updated.push(selected);
|
|
288830
|
-
|
|
289091
|
+
writeFileSync23(knownFile, JSON.stringify(updated, null, 2), "utf8");
|
|
288831
289092
|
} catch {
|
|
288832
289093
|
}
|
|
288833
289094
|
renderInfo(`Connected to sponsored endpoint: ${selected.name}`);
|
|
@@ -288896,11 +289157,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
|
|
|
288896
289157
|
const models = await fetchModels(peerUrl, authKey);
|
|
288897
289158
|
if (models.length > 0) {
|
|
288898
289159
|
try {
|
|
288899
|
-
const { writeFileSync:
|
|
288900
|
-
const { join:
|
|
288901
|
-
const cachePath =
|
|
288902
|
-
|
|
288903
|
-
|
|
289160
|
+
const { writeFileSync: writeFileSync35, mkdirSync: mkdirSync37 } = await import("node:fs");
|
|
289161
|
+
const { join: join87, dirname: dirname27 } = await import("node:path");
|
|
289162
|
+
const cachePath = join87(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
289163
|
+
mkdirSync37(dirname27(cachePath), { recursive: true });
|
|
289164
|
+
writeFileSync35(cachePath, JSON.stringify({
|
|
288904
289165
|
peerId,
|
|
288905
289166
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
288906
289167
|
models: models.map((m2) => ({ name: m2.name, size: m2.size, parameterSize: m2.parameterSize }))
|
|
@@ -289051,8 +289312,8 @@ Environment="OLLAMA_NUM_PARALLEL=${n2}"
|
|
|
289051
289312
|
}
|
|
289052
289313
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
289053
289314
|
process.env.OLLAMA_NUM_PARALLEL = String(n2);
|
|
289054
|
-
const { spawn:
|
|
289055
|
-
const child =
|
|
289315
|
+
const { spawn: spawn26 } = await import("node:child_process");
|
|
289316
|
+
const child = spawn26("ollama", ["serve"], {
|
|
289056
289317
|
stdio: "ignore",
|
|
289057
289318
|
detached: true,
|
|
289058
289319
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n2) }
|
|
@@ -289098,18 +289359,18 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
289098
289359
|
let currentVersion = "0.0.0";
|
|
289099
289360
|
try {
|
|
289100
289361
|
const { createRequire: createRequire7 } = await import("node:module");
|
|
289101
|
-
const { fileURLToPath:
|
|
289102
|
-
const { dirname:
|
|
289103
|
-
const { existsSync:
|
|
289362
|
+
const { fileURLToPath: fileURLToPath19 } = await import("node:url");
|
|
289363
|
+
const { dirname: dirname27, join: join87 } = await import("node:path");
|
|
289364
|
+
const { existsSync: existsSync67 } = await import("node:fs");
|
|
289104
289365
|
const req2 = createRequire7(import.meta.url);
|
|
289105
|
-
const thisDir =
|
|
289366
|
+
const thisDir = dirname27(fileURLToPath19(import.meta.url));
|
|
289106
289367
|
const candidates = [
|
|
289107
|
-
|
|
289108
|
-
|
|
289109
|
-
|
|
289368
|
+
join87(thisDir, "..", "package.json"),
|
|
289369
|
+
join87(thisDir, "..", "..", "package.json"),
|
|
289370
|
+
join87(thisDir, "..", "..", "..", "package.json")
|
|
289110
289371
|
];
|
|
289111
289372
|
for (const pkgPath of candidates) {
|
|
289112
|
-
if (
|
|
289373
|
+
if (existsSync67(pkgPath)) {
|
|
289113
289374
|
const pkg = req2(pkgPath);
|
|
289114
289375
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
289115
289376
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -290164,10 +290425,10 @@ var init_commands = __esm({
|
|
|
290164
290425
|
});
|
|
290165
290426
|
|
|
290166
290427
|
// packages/cli/dist/tui/project-context.js
|
|
290167
|
-
import { existsSync as
|
|
290168
|
-
import { join as
|
|
290428
|
+
import { existsSync as existsSync50, readFileSync as readFileSync38, readdirSync as readdirSync15 } from "node:fs";
|
|
290429
|
+
import { join as join66, basename as basename13 } from "node:path";
|
|
290169
290430
|
import { execSync as execSync34 } from "node:child_process";
|
|
290170
|
-
import { homedir as
|
|
290431
|
+
import { homedir as homedir21, platform as platform4, release } from "node:os";
|
|
290171
290432
|
function getModelTier(modelName) {
|
|
290172
290433
|
const m2 = modelName.toLowerCase();
|
|
290173
290434
|
const sizeMatch = m2.match(/\b(\d+)b\b/);
|
|
@@ -290200,10 +290461,10 @@ function loadProjectMap(repoRoot) {
|
|
|
290200
290461
|
if (!hasOaDirectory(repoRoot)) {
|
|
290201
290462
|
initOaDirectory(repoRoot);
|
|
290202
290463
|
}
|
|
290203
|
-
const mapPath2 =
|
|
290204
|
-
if (
|
|
290464
|
+
const mapPath2 = join66(repoRoot, OA_DIR, "context", "project-map.md");
|
|
290465
|
+
if (existsSync50(mapPath2)) {
|
|
290205
290466
|
try {
|
|
290206
|
-
const content =
|
|
290467
|
+
const content = readFileSync38(mapPath2, "utf-8");
|
|
290207
290468
|
return content;
|
|
290208
290469
|
} catch {
|
|
290209
290470
|
}
|
|
@@ -290244,31 +290505,31 @@ ${log22}`);
|
|
|
290244
290505
|
}
|
|
290245
290506
|
function loadMemoryContext(repoRoot) {
|
|
290246
290507
|
const sections = [];
|
|
290247
|
-
const oaMemDir =
|
|
290508
|
+
const oaMemDir = join66(repoRoot, OA_DIR, "memory");
|
|
290248
290509
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
290249
290510
|
if (oaEntries)
|
|
290250
290511
|
sections.push(oaEntries);
|
|
290251
|
-
const legacyMemDir =
|
|
290252
|
-
if (legacyMemDir !== oaMemDir &&
|
|
290512
|
+
const legacyMemDir = join66(repoRoot, ".open-agents", "memory");
|
|
290513
|
+
if (legacyMemDir !== oaMemDir && existsSync50(legacyMemDir)) {
|
|
290253
290514
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
290254
290515
|
if (legacyEntries)
|
|
290255
290516
|
sections.push(legacyEntries);
|
|
290256
290517
|
}
|
|
290257
|
-
const globalMemDir =
|
|
290518
|
+
const globalMemDir = join66(homedir21(), ".open-agents", "memory");
|
|
290258
290519
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
290259
290520
|
if (globalEntries)
|
|
290260
290521
|
sections.push(globalEntries);
|
|
290261
290522
|
return sections.join("\n\n");
|
|
290262
290523
|
}
|
|
290263
290524
|
function loadMemoryDir(memDir, scope) {
|
|
290264
|
-
if (!
|
|
290525
|
+
if (!existsSync50(memDir))
|
|
290265
290526
|
return "";
|
|
290266
290527
|
const lines = [];
|
|
290267
290528
|
try {
|
|
290268
290529
|
const files = readdirSync15(memDir).filter((f2) => f2.endsWith(".json"));
|
|
290269
290530
|
for (const file of files.slice(0, 10)) {
|
|
290270
290531
|
try {
|
|
290271
|
-
const raw =
|
|
290532
|
+
const raw = readFileSync38(join66(memDir, file), "utf-8");
|
|
290272
290533
|
const entries = JSON.parse(raw);
|
|
290273
290534
|
const topic = basename13(file, ".json");
|
|
290274
290535
|
const keys = Object.keys(entries);
|
|
@@ -291413,8 +291674,8 @@ __export(banner_exports, {
|
|
|
291413
291674
|
saveBannerDesign: () => saveBannerDesign,
|
|
291414
291675
|
setGridText: () => setGridText
|
|
291415
291676
|
});
|
|
291416
|
-
import { existsSync as
|
|
291417
|
-
import { join as
|
|
291677
|
+
import { existsSync as existsSync51, readFileSync as readFileSync39, writeFileSync as writeFileSync24, mkdirSync as mkdirSync23 } from "node:fs";
|
|
291678
|
+
import { join as join67 } from "node:path";
|
|
291418
291679
|
function generateMnemonic(seed) {
|
|
291419
291680
|
let h = 2166136261;
|
|
291420
291681
|
for (let i2 = 0; i2 < seed.length; i2++) {
|
|
@@ -291609,23 +291870,23 @@ function createSponsorBanner(sponsorName, tagline, primaryColor = 214, bgColor =
|
|
|
291609
291870
|
};
|
|
291610
291871
|
}
|
|
291611
291872
|
function saveBannerDesign(workDir, design) {
|
|
291612
|
-
const dir =
|
|
291613
|
-
|
|
291614
|
-
|
|
291873
|
+
const dir = join67(workDir, ".oa", "banners");
|
|
291874
|
+
mkdirSync23(dir, { recursive: true });
|
|
291875
|
+
writeFileSync24(join67(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
|
|
291615
291876
|
}
|
|
291616
291877
|
function loadBannerDesign(workDir, id) {
|
|
291617
|
-
const file =
|
|
291618
|
-
if (!
|
|
291878
|
+
const file = join67(workDir, ".oa", "banners", `${id}.json`);
|
|
291879
|
+
if (!existsSync51(file))
|
|
291619
291880
|
return null;
|
|
291620
291881
|
try {
|
|
291621
|
-
return JSON.parse(
|
|
291882
|
+
return JSON.parse(readFileSync39(file, "utf8"));
|
|
291622
291883
|
} catch {
|
|
291623
291884
|
return null;
|
|
291624
291885
|
}
|
|
291625
291886
|
}
|
|
291626
291887
|
function listBannerDesigns(workDir) {
|
|
291627
|
-
const dir =
|
|
291628
|
-
if (!
|
|
291888
|
+
const dir = join67(workDir, ".oa", "banners");
|
|
291889
|
+
if (!existsSync51(dir))
|
|
291629
291890
|
return [];
|
|
291630
291891
|
try {
|
|
291631
291892
|
const { readdirSync: readdirSync26 } = __require("node:fs");
|
|
@@ -291993,22 +292254,22 @@ var init_banner = __esm({
|
|
|
291993
292254
|
});
|
|
291994
292255
|
|
|
291995
292256
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
291996
|
-
import { existsSync as
|
|
291997
|
-
import { join as
|
|
292257
|
+
import { existsSync as existsSync52, readFileSync as readFileSync40, writeFileSync as writeFileSync25, mkdirSync as mkdirSync24, readdirSync as readdirSync16 } from "node:fs";
|
|
292258
|
+
import { join as join68, basename as basename14 } from "node:path";
|
|
291998
292259
|
function loadToolProfile(repoRoot) {
|
|
291999
|
-
const filePath =
|
|
292260
|
+
const filePath = join68(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
292000
292261
|
try {
|
|
292001
|
-
if (!
|
|
292262
|
+
if (!existsSync52(filePath))
|
|
292002
292263
|
return null;
|
|
292003
|
-
return JSON.parse(
|
|
292264
|
+
return JSON.parse(readFileSync40(filePath, "utf-8"));
|
|
292004
292265
|
} catch {
|
|
292005
292266
|
return null;
|
|
292006
292267
|
}
|
|
292007
292268
|
}
|
|
292008
292269
|
function saveToolProfile(repoRoot, profile) {
|
|
292009
|
-
const contextDir =
|
|
292010
|
-
|
|
292011
|
-
|
|
292270
|
+
const contextDir = join68(repoRoot, OA_DIR, "context");
|
|
292271
|
+
mkdirSync24(contextDir, { recursive: true });
|
|
292272
|
+
writeFileSync25(join68(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
292012
292273
|
}
|
|
292013
292274
|
function categorizeToolCall(toolName) {
|
|
292014
292275
|
for (const cat2 of TOOL_CATEGORIES) {
|
|
@@ -292066,25 +292327,25 @@ function weightedColor(profile) {
|
|
|
292066
292327
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
292067
292328
|
}
|
|
292068
292329
|
function loadCachedDescriptors(repoRoot) {
|
|
292069
|
-
const filePath =
|
|
292330
|
+
const filePath = join68(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
292070
292331
|
try {
|
|
292071
|
-
if (!
|
|
292332
|
+
if (!existsSync52(filePath))
|
|
292072
292333
|
return null;
|
|
292073
|
-
const cached = JSON.parse(
|
|
292334
|
+
const cached = JSON.parse(readFileSync40(filePath, "utf-8"));
|
|
292074
292335
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
292075
292336
|
} catch {
|
|
292076
292337
|
return null;
|
|
292077
292338
|
}
|
|
292078
292339
|
}
|
|
292079
292340
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
292080
|
-
const contextDir =
|
|
292081
|
-
|
|
292341
|
+
const contextDir = join68(repoRoot, OA_DIR, "context");
|
|
292342
|
+
mkdirSync24(contextDir, { recursive: true });
|
|
292082
292343
|
const cached = {
|
|
292083
292344
|
phrases,
|
|
292084
292345
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
292085
292346
|
sourceHash
|
|
292086
292347
|
};
|
|
292087
|
-
|
|
292348
|
+
writeFileSync25(join68(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
292088
292349
|
}
|
|
292089
292350
|
function generateDescriptors(repoRoot) {
|
|
292090
292351
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -292132,11 +292393,11 @@ function generateDescriptors(repoRoot) {
|
|
|
292132
292393
|
return phrases;
|
|
292133
292394
|
}
|
|
292134
292395
|
function extractFromPackageJson(repoRoot, tags) {
|
|
292135
|
-
const pkgPath =
|
|
292396
|
+
const pkgPath = join68(repoRoot, "package.json");
|
|
292136
292397
|
try {
|
|
292137
|
-
if (!
|
|
292398
|
+
if (!existsSync52(pkgPath))
|
|
292138
292399
|
return;
|
|
292139
|
-
const pkg = JSON.parse(
|
|
292400
|
+
const pkg = JSON.parse(readFileSync40(pkgPath, "utf-8"));
|
|
292140
292401
|
if (pkg.name && typeof pkg.name === "string") {
|
|
292141
292402
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
292142
292403
|
for (const p2 of parts)
|
|
@@ -292180,7 +292441,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
292180
292441
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
292181
292442
|
];
|
|
292182
292443
|
for (const check of manifestChecks) {
|
|
292183
|
-
if (
|
|
292444
|
+
if (existsSync52(join68(repoRoot, check.file))) {
|
|
292184
292445
|
tags.push(check.tag);
|
|
292185
292446
|
}
|
|
292186
292447
|
}
|
|
@@ -292202,16 +292463,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
292202
292463
|
}
|
|
292203
292464
|
}
|
|
292204
292465
|
function extractFromMemory(repoRoot, tags) {
|
|
292205
|
-
const memoryDir =
|
|
292466
|
+
const memoryDir = join68(repoRoot, OA_DIR, "memory");
|
|
292206
292467
|
try {
|
|
292207
|
-
if (!
|
|
292468
|
+
if (!existsSync52(memoryDir))
|
|
292208
292469
|
return;
|
|
292209
292470
|
const files = readdirSync16(memoryDir).filter((f2) => f2.endsWith(".json"));
|
|
292210
292471
|
for (const file of files) {
|
|
292211
292472
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
292212
292473
|
tags.push(topic);
|
|
292213
292474
|
try {
|
|
292214
|
-
const data = JSON.parse(
|
|
292475
|
+
const data = JSON.parse(readFileSync40(join68(memoryDir, file), "utf-8"));
|
|
292215
292476
|
if (data && typeof data === "object") {
|
|
292216
292477
|
const keys = Object.keys(data).slice(0, 3);
|
|
292217
292478
|
for (const key of keys) {
|
|
@@ -292882,13 +293143,13 @@ var init_stream_renderer = __esm({
|
|
|
292882
293143
|
});
|
|
292883
293144
|
|
|
292884
293145
|
// packages/cli/dist/tui/edit-history.js
|
|
292885
|
-
import { appendFileSync as appendFileSync4, mkdirSync as
|
|
292886
|
-
import { join as
|
|
293146
|
+
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync25 } from "node:fs";
|
|
293147
|
+
import { join as join69 } from "node:path";
|
|
292887
293148
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
292888
|
-
const historyDir =
|
|
292889
|
-
const logPath2 =
|
|
293149
|
+
const historyDir = join69(repoRoot, ".oa", "history");
|
|
293150
|
+
const logPath2 = join69(historyDir, "edits.jsonl");
|
|
292890
293151
|
try {
|
|
292891
|
-
|
|
293152
|
+
mkdirSync25(historyDir, { recursive: true });
|
|
292892
293153
|
} catch {
|
|
292893
293154
|
}
|
|
292894
293155
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -292997,17 +293258,17 @@ var init_edit_history = __esm({
|
|
|
292997
293258
|
});
|
|
292998
293259
|
|
|
292999
293260
|
// packages/cli/dist/tui/promptLoader.js
|
|
293000
|
-
import { readFileSync as
|
|
293001
|
-
import { join as
|
|
293002
|
-
import { fileURLToPath as
|
|
293261
|
+
import { readFileSync as readFileSync41, existsSync as existsSync53 } from "node:fs";
|
|
293262
|
+
import { join as join70, dirname as dirname22 } from "node:path";
|
|
293263
|
+
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
293003
293264
|
function loadPrompt3(promptPath, vars) {
|
|
293004
293265
|
let content = cache6.get(promptPath);
|
|
293005
293266
|
if (content === void 0) {
|
|
293006
|
-
const fullPath =
|
|
293007
|
-
if (!
|
|
293267
|
+
const fullPath = join70(PROMPTS_DIR3, promptPath);
|
|
293268
|
+
if (!existsSync53(fullPath)) {
|
|
293008
293269
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
293009
293270
|
}
|
|
293010
|
-
content =
|
|
293271
|
+
content = readFileSync41(fullPath, "utf-8");
|
|
293011
293272
|
cache6.set(promptPath, content);
|
|
293012
293273
|
}
|
|
293013
293274
|
if (!vars)
|
|
@@ -293018,25 +293279,25 @@ var __filename5, __dirname7, devPath2, publishedPath2, PROMPTS_DIR3, cache6;
|
|
|
293018
293279
|
var init_promptLoader3 = __esm({
|
|
293019
293280
|
"packages/cli/dist/tui/promptLoader.js"() {
|
|
293020
293281
|
"use strict";
|
|
293021
|
-
__filename5 =
|
|
293022
|
-
__dirname7 =
|
|
293023
|
-
devPath2 =
|
|
293024
|
-
publishedPath2 =
|
|
293025
|
-
PROMPTS_DIR3 =
|
|
293282
|
+
__filename5 = fileURLToPath14(import.meta.url);
|
|
293283
|
+
__dirname7 = dirname22(__filename5);
|
|
293284
|
+
devPath2 = join70(__dirname7, "..", "..", "prompts");
|
|
293285
|
+
publishedPath2 = join70(__dirname7, "..", "prompts");
|
|
293286
|
+
PROMPTS_DIR3 = existsSync53(devPath2) ? devPath2 : publishedPath2;
|
|
293026
293287
|
cache6 = /* @__PURE__ */ new Map();
|
|
293027
293288
|
}
|
|
293028
293289
|
});
|
|
293029
293290
|
|
|
293030
293291
|
// packages/cli/dist/tui/dream-engine.js
|
|
293031
|
-
import { mkdirSync as
|
|
293032
|
-
import { join as
|
|
293292
|
+
import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync26, readFileSync as readFileSync42, existsSync as existsSync54, cpSync, rmSync as rmSync3, readdirSync as readdirSync17 } from "node:fs";
|
|
293293
|
+
import { join as join71, basename as basename15 } from "node:path";
|
|
293033
293294
|
import { execSync as execSync35 } from "node:child_process";
|
|
293034
293295
|
function loadAutoresearchMemory(repoRoot) {
|
|
293035
|
-
const memoryPath =
|
|
293036
|
-
if (!
|
|
293296
|
+
const memoryPath = join71(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
293297
|
+
if (!existsSync54(memoryPath))
|
|
293037
293298
|
return "";
|
|
293038
293299
|
try {
|
|
293039
|
-
const raw =
|
|
293300
|
+
const raw = readFileSync42(memoryPath, "utf-8");
|
|
293040
293301
|
const data = JSON.parse(raw);
|
|
293041
293302
|
const sections = [];
|
|
293042
293303
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -293226,14 +293487,14 @@ var init_dream_engine = __esm({
|
|
|
293226
293487
|
const content = String(args["content"] ?? "");
|
|
293227
293488
|
if (!rawPath)
|
|
293228
293489
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
293229
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
293490
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join71(this.autoresearchDir, basename15(rawPath)) : join71(this.autoresearchDir, rawPath);
|
|
293230
293491
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
293231
293492
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
293232
293493
|
}
|
|
293233
293494
|
try {
|
|
293234
|
-
const dir =
|
|
293235
|
-
|
|
293236
|
-
|
|
293495
|
+
const dir = join71(targetPath, "..");
|
|
293496
|
+
mkdirSync26(dir, { recursive: true });
|
|
293497
|
+
writeFileSync26(targetPath, content, "utf-8");
|
|
293237
293498
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293238
293499
|
} catch (err) {
|
|
293239
293500
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
|
|
@@ -293261,20 +293522,20 @@ var init_dream_engine = __esm({
|
|
|
293261
293522
|
const rawPath = String(args["path"] ?? "");
|
|
293262
293523
|
const oldStr = String(args["old_string"] ?? "");
|
|
293263
293524
|
const newStr = String(args["new_string"] ?? "");
|
|
293264
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
293525
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join71(this.autoresearchDir, basename15(rawPath)) : join71(this.autoresearchDir, rawPath);
|
|
293265
293526
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
293266
293527
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start2 };
|
|
293267
293528
|
}
|
|
293268
293529
|
try {
|
|
293269
|
-
if (!
|
|
293530
|
+
if (!existsSync54(targetPath)) {
|
|
293270
293531
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293271
293532
|
}
|
|
293272
|
-
let content =
|
|
293533
|
+
let content = readFileSync42(targetPath, "utf-8");
|
|
293273
293534
|
if (!content.includes(oldStr)) {
|
|
293274
293535
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
|
|
293275
293536
|
}
|
|
293276
293537
|
content = content.replace(oldStr, newStr);
|
|
293277
|
-
|
|
293538
|
+
writeFileSync26(targetPath, content, "utf-8");
|
|
293278
293539
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293279
293540
|
} catch (err) {
|
|
293280
293541
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
|
|
@@ -293315,14 +293576,14 @@ var init_dream_engine = __esm({
|
|
|
293315
293576
|
const content = String(args["content"] ?? "");
|
|
293316
293577
|
if (!rawPath)
|
|
293317
293578
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
293318
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
293579
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join71(this.dreamsDir, basename15(rawPath)) : join71(this.dreamsDir, rawPath);
|
|
293319
293580
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
293320
293581
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
293321
293582
|
}
|
|
293322
293583
|
try {
|
|
293323
|
-
const dir =
|
|
293324
|
-
|
|
293325
|
-
|
|
293584
|
+
const dir = join71(targetPath, "..");
|
|
293585
|
+
mkdirSync26(dir, { recursive: true });
|
|
293586
|
+
writeFileSync26(targetPath, content, "utf-8");
|
|
293326
293587
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293327
293588
|
} catch (err) {
|
|
293328
293589
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
|
|
@@ -293350,20 +293611,20 @@ var init_dream_engine = __esm({
|
|
|
293350
293611
|
const rawPath = String(args["path"] ?? "");
|
|
293351
293612
|
const oldStr = String(args["old_string"] ?? "");
|
|
293352
293613
|
const newStr = String(args["new_string"] ?? "");
|
|
293353
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
293614
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join71(this.dreamsDir, basename15(rawPath)) : join71(this.dreamsDir, rawPath);
|
|
293354
293615
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
293355
293616
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start2 };
|
|
293356
293617
|
}
|
|
293357
293618
|
try {
|
|
293358
|
-
if (!
|
|
293619
|
+
if (!existsSync54(targetPath)) {
|
|
293359
293620
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293360
293621
|
}
|
|
293361
|
-
let content =
|
|
293622
|
+
let content = readFileSync42(targetPath, "utf-8");
|
|
293362
293623
|
if (!content.includes(oldStr)) {
|
|
293363
293624
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
|
|
293364
293625
|
}
|
|
293365
293626
|
content = content.replace(oldStr, newStr);
|
|
293366
|
-
|
|
293627
|
+
writeFileSync26(targetPath, content, "utf-8");
|
|
293367
293628
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start2 };
|
|
293368
293629
|
} catch (err) {
|
|
293369
293630
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
|
|
@@ -293417,7 +293678,7 @@ var init_dream_engine = __esm({
|
|
|
293417
293678
|
constructor(config, repoRoot) {
|
|
293418
293679
|
this.config = config;
|
|
293419
293680
|
this.repoRoot = repoRoot;
|
|
293420
|
-
this.dreamsDir =
|
|
293681
|
+
this.dreamsDir = join71(repoRoot, ".oa", "dreams");
|
|
293421
293682
|
this.state = {
|
|
293422
293683
|
mode: "default",
|
|
293423
293684
|
active: false,
|
|
@@ -293438,6 +293699,9 @@ var init_dream_engine = __esm({
|
|
|
293438
293699
|
if (this.state.active) {
|
|
293439
293700
|
throw new Error("Already dreaming. Use /dream stop first.");
|
|
293440
293701
|
}
|
|
293702
|
+
if (mode === "consolidate") {
|
|
293703
|
+
return this.runConsolidation(onEvent);
|
|
293704
|
+
}
|
|
293441
293705
|
this.abortController = new AbortController();
|
|
293442
293706
|
const totalCycles = mode === "deep" ? 3 : mode === "lucid" ? 2 : 1;
|
|
293443
293707
|
this.state = {
|
|
@@ -293448,7 +293712,7 @@ var init_dream_engine = __esm({
|
|
|
293448
293712
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
293449
293713
|
results: []
|
|
293450
293714
|
};
|
|
293451
|
-
|
|
293715
|
+
mkdirSync26(this.dreamsDir, { recursive: true });
|
|
293452
293716
|
this.saveDreamState();
|
|
293453
293717
|
try {
|
|
293454
293718
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -293501,8 +293765,8 @@ ${result.summary}`;
|
|
|
293501
293765
|
if (mode !== "default" || cycle === totalCycles) {
|
|
293502
293766
|
renderDreamContraction(cycle);
|
|
293503
293767
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
293504
|
-
const summaryPath =
|
|
293505
|
-
|
|
293768
|
+
const summaryPath = join71(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
293769
|
+
writeFileSync26(summaryPath, cycleSummary, "utf-8");
|
|
293506
293770
|
}
|
|
293507
293771
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
293508
293772
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -293714,7 +293978,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
293714
293978
|
}
|
|
293715
293979
|
/** Build role-specific tool sets for swarm agents */
|
|
293716
293980
|
buildSwarmTools(role, _workspace) {
|
|
293717
|
-
const autoresearchDir =
|
|
293981
|
+
const autoresearchDir = join71(this.repoRoot, ".oa", "autoresearch");
|
|
293718
293982
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
293719
293983
|
switch (role) {
|
|
293720
293984
|
case "researcher": {
|
|
@@ -294078,7 +294342,7 @@ INSTRUCTIONS:
|
|
|
294078
294342
|
2. Summarize the key learnings and next steps
|
|
294079
294343
|
|
|
294080
294344
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
294081
|
-
const reportPath =
|
|
294345
|
+
const reportPath = join71(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
294082
294346
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
294083
294347
|
|
|
294084
294348
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -294100,8 +294364,8 @@ ${summaryResult}
|
|
|
294100
294364
|
*Generated by open-agents autoresearch swarm*
|
|
294101
294365
|
`;
|
|
294102
294366
|
try {
|
|
294103
|
-
|
|
294104
|
-
|
|
294367
|
+
mkdirSync26(this.dreamsDir, { recursive: true });
|
|
294368
|
+
writeFileSync26(reportPath, report, "utf-8");
|
|
294105
294369
|
} catch {
|
|
294106
294370
|
}
|
|
294107
294371
|
renderSwarmComplete(workspace);
|
|
@@ -294167,9 +294431,9 @@ ${summaryResult}
|
|
|
294167
294431
|
}
|
|
294168
294432
|
/** Save workspace backup for lucid mode */
|
|
294169
294433
|
saveVersionCheckpoint(cycle) {
|
|
294170
|
-
const checkpointDir =
|
|
294434
|
+
const checkpointDir = join71(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
294171
294435
|
try {
|
|
294172
|
-
|
|
294436
|
+
mkdirSync26(checkpointDir, { recursive: true });
|
|
294173
294437
|
try {
|
|
294174
294438
|
const gitStatus = execSync35("git status --porcelain", {
|
|
294175
294439
|
cwd: this.repoRoot,
|
|
@@ -294186,10 +294450,10 @@ ${summaryResult}
|
|
|
294186
294450
|
encoding: "utf-8",
|
|
294187
294451
|
timeout: 5e3
|
|
294188
294452
|
}).trim();
|
|
294189
|
-
|
|
294190
|
-
|
|
294191
|
-
|
|
294192
|
-
|
|
294453
|
+
writeFileSync26(join71(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
294454
|
+
writeFileSync26(join71(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
294455
|
+
writeFileSync26(join71(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
294456
|
+
writeFileSync26(join71(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
294193
294457
|
cycle,
|
|
294194
294458
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
294195
294459
|
gitHash,
|
|
@@ -294197,7 +294461,7 @@ ${summaryResult}
|
|
|
294197
294461
|
}, null, 2), "utf-8");
|
|
294198
294462
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
294199
294463
|
} catch {
|
|
294200
|
-
|
|
294464
|
+
writeFileSync26(join71(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
294201
294465
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
294202
294466
|
}
|
|
294203
294467
|
} catch (err) {
|
|
@@ -294255,14 +294519,107 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
|
|
|
294255
294519
|
---
|
|
294256
294520
|
*Auto-generated by open-agents dream engine*
|
|
294257
294521
|
`;
|
|
294258
|
-
|
|
294522
|
+
writeFileSync26(join71(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
294523
|
+
} catch {
|
|
294524
|
+
}
|
|
294525
|
+
}
|
|
294526
|
+
/**
|
|
294527
|
+
* WO-LL-01: Memory Consolidation — runs the consolidation prompt through
|
|
294528
|
+
* AgenticRunner with read/write tools targeting .oa/memory/.
|
|
294529
|
+
*
|
|
294530
|
+
* 4-phase: Orient → Gather → Consolidate → Prune
|
|
294531
|
+
* Hannover reference: services/autoDream/autoDream.ts
|
|
294532
|
+
*/
|
|
294533
|
+
async runConsolidation(onEvent) {
|
|
294534
|
+
this.state = {
|
|
294535
|
+
mode: "consolidate",
|
|
294536
|
+
active: true,
|
|
294537
|
+
cycleCount: 1,
|
|
294538
|
+
currentCycle: 1,
|
|
294539
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
294540
|
+
results: []
|
|
294541
|
+
};
|
|
294542
|
+
renderInfo("Memory consolidation starting \u2014 Phase 1: Orient \u2192 Phase 2: Gather \u2192 Phase 3: Consolidate \u2192 Phase 4: Prune");
|
|
294543
|
+
const memoryDir = join71(this.repoRoot, ".oa", "memory");
|
|
294544
|
+
mkdirSync26(memoryDir, { recursive: true });
|
|
294545
|
+
let prompt;
|
|
294546
|
+
try {
|
|
294547
|
+
prompt = loadPrompt3("tui/dream-consolidate.md", {
|
|
294548
|
+
memoryDir,
|
|
294549
|
+
lookbackEntries: "10"
|
|
294550
|
+
});
|
|
294259
294551
|
} catch {
|
|
294552
|
+
prompt = `Consolidate the memory files in ${memoryDir}. List the directory, read files, merge duplicates, delete stale entries, update the index.`;
|
|
294553
|
+
}
|
|
294554
|
+
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
|
|
294555
|
+
const modelTier = getModelTier(this.config.model);
|
|
294556
|
+
const runner = new AgenticRunner(backend, {
|
|
294557
|
+
maxTurns: 20,
|
|
294558
|
+
maxTokens: 4096,
|
|
294559
|
+
temperature: 0,
|
|
294560
|
+
requestTimeoutMs: this.config.timeoutMs,
|
|
294561
|
+
taskTimeoutMs: this.config.timeoutMs * 3,
|
|
294562
|
+
compactionThreshold: 24e3,
|
|
294563
|
+
contextWindowSize: 32768,
|
|
294564
|
+
modelTier
|
|
294565
|
+
});
|
|
294566
|
+
const tools = [
|
|
294567
|
+
new FileReadTool(this.repoRoot),
|
|
294568
|
+
new FileWriteTool(this.repoRoot),
|
|
294569
|
+
new FileEditTool(this.repoRoot),
|
|
294570
|
+
new ListDirectoryTool(this.repoRoot),
|
|
294571
|
+
new GrepSearchTool(this.repoRoot),
|
|
294572
|
+
new GlobFindTool(this.repoRoot),
|
|
294573
|
+
new ShellTool(this.repoRoot),
|
|
294574
|
+
new MemoryReadTool(this.repoRoot),
|
|
294575
|
+
new MemoryWriteTool(this.repoRoot),
|
|
294576
|
+
new MemorySearchTool(this.repoRoot)
|
|
294577
|
+
].map((t2) => ({
|
|
294578
|
+
name: t2.name,
|
|
294579
|
+
description: t2.description,
|
|
294580
|
+
parameters: t2.parameters,
|
|
294581
|
+
execute: t2.execute.bind(t2)
|
|
294582
|
+
}));
|
|
294583
|
+
tools.push({
|
|
294584
|
+
name: "task_complete",
|
|
294585
|
+
description: "Signal consolidation is done. Args: {summary: string}",
|
|
294586
|
+
parameters: { type: "object", properties: { summary: { type: "string" } }, required: ["summary"] },
|
|
294587
|
+
execute: async (args) => ({ success: true, output: String(args["summary"] ?? "done") })
|
|
294588
|
+
});
|
|
294589
|
+
for (const t2 of tools)
|
|
294590
|
+
runner.registerTool(t2);
|
|
294591
|
+
if (onEvent)
|
|
294592
|
+
runner.onEvent(onEvent);
|
|
294593
|
+
const startMs = Date.now();
|
|
294594
|
+
try {
|
|
294595
|
+
const result = await runner.run(prompt);
|
|
294596
|
+
const durationMs = Date.now() - startMs;
|
|
294597
|
+
this.state.results.push({
|
|
294598
|
+
cycle: 1,
|
|
294599
|
+
stage: "consolidation",
|
|
294600
|
+
ideas: [],
|
|
294601
|
+
proposals: [],
|
|
294602
|
+
filesGenerated: [],
|
|
294603
|
+
durationMs
|
|
294604
|
+
});
|
|
294605
|
+
try {
|
|
294606
|
+
writeFileSync26(join71(memoryDir, ".last-consolidation"), JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), summary: result.summary?.slice(0, 500) }) + "\n");
|
|
294607
|
+
} catch {
|
|
294608
|
+
}
|
|
294609
|
+
renderInfo(`Consolidation complete: ${result.turns} turns, ${result.toolCalls} tool calls, ${(durationMs / 1e3).toFixed(1)}s`);
|
|
294610
|
+
if (result.summary)
|
|
294611
|
+
renderInfo(`Summary: ${result.summary.slice(0, 200)}`);
|
|
294612
|
+
} catch (err) {
|
|
294613
|
+
renderWarning(`Consolidation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
294260
294614
|
}
|
|
294615
|
+
this.state.active = false;
|
|
294616
|
+
this.saveDreamState();
|
|
294617
|
+
return this.state;
|
|
294261
294618
|
}
|
|
294262
294619
|
/** Save dream state for resume/inspection */
|
|
294263
294620
|
saveDreamState() {
|
|
294264
294621
|
try {
|
|
294265
|
-
|
|
294622
|
+
writeFileSync26(join71(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
294266
294623
|
} catch {
|
|
294267
294624
|
}
|
|
294268
294625
|
}
|
|
@@ -294636,8 +294993,8 @@ var init_bless_engine = __esm({
|
|
|
294636
294993
|
});
|
|
294637
294994
|
|
|
294638
294995
|
// packages/cli/dist/tui/dmn-engine.js
|
|
294639
|
-
import { existsSync as
|
|
294640
|
-
import { join as
|
|
294996
|
+
import { existsSync as existsSync55, readFileSync as readFileSync43, writeFileSync as writeFileSync27, mkdirSync as mkdirSync27, readdirSync as readdirSync18, unlinkSync as unlinkSync11 } from "node:fs";
|
|
294997
|
+
import { join as join72, basename as basename16 } from "node:path";
|
|
294641
294998
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
294642
294999
|
const competenceReport = competence.length > 0 ? competence.map((c4) => {
|
|
294643
295000
|
const rate = c4.attempts > 0 ? Math.round(c4.successes / c4.attempts * 100) : 0;
|
|
@@ -294757,9 +295114,9 @@ var init_dmn_engine = __esm({
|
|
|
294757
295114
|
constructor(config, repoRoot) {
|
|
294758
295115
|
this.config = config;
|
|
294759
295116
|
this.repoRoot = repoRoot;
|
|
294760
|
-
this.stateDir =
|
|
294761
|
-
this.historyDir =
|
|
294762
|
-
|
|
295117
|
+
this.stateDir = join72(repoRoot, ".oa", "dmn");
|
|
295118
|
+
this.historyDir = join72(repoRoot, ".oa", "dmn", "cycles");
|
|
295119
|
+
mkdirSync27(this.historyDir, { recursive: true });
|
|
294763
295120
|
this.loadState();
|
|
294764
295121
|
}
|
|
294765
295122
|
get stats() {
|
|
@@ -295348,11 +295705,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
295348
295705
|
async gatherMemoryTopics() {
|
|
295349
295706
|
const topics = [];
|
|
295350
295707
|
const dirs = [
|
|
295351
|
-
|
|
295352
|
-
|
|
295708
|
+
join72(this.repoRoot, ".oa", "memory"),
|
|
295709
|
+
join72(this.repoRoot, ".open-agents", "memory")
|
|
295353
295710
|
];
|
|
295354
295711
|
for (const dir of dirs) {
|
|
295355
|
-
if (!
|
|
295712
|
+
if (!existsSync55(dir))
|
|
295356
295713
|
continue;
|
|
295357
295714
|
try {
|
|
295358
295715
|
const files = readdirSync18(dir).filter((f2) => f2.endsWith(".json"));
|
|
@@ -295368,29 +295725,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
295368
295725
|
}
|
|
295369
295726
|
// ── State persistence ─────────────────────────────────────────────────
|
|
295370
295727
|
loadState() {
|
|
295371
|
-
const path5 =
|
|
295372
|
-
if (
|
|
295728
|
+
const path5 = join72(this.stateDir, "state.json");
|
|
295729
|
+
if (existsSync55(path5)) {
|
|
295373
295730
|
try {
|
|
295374
|
-
this.state = JSON.parse(
|
|
295731
|
+
this.state = JSON.parse(readFileSync43(path5, "utf-8"));
|
|
295375
295732
|
} catch {
|
|
295376
295733
|
}
|
|
295377
295734
|
}
|
|
295378
295735
|
}
|
|
295379
295736
|
saveState() {
|
|
295380
295737
|
try {
|
|
295381
|
-
|
|
295738
|
+
writeFileSync27(join72(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
295382
295739
|
} catch {
|
|
295383
295740
|
}
|
|
295384
295741
|
}
|
|
295385
295742
|
saveCycleResult(result) {
|
|
295386
295743
|
try {
|
|
295387
295744
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
295388
|
-
|
|
295745
|
+
writeFileSync27(join72(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
295389
295746
|
const files = readdirSync18(this.historyDir).filter((f2) => f2.startsWith("cycle-") && f2.endsWith(".json")).sort();
|
|
295390
295747
|
if (files.length > 50) {
|
|
295391
295748
|
for (const old of files.slice(0, files.length - 50)) {
|
|
295392
295749
|
try {
|
|
295393
|
-
|
|
295750
|
+
unlinkSync11(join72(this.historyDir, old));
|
|
295394
295751
|
} catch {
|
|
295395
295752
|
}
|
|
295396
295753
|
}
|
|
@@ -295403,8 +295760,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
295403
295760
|
});
|
|
295404
295761
|
|
|
295405
295762
|
// packages/cli/dist/tui/snr-engine.js
|
|
295406
|
-
import { existsSync as
|
|
295407
|
-
import { join as
|
|
295763
|
+
import { existsSync as existsSync56, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "node:fs";
|
|
295764
|
+
import { join as join73, basename as basename17 } from "node:path";
|
|
295408
295765
|
function computeDPrime(signalScores, noiseScores) {
|
|
295409
295766
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
295410
295767
|
return 0;
|
|
@@ -295644,11 +296001,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
295644
296001
|
loadMemoryEntries(topics) {
|
|
295645
296002
|
const entries = [];
|
|
295646
296003
|
const dirs = [
|
|
295647
|
-
|
|
295648
|
-
|
|
296004
|
+
join73(this.repoRoot, ".oa", "memory"),
|
|
296005
|
+
join73(this.repoRoot, ".open-agents", "memory")
|
|
295649
296006
|
];
|
|
295650
296007
|
for (const dir of dirs) {
|
|
295651
|
-
if (!
|
|
296008
|
+
if (!existsSync56(dir))
|
|
295652
296009
|
continue;
|
|
295653
296010
|
try {
|
|
295654
296011
|
const files = readdirSync19(dir).filter((f2) => f2.endsWith(".json"));
|
|
@@ -295657,7 +296014,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
295657
296014
|
if (topics.length > 0 && !topics.includes(topic))
|
|
295658
296015
|
continue;
|
|
295659
296016
|
try {
|
|
295660
|
-
const data = JSON.parse(
|
|
296017
|
+
const data = JSON.parse(readFileSync44(join73(dir, f2), "utf-8"));
|
|
295661
296018
|
for (const [key, val] of Object.entries(data)) {
|
|
295662
296019
|
const value2 = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
295663
296020
|
entries.push({ topic, key, value: value2 });
|
|
@@ -296224,8 +296581,8 @@ var init_tool_policy = __esm({
|
|
|
296224
296581
|
});
|
|
296225
296582
|
|
|
296226
296583
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
296227
|
-
import { mkdirSync as
|
|
296228
|
-
import { join as
|
|
296584
|
+
import { mkdirSync as mkdirSync28, existsSync as existsSync57, unlinkSync as unlinkSync12, readdirSync as readdirSync20, statSync as statSync16 } from "node:fs";
|
|
296585
|
+
import { join as join74, resolve as resolve32 } from "node:path";
|
|
296229
296586
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
296230
296587
|
function convertMarkdownToTelegramHTML(md) {
|
|
296231
296588
|
let html = md;
|
|
@@ -296553,7 +296910,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
296553
296910
|
this.polling = true;
|
|
296554
296911
|
this.abortController = new AbortController();
|
|
296555
296912
|
try {
|
|
296556
|
-
|
|
296913
|
+
mkdirSync28(this.mediaCacheDir, { recursive: true });
|
|
296557
296914
|
} catch {
|
|
296558
296915
|
}
|
|
296559
296916
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -296990,7 +297347,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
296990
297347
|
return null;
|
|
296991
297348
|
const buffer2 = Buffer.from(await res.arrayBuffer());
|
|
296992
297349
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension2}`;
|
|
296993
|
-
const localPath =
|
|
297350
|
+
const localPath = join74(this.mediaCacheDir, fileName);
|
|
296994
297351
|
await writeFileAsync(localPath, buffer2);
|
|
296995
297352
|
return localPath;
|
|
296996
297353
|
} catch {
|
|
@@ -297078,7 +297435,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
297078
297435
|
for (const [key, entry] of this.mediaCache) {
|
|
297079
297436
|
if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
|
|
297080
297437
|
try {
|
|
297081
|
-
|
|
297438
|
+
unlinkSync12(entry.localPath);
|
|
297082
297439
|
} catch {
|
|
297083
297440
|
}
|
|
297084
297441
|
this.mediaCache.delete(key);
|
|
@@ -298346,7 +298703,7 @@ var init_text_selection = __esm({
|
|
|
298346
298703
|
});
|
|
298347
298704
|
|
|
298348
298705
|
// packages/cli/dist/tui/status-bar.js
|
|
298349
|
-
import { readFileSync as
|
|
298706
|
+
import { readFileSync as readFileSync45 } from "node:fs";
|
|
298350
298707
|
function setTerminalTitle(task, version4) {
|
|
298351
298708
|
if (!process.stdout.isTTY)
|
|
298352
298709
|
return;
|
|
@@ -299085,7 +299442,7 @@ var init_status_bar = __esm({
|
|
|
299085
299442
|
if (nexusDir) {
|
|
299086
299443
|
try {
|
|
299087
299444
|
const metricsPath = nexusDir + "/remote-metrics.json";
|
|
299088
|
-
const raw =
|
|
299445
|
+
const raw = readFileSync45(metricsPath, "utf8");
|
|
299089
299446
|
const cached = JSON.parse(raw);
|
|
299090
299447
|
if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
|
|
299091
299448
|
const m2 = cached.data;
|
|
@@ -301394,13 +301751,13 @@ var init_direct_input = __esm({
|
|
|
301394
301751
|
});
|
|
301395
301752
|
|
|
301396
301753
|
// packages/cli/dist/api/audit-log.js
|
|
301397
|
-
import { mkdirSync as
|
|
301398
|
-
import { join as
|
|
301754
|
+
import { mkdirSync as mkdirSync29, appendFileSync as appendFileSync5, readFileSync as readFileSync46, existsSync as existsSync58 } from "node:fs";
|
|
301755
|
+
import { join as join75 } from "node:path";
|
|
301399
301756
|
function initAuditLog(oaDir) {
|
|
301400
|
-
auditDir =
|
|
301401
|
-
auditFile =
|
|
301757
|
+
auditDir = join75(oaDir, "audit");
|
|
301758
|
+
auditFile = join75(auditDir, "audit.jsonl");
|
|
301402
301759
|
try {
|
|
301403
|
-
|
|
301760
|
+
mkdirSync29(auditDir, { recursive: true });
|
|
301404
301761
|
initialized = true;
|
|
301405
301762
|
} catch {
|
|
301406
301763
|
}
|
|
@@ -301415,10 +301772,10 @@ function recordAudit(record) {
|
|
|
301415
301772
|
}
|
|
301416
301773
|
}
|
|
301417
301774
|
function queryAudit(opts) {
|
|
301418
|
-
if (!initialized || !
|
|
301775
|
+
if (!initialized || !existsSync58(auditFile))
|
|
301419
301776
|
return [];
|
|
301420
301777
|
try {
|
|
301421
|
-
const raw =
|
|
301778
|
+
const raw = readFileSync46(auditFile, "utf-8");
|
|
301422
301779
|
const lines = raw.split("\n").filter(Boolean);
|
|
301423
301780
|
let records = lines.map((l2) => {
|
|
301424
301781
|
try {
|
|
@@ -302741,29 +303098,29 @@ var init_auth_oidc = __esm({
|
|
|
302741
303098
|
|
|
302742
303099
|
// packages/cli/dist/api/chat-session.js
|
|
302743
303100
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
302744
|
-
import { existsSync as
|
|
302745
|
-
import { join as
|
|
303101
|
+
import { existsSync as existsSync59, readFileSync as readFileSync47, readdirSync as readdirSync21 } from "node:fs";
|
|
303102
|
+
import { join as join76 } from "node:path";
|
|
302746
303103
|
function buildSystemPrompt(cwd4) {
|
|
302747
303104
|
const parts = [];
|
|
302748
303105
|
parts.push("You are Open Agent (OA), an AI coding assistant running locally via Ollama. You have access to the user's workspace and can discuss code, files, and projects. Be helpful, concise, and technically precise. When asked about files or code, describe what you know from the conversation context.");
|
|
302749
303106
|
parts.push(`\\nEnvironment: ${process.platform}, Node ${process.version}, CWD: ${cwd4}`);
|
|
302750
|
-
const diaryPath =
|
|
302751
|
-
if (
|
|
303107
|
+
const diaryPath = join76(cwd4, ".oa", "context", "session-diary.md");
|
|
303108
|
+
if (existsSync59(diaryPath)) {
|
|
302752
303109
|
try {
|
|
302753
|
-
const diary =
|
|
303110
|
+
const diary = readFileSync47(diaryPath, "utf-8").slice(0, 1e3);
|
|
302754
303111
|
parts.push(`\\nPrevious session history:\\n${diary}`);
|
|
302755
303112
|
} catch {
|
|
302756
303113
|
}
|
|
302757
303114
|
}
|
|
302758
|
-
const memDir =
|
|
302759
|
-
if (
|
|
303115
|
+
const memDir = join76(cwd4, ".oa", "memory");
|
|
303116
|
+
if (existsSync59(memDir)) {
|
|
302760
303117
|
try {
|
|
302761
303118
|
const files = readdirSync21(memDir).filter((f2) => f2.endsWith(".json")).slice(0, 5);
|
|
302762
303119
|
if (files.length > 0) {
|
|
302763
303120
|
parts.push("\\nPersistent memory topics: " + files.map((f2) => f2.replace(".json", "")).join(", "));
|
|
302764
303121
|
for (const f2 of files.slice(0, 3)) {
|
|
302765
303122
|
try {
|
|
302766
|
-
const data = JSON.parse(
|
|
303123
|
+
const data = JSON.parse(readFileSync47(join76(memDir, f2), "utf-8"));
|
|
302767
303124
|
const entries = Object.entries(data).slice(0, 3);
|
|
302768
303125
|
if (entries.length > 0) {
|
|
302769
303126
|
parts.push(`\\nMemory [${f2.replace(".json", "")}]: ` + entries.map(([k, v]) => `${k}: ${String(v.value ?? v).slice(0, 100)}`).join("; "));
|
|
@@ -302776,10 +303133,10 @@ function buildSystemPrompt(cwd4) {
|
|
|
302776
303133
|
}
|
|
302777
303134
|
}
|
|
302778
303135
|
for (const name10 of ["AGENTS.md", "OA.md", ".open-agents.md"]) {
|
|
302779
|
-
const p2 =
|
|
302780
|
-
if (
|
|
303136
|
+
const p2 = join76(cwd4, name10);
|
|
303137
|
+
if (existsSync59(p2)) {
|
|
302781
303138
|
try {
|
|
302782
|
-
const content =
|
|
303139
|
+
const content = readFileSync47(p2, "utf-8").slice(0, 500);
|
|
302783
303140
|
parts.push(`\\nProject instructions (${name10}):\\n${content}`);
|
|
302784
303141
|
} catch {
|
|
302785
303142
|
}
|
|
@@ -302857,15 +303214,15 @@ var init_chat_session = __esm({
|
|
|
302857
303214
|
});
|
|
302858
303215
|
|
|
302859
303216
|
// packages/cli/dist/api/usage-tracker.js
|
|
302860
|
-
import { mkdirSync as
|
|
302861
|
-
import { join as
|
|
303217
|
+
import { mkdirSync as mkdirSync30, readFileSync as readFileSync48, writeFileSync as writeFileSync28, existsSync as existsSync60 } from "node:fs";
|
|
303218
|
+
import { join as join77 } from "node:path";
|
|
302862
303219
|
function initUsageTracker(oaDir) {
|
|
302863
|
-
const dir =
|
|
302864
|
-
|
|
302865
|
-
usageFile =
|
|
303220
|
+
const dir = join77(oaDir, "usage");
|
|
303221
|
+
mkdirSync30(dir, { recursive: true });
|
|
303222
|
+
usageFile = join77(dir, "token-usage.json");
|
|
302866
303223
|
try {
|
|
302867
|
-
if (
|
|
302868
|
-
store = JSON.parse(
|
|
303224
|
+
if (existsSync60(usageFile)) {
|
|
303225
|
+
store = JSON.parse(readFileSync48(usageFile, "utf-8"));
|
|
302869
303226
|
}
|
|
302870
303227
|
} catch {
|
|
302871
303228
|
store = { providers: {}, lastSaved: "" };
|
|
@@ -302905,7 +303262,7 @@ function flush2() {
|
|
|
302905
303262
|
return;
|
|
302906
303263
|
try {
|
|
302907
303264
|
store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
|
|
302908
|
-
|
|
303265
|
+
writeFileSync28(usageFile, JSON.stringify(store, null, 2), "utf-8");
|
|
302909
303266
|
dirty = false;
|
|
302910
303267
|
} catch {
|
|
302911
303268
|
}
|
|
@@ -302933,24 +303290,24 @@ var init_usage_tracker = __esm({
|
|
|
302933
303290
|
});
|
|
302934
303291
|
|
|
302935
303292
|
// packages/cli/dist/api/profiles.js
|
|
302936
|
-
import { existsSync as
|
|
302937
|
-
import { join as
|
|
302938
|
-
import { homedir as
|
|
303293
|
+
import { existsSync as existsSync61, readFileSync as readFileSync49, writeFileSync as writeFileSync29, mkdirSync as mkdirSync31, readdirSync as readdirSync22, unlinkSync as unlinkSync13 } from "node:fs";
|
|
303294
|
+
import { join as join78 } from "node:path";
|
|
303295
|
+
import { homedir as homedir22 } from "node:os";
|
|
302939
303296
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync3, createHash as createHash5 } from "node:crypto";
|
|
302940
303297
|
function globalProfileDir() {
|
|
302941
|
-
return
|
|
303298
|
+
return join78(homedir22(), ".open-agents", "profiles");
|
|
302942
303299
|
}
|
|
302943
303300
|
function projectProfileDir(projectDir) {
|
|
302944
|
-
return
|
|
303301
|
+
return join78(projectDir || process.cwd(), ".oa", "profiles");
|
|
302945
303302
|
}
|
|
302946
303303
|
function listProfiles(projectDir) {
|
|
302947
303304
|
const result = [];
|
|
302948
303305
|
const seen = /* @__PURE__ */ new Set();
|
|
302949
303306
|
const projDir = projectProfileDir(projectDir);
|
|
302950
|
-
if (
|
|
303307
|
+
if (existsSync61(projDir)) {
|
|
302951
303308
|
for (const f2 of readdirSync22(projDir).filter((f3) => f3.endsWith(".json"))) {
|
|
302952
303309
|
try {
|
|
302953
|
-
const raw = JSON.parse(
|
|
303310
|
+
const raw = JSON.parse(readFileSync49(join78(projDir, f2), "utf8"));
|
|
302954
303311
|
const name10 = f2.replace(".json", "");
|
|
302955
303312
|
seen.add(name10);
|
|
302956
303313
|
result.push({
|
|
@@ -302964,13 +303321,13 @@ function listProfiles(projectDir) {
|
|
|
302964
303321
|
}
|
|
302965
303322
|
}
|
|
302966
303323
|
const globDir = globalProfileDir();
|
|
302967
|
-
if (
|
|
303324
|
+
if (existsSync61(globDir)) {
|
|
302968
303325
|
for (const f2 of readdirSync22(globDir).filter((f3) => f3.endsWith(".json"))) {
|
|
302969
303326
|
const name10 = f2.replace(".json", "");
|
|
302970
303327
|
if (seen.has(name10))
|
|
302971
303328
|
continue;
|
|
302972
303329
|
try {
|
|
302973
|
-
const raw = JSON.parse(
|
|
303330
|
+
const raw = JSON.parse(readFileSync49(join78(globDir, f2), "utf8"));
|
|
302974
303331
|
result.push({
|
|
302975
303332
|
name: name10,
|
|
302976
303333
|
description: raw.description || "",
|
|
@@ -302985,12 +303342,12 @@ function listProfiles(projectDir) {
|
|
|
302985
303342
|
}
|
|
302986
303343
|
function loadProfile(name10, password, projectDir) {
|
|
302987
303344
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
302988
|
-
const projPath =
|
|
302989
|
-
const globPath =
|
|
302990
|
-
const filePath =
|
|
303345
|
+
const projPath = join78(projectProfileDir(projectDir), `${sanitized}.json`);
|
|
303346
|
+
const globPath = join78(globalProfileDir(), `${sanitized}.json`);
|
|
303347
|
+
const filePath = existsSync61(projPath) ? projPath : existsSync61(globPath) ? globPath : null;
|
|
302991
303348
|
if (!filePath)
|
|
302992
303349
|
return null;
|
|
302993
|
-
const raw = JSON.parse(
|
|
303350
|
+
const raw = JSON.parse(readFileSync49(filePath, "utf8"));
|
|
302994
303351
|
if (raw.encrypted === true) {
|
|
302995
303352
|
if (!password)
|
|
302996
303353
|
return null;
|
|
@@ -303000,24 +303357,24 @@ function loadProfile(name10, password, projectDir) {
|
|
|
303000
303357
|
}
|
|
303001
303358
|
function saveProfile(profile, password, scope = "global", projectDir) {
|
|
303002
303359
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
303003
|
-
|
|
303360
|
+
mkdirSync31(dir, { recursive: true });
|
|
303004
303361
|
const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
303005
|
-
const filePath =
|
|
303362
|
+
const filePath = join78(dir, `${sanitized}.json`);
|
|
303006
303363
|
profile.modified = (/* @__PURE__ */ new Date()).toISOString();
|
|
303007
303364
|
if (password) {
|
|
303008
303365
|
const encrypted = encryptProfile(profile, password);
|
|
303009
|
-
|
|
303366
|
+
writeFileSync29(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
303010
303367
|
} else {
|
|
303011
303368
|
profile.encrypted = false;
|
|
303012
|
-
|
|
303369
|
+
writeFileSync29(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
|
|
303013
303370
|
}
|
|
303014
303371
|
}
|
|
303015
303372
|
function deleteProfile(name10, scope = "global", projectDir) {
|
|
303016
303373
|
const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
303017
303374
|
const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
|
|
303018
|
-
const filePath =
|
|
303019
|
-
if (
|
|
303020
|
-
|
|
303375
|
+
const filePath = join78(dir, `${sanitized}.json`);
|
|
303376
|
+
if (existsSync61(filePath)) {
|
|
303377
|
+
unlinkSync13(filePath);
|
|
303021
303378
|
return true;
|
|
303022
303379
|
}
|
|
303023
303380
|
return false;
|
|
@@ -303130,24 +303487,24 @@ var init_profiles = __esm({
|
|
|
303130
303487
|
});
|
|
303131
303488
|
|
|
303132
303489
|
// packages/cli/dist/docker.js
|
|
303133
|
-
import { execSync as execSync37, spawn as
|
|
303134
|
-
import { existsSync as
|
|
303135
|
-
import { join as
|
|
303136
|
-
import { homedir as
|
|
303137
|
-
import { fileURLToPath as
|
|
303490
|
+
import { execSync as execSync37, spawn as spawn23 } from "node:child_process";
|
|
303491
|
+
import { existsSync as existsSync62, mkdirSync as mkdirSync32, writeFileSync as writeFileSync30 } from "node:fs";
|
|
303492
|
+
import { join as join79, resolve as resolve33, dirname as dirname23 } from "node:path";
|
|
303493
|
+
import { homedir as homedir23 } from "node:os";
|
|
303494
|
+
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
303138
303495
|
function getDockerDir() {
|
|
303139
303496
|
try {
|
|
303140
303497
|
if (typeof __dirname !== "undefined") {
|
|
303141
|
-
return
|
|
303498
|
+
return join79(__dirname, "..", "..", "..", "docker");
|
|
303142
303499
|
}
|
|
303143
303500
|
} catch {
|
|
303144
303501
|
}
|
|
303145
303502
|
try {
|
|
303146
|
-
const thisDir =
|
|
303147
|
-
return
|
|
303503
|
+
const thisDir = dirname23(fileURLToPath15(import.meta.url));
|
|
303504
|
+
return join79(thisDir, "..", "..", "..", "docker");
|
|
303148
303505
|
} catch {
|
|
303149
303506
|
}
|
|
303150
|
-
return
|
|
303507
|
+
return join79(process.cwd(), "docker");
|
|
303151
303508
|
}
|
|
303152
303509
|
function isDockerAvailable() {
|
|
303153
303510
|
try {
|
|
@@ -303278,11 +303635,11 @@ async function ensureOaImage(force = false) {
|
|
|
303278
303635
|
}
|
|
303279
303636
|
let buildContext;
|
|
303280
303637
|
const dockerDir = getDockerDir();
|
|
303281
|
-
if (
|
|
303638
|
+
if (existsSync62(join79(dockerDir, "Dockerfile"))) {
|
|
303282
303639
|
buildContext = dockerDir;
|
|
303283
303640
|
} else {
|
|
303284
|
-
buildContext =
|
|
303285
|
-
|
|
303641
|
+
buildContext = join79(homedir23(), ".oa", "docker-build");
|
|
303642
|
+
mkdirSync32(buildContext, { recursive: true });
|
|
303286
303643
|
writeDockerfiles(buildContext);
|
|
303287
303644
|
}
|
|
303288
303645
|
try {
|
|
@@ -303356,8 +303713,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
|
|
|
303356
303713
|
if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
|
|
303357
303714
|
exec "$@"
|
|
303358
303715
|
`;
|
|
303359
|
-
|
|
303360
|
-
|
|
303716
|
+
writeFileSync30(join79(dir, "Dockerfile"), dockerfile);
|
|
303717
|
+
writeFileSync30(join79(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
|
|
303361
303718
|
}
|
|
303362
303719
|
function hasNvidiaGpu() {
|
|
303363
303720
|
try {
|
|
@@ -303414,7 +303771,7 @@ function runInContainer(opts) {
|
|
|
303414
303771
|
if (opts.timeoutS)
|
|
303415
303772
|
oaArgs.push("--timeout", String(opts.timeoutS));
|
|
303416
303773
|
args.push(...oaArgs);
|
|
303417
|
-
return
|
|
303774
|
+
return spawn23("docker", args, {
|
|
303418
303775
|
stdio: ["ignore", "pipe", "pipe"]
|
|
303419
303776
|
});
|
|
303420
303777
|
}
|
|
@@ -303436,23 +303793,23 @@ __export(serve_exports, {
|
|
|
303436
303793
|
import * as http5 from "node:http";
|
|
303437
303794
|
import * as https3 from "node:https";
|
|
303438
303795
|
import { createRequire as createRequire4 } from "node:module";
|
|
303439
|
-
import { fileURLToPath as
|
|
303440
|
-
import { dirname as
|
|
303441
|
-
import { spawn as
|
|
303442
|
-
import { mkdirSync as
|
|
303796
|
+
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
303797
|
+
import { dirname as dirname24, join as join80, resolve as resolve34 } from "node:path";
|
|
303798
|
+
import { spawn as spawn24, execSync as execSync38 } from "node:child_process";
|
|
303799
|
+
import { mkdirSync as mkdirSync33, writeFileSync as writeFileSync31, readFileSync as readFileSync50, readdirSync as readdirSync23, existsSync as existsSync63 } from "node:fs";
|
|
303443
303800
|
import { randomBytes as randomBytes19, randomUUID as randomUUID5 } from "node:crypto";
|
|
303444
303801
|
function getVersion3() {
|
|
303445
303802
|
try {
|
|
303446
303803
|
const require3 = createRequire4(import.meta.url);
|
|
303447
|
-
const thisDir =
|
|
303804
|
+
const thisDir = dirname24(fileURLToPath16(import.meta.url));
|
|
303448
303805
|
const candidates = [
|
|
303449
|
-
|
|
303450
|
-
|
|
303451
|
-
|
|
303806
|
+
join80(thisDir, "..", "package.json"),
|
|
303807
|
+
join80(thisDir, "..", "..", "package.json"),
|
|
303808
|
+
join80(thisDir, "..", "..", "..", "package.json")
|
|
303452
303809
|
];
|
|
303453
303810
|
for (const pkgPath of candidates) {
|
|
303454
303811
|
try {
|
|
303455
|
-
if (!
|
|
303812
|
+
if (!existsSync63(pkgPath))
|
|
303456
303813
|
continue;
|
|
303457
303814
|
const pkg = require3(pkgPath);
|
|
303458
303815
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
@@ -303753,29 +304110,29 @@ function ollamaStream(ollamaUrl, path5, method, body, onData, onEnd, onError) {
|
|
|
303753
304110
|
}
|
|
303754
304111
|
function jobsDir() {
|
|
303755
304112
|
const root = resolve34(process.cwd());
|
|
303756
|
-
const dir =
|
|
303757
|
-
|
|
304113
|
+
const dir = join80(root, ".oa", "jobs");
|
|
304114
|
+
mkdirSync33(dir, { recursive: true });
|
|
303758
304115
|
return dir;
|
|
303759
304116
|
}
|
|
303760
304117
|
function loadJob(id) {
|
|
303761
|
-
const file =
|
|
303762
|
-
if (!
|
|
304118
|
+
const file = join80(jobsDir(), `${id}.json`);
|
|
304119
|
+
if (!existsSync63(file))
|
|
303763
304120
|
return null;
|
|
303764
304121
|
try {
|
|
303765
|
-
return JSON.parse(
|
|
304122
|
+
return JSON.parse(readFileSync50(file, "utf-8"));
|
|
303766
304123
|
} catch {
|
|
303767
304124
|
return null;
|
|
303768
304125
|
}
|
|
303769
304126
|
}
|
|
303770
304127
|
function listJobs() {
|
|
303771
304128
|
const dir = jobsDir();
|
|
303772
|
-
if (!
|
|
304129
|
+
if (!existsSync63(dir))
|
|
303773
304130
|
return [];
|
|
303774
304131
|
const files = readdirSync23(dir).filter((f2) => f2.endsWith(".json")).sort();
|
|
303775
304132
|
const jobs = [];
|
|
303776
304133
|
for (const file of files) {
|
|
303777
304134
|
try {
|
|
303778
|
-
jobs.push(JSON.parse(
|
|
304135
|
+
jobs.push(JSON.parse(readFileSync50(join80(dir, file), "utf-8")));
|
|
303779
304136
|
} catch {
|
|
303780
304137
|
}
|
|
303781
304138
|
}
|
|
@@ -304250,8 +304607,8 @@ async function handleV1Run(req2, res) {
|
|
|
304250
304607
|
if (workingDir) {
|
|
304251
304608
|
cwd4 = resolve34(workingDir);
|
|
304252
304609
|
} else if (isolate) {
|
|
304253
|
-
const wsDir =
|
|
304254
|
-
|
|
304610
|
+
const wsDir = join80(dir, "..", "workspaces", id);
|
|
304611
|
+
mkdirSync33(wsDir, { recursive: true });
|
|
304255
304612
|
cwd4 = wsDir;
|
|
304256
304613
|
} else {
|
|
304257
304614
|
cwd4 = resolve34(process.cwd());
|
|
@@ -304329,7 +304686,7 @@ async function handleV1Run(req2, res) {
|
|
|
304329
304686
|
});
|
|
304330
304687
|
job.sandbox = "container";
|
|
304331
304688
|
} else {
|
|
304332
|
-
child =
|
|
304689
|
+
child = spawn24(process.execPath, [oaBin, ...args], {
|
|
304333
304690
|
cwd: cwd4,
|
|
304334
304691
|
env: runEnv,
|
|
304335
304692
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -304339,7 +304696,7 @@ async function handleV1Run(req2, res) {
|
|
|
304339
304696
|
job.sandbox = sandbox;
|
|
304340
304697
|
}
|
|
304341
304698
|
job.pid = child.pid ?? 0;
|
|
304342
|
-
|
|
304699
|
+
writeFileSync31(join80(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
304343
304700
|
runningProcesses.set(id, child);
|
|
304344
304701
|
if (streamMode) {
|
|
304345
304702
|
res.writeHead(200, {
|
|
@@ -304366,7 +304723,7 @@ async function handleV1Run(req2, res) {
|
|
|
304366
304723
|
job.status = code8 === 0 ? "completed" : "failed";
|
|
304367
304724
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
304368
304725
|
try {
|
|
304369
|
-
|
|
304726
|
+
writeFileSync31(join80(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
304370
304727
|
} catch {
|
|
304371
304728
|
}
|
|
304372
304729
|
runningProcesses.delete(id);
|
|
@@ -304406,7 +304763,7 @@ async function handleV1Run(req2, res) {
|
|
|
304406
304763
|
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
304407
304764
|
}
|
|
304408
304765
|
try {
|
|
304409
|
-
|
|
304766
|
+
writeFileSync31(join80(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
304410
304767
|
} catch {
|
|
304411
304768
|
}
|
|
304412
304769
|
runningProcesses.delete(id);
|
|
@@ -304475,7 +304832,7 @@ function handleV1RunsDelete(res, id) {
|
|
|
304475
304832
|
job.error = "Aborted via API";
|
|
304476
304833
|
const dir = jobsDir();
|
|
304477
304834
|
try {
|
|
304478
|
-
|
|
304835
|
+
writeFileSync31(join80(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
304479
304836
|
} catch {
|
|
304480
304837
|
}
|
|
304481
304838
|
runningProcesses.delete(id);
|
|
@@ -304587,7 +304944,7 @@ async function handlePostCommand(res, cmd) {
|
|
|
304587
304944
|
return;
|
|
304588
304945
|
}
|
|
304589
304946
|
try {
|
|
304590
|
-
const child =
|
|
304947
|
+
const child = spawn24("node", [oaBin, "run", `/${cmd}`, "--json"], {
|
|
304591
304948
|
env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
|
|
304592
304949
|
stdio: ["ignore", "pipe", "pipe"],
|
|
304593
304950
|
timeout: 3e4
|
|
@@ -304797,7 +305154,7 @@ ${historyLines}
|
|
|
304797
305154
|
};
|
|
304798
305155
|
if (currentCfg.apiKey)
|
|
304799
305156
|
runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
304800
|
-
const child =
|
|
305157
|
+
const child = spawn24(process.execPath, [oaBin, ...args], {
|
|
304801
305158
|
cwd: cwdPath,
|
|
304802
305159
|
env: runEnv,
|
|
304803
305160
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -305168,24 +305525,24 @@ function startApiServer(options2 = {}) {
|
|
|
305168
305525
|
const config = loadConfig();
|
|
305169
305526
|
const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
|
|
305170
305527
|
const cwd4 = process.cwd();
|
|
305171
|
-
initAuditLog(
|
|
305172
|
-
initUsageTracker(
|
|
305528
|
+
initAuditLog(join80(cwd4, ".oa"));
|
|
305529
|
+
initUsageTracker(join80(cwd4, ".oa"));
|
|
305173
305530
|
const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
|
|
305174
305531
|
if (retentionDays > 0) {
|
|
305175
305532
|
try {
|
|
305176
|
-
const jobsDir3 =
|
|
305177
|
-
if (
|
|
305533
|
+
const jobsDir3 = join80(cwd4, ".oa", "jobs");
|
|
305534
|
+
if (existsSync63(jobsDir3)) {
|
|
305178
305535
|
const cutoff = Date.now() - retentionDays * 864e5;
|
|
305179
305536
|
for (const f2 of readdirSync23(jobsDir3)) {
|
|
305180
305537
|
if (!f2.endsWith(".json"))
|
|
305181
305538
|
continue;
|
|
305182
305539
|
try {
|
|
305183
|
-
const jobPath =
|
|
305184
|
-
const job = JSON.parse(
|
|
305540
|
+
const jobPath = join80(jobsDir3, f2);
|
|
305541
|
+
const job = JSON.parse(readFileSync50(jobPath, "utf-8"));
|
|
305185
305542
|
const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
|
|
305186
305543
|
if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
|
|
305187
|
-
const { unlinkSync:
|
|
305188
|
-
|
|
305544
|
+
const { unlinkSync: unlinkSync14 } = __require("node:fs");
|
|
305545
|
+
unlinkSync14(jobPath);
|
|
305189
305546
|
}
|
|
305190
305547
|
} catch {
|
|
305191
305548
|
}
|
|
@@ -305201,8 +305558,8 @@ function startApiServer(options2 = {}) {
|
|
|
305201
305558
|
if (useTls) {
|
|
305202
305559
|
try {
|
|
305203
305560
|
tlsOpts = {
|
|
305204
|
-
cert:
|
|
305205
|
-
key:
|
|
305561
|
+
cert: readFileSync50(resolve34(tlsCert)),
|
|
305562
|
+
key: readFileSync50(resolve34(tlsKey))
|
|
305206
305563
|
};
|
|
305207
305564
|
} catch (e2) {
|
|
305208
305565
|
log22(`
|
|
@@ -305401,13 +305758,13 @@ var init_serve = __esm({
|
|
|
305401
305758
|
|
|
305402
305759
|
// packages/cli/dist/tui/interactive.js
|
|
305403
305760
|
import { cwd } from "node:process";
|
|
305404
|
-
import { resolve as resolve35, join as
|
|
305761
|
+
import { resolve as resolve35, join as join81, dirname as dirname25, extname as extname11 } from "node:path";
|
|
305405
305762
|
import { createRequire as createRequire5 } from "node:module";
|
|
305406
|
-
import { fileURLToPath as
|
|
305407
|
-
import { readFileSync as
|
|
305408
|
-
import { existsSync as
|
|
305763
|
+
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
305764
|
+
import { readFileSync as readFileSync51, writeFileSync as writeFileSync32, appendFileSync as appendFileSync6, rmSync as rmSync4, readdirSync as readdirSync24, mkdirSync as mkdirSync34 } from "node:fs";
|
|
305765
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
305409
305766
|
import { execSync as execSync39 } from "node:child_process";
|
|
305410
|
-
import { homedir as
|
|
305767
|
+
import { homedir as homedir24 } from "node:os";
|
|
305411
305768
|
function formatTimeAgo(date) {
|
|
305412
305769
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
305413
305770
|
if (seconds < 60)
|
|
@@ -305424,14 +305781,14 @@ function formatTimeAgo(date) {
|
|
|
305424
305781
|
function getVersion4() {
|
|
305425
305782
|
try {
|
|
305426
305783
|
const require3 = createRequire5(import.meta.url);
|
|
305427
|
-
const thisDir =
|
|
305784
|
+
const thisDir = dirname25(fileURLToPath17(import.meta.url));
|
|
305428
305785
|
const candidates = [
|
|
305429
|
-
|
|
305430
|
-
|
|
305431
|
-
|
|
305786
|
+
join81(thisDir, "..", "package.json"),
|
|
305787
|
+
join81(thisDir, "..", "..", "package.json"),
|
|
305788
|
+
join81(thisDir, "..", "..", "..", "package.json")
|
|
305432
305789
|
];
|
|
305433
305790
|
for (const pkgPath of candidates) {
|
|
305434
|
-
if (
|
|
305791
|
+
if (existsSync64(pkgPath)) {
|
|
305435
305792
|
const pkg = require3(pkgPath);
|
|
305436
305793
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
|
|
305437
305794
|
return pkg.version ?? "0.0.0";
|
|
@@ -305885,15 +306242,15 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
|
|
|
305885
306242
|
function gatherMemorySnippets(root) {
|
|
305886
306243
|
const snippets = [];
|
|
305887
306244
|
const dirs = [
|
|
305888
|
-
|
|
305889
|
-
|
|
306245
|
+
join81(root, ".oa", "memory"),
|
|
306246
|
+
join81(root, ".open-agents", "memory")
|
|
305890
306247
|
];
|
|
305891
306248
|
for (const dir of dirs) {
|
|
305892
|
-
if (!
|
|
306249
|
+
if (!existsSync64(dir))
|
|
305893
306250
|
continue;
|
|
305894
306251
|
try {
|
|
305895
306252
|
for (const f2 of readdirSync24(dir).filter((f3) => f3.endsWith(".json"))) {
|
|
305896
|
-
const data = JSON.parse(
|
|
306253
|
+
const data = JSON.parse(readFileSync51(join81(dir, f2), "utf-8"));
|
|
305897
306254
|
for (const val of Object.values(data)) {
|
|
305898
306255
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
305899
306256
|
if (v.length > 10)
|
|
@@ -306050,9 +306407,9 @@ ${metabolismMemories}
|
|
|
306050
306407
|
} catch {
|
|
306051
306408
|
}
|
|
306052
306409
|
try {
|
|
306053
|
-
const archeFile =
|
|
306054
|
-
if (
|
|
306055
|
-
const variants = JSON.parse(
|
|
306410
|
+
const archeFile = join81(repoRoot, ".oa", "arche", "variants.json");
|
|
306411
|
+
if (existsSync64(archeFile)) {
|
|
306412
|
+
const variants = JSON.parse(readFileSync51(archeFile, "utf8"));
|
|
306056
306413
|
if (variants.length > 0) {
|
|
306057
306414
|
let filtered = variants;
|
|
306058
306415
|
if (taskType) {
|
|
@@ -306221,9 +306578,9 @@ RULES:
|
|
|
306221
306578
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
306222
306579
|
let identityInjection = "";
|
|
306223
306580
|
try {
|
|
306224
|
-
const ikStateFile =
|
|
306225
|
-
if (
|
|
306226
|
-
const selfState = JSON.parse(
|
|
306581
|
+
const ikStateFile = join81(repoRoot, ".oa", "identity", "self-state.json");
|
|
306582
|
+
if (existsSync64(ikStateFile)) {
|
|
306583
|
+
const selfState = JSON.parse(readFileSync51(ikStateFile, "utf8"));
|
|
306227
306584
|
const lines = [
|
|
306228
306585
|
`[Identity State v${selfState.version}]`,
|
|
306229
306586
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -306889,13 +307246,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
306889
307246
|
});
|
|
306890
307247
|
}
|
|
306891
307248
|
try {
|
|
306892
|
-
const ikDir =
|
|
306893
|
-
const ikFile =
|
|
307249
|
+
const ikDir = join81(repoRoot, ".oa", "identity");
|
|
307250
|
+
const ikFile = join81(ikDir, "self-state.json");
|
|
306894
307251
|
let ikState;
|
|
306895
|
-
if (
|
|
306896
|
-
ikState = JSON.parse(
|
|
307252
|
+
if (existsSync64(ikFile)) {
|
|
307253
|
+
ikState = JSON.parse(readFileSync51(ikFile, "utf8"));
|
|
306897
307254
|
} else {
|
|
306898
|
-
|
|
307255
|
+
mkdirSync34(ikDir, { recursive: true });
|
|
306899
307256
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
306900
307257
|
ikState = {
|
|
306901
307258
|
self_id: `oa-${machineId}`,
|
|
@@ -306956,7 +307313,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
306956
307313
|
}
|
|
306957
307314
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
306958
307315
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
306959
|
-
|
|
307316
|
+
writeFileSync32(ikFile, JSON.stringify(ikState, null, 2));
|
|
306960
307317
|
} catch (ikErr) {
|
|
306961
307318
|
try {
|
|
306962
307319
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -306971,9 +307328,9 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
306971
307328
|
} else {
|
|
306972
307329
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
306973
307330
|
try {
|
|
306974
|
-
const ikFile =
|
|
306975
|
-
if (
|
|
306976
|
-
const ikState = JSON.parse(
|
|
307331
|
+
const ikFile = join81(repoRoot, ".oa", "identity", "self-state.json");
|
|
307332
|
+
if (existsSync64(ikFile)) {
|
|
307333
|
+
const ikState = JSON.parse(readFileSync51(ikFile, "utf8"));
|
|
306977
307334
|
if (!ikState.stats)
|
|
306978
307335
|
ikState.stats = { queries_served: 0 };
|
|
306979
307336
|
ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
|
|
@@ -306987,7 +307344,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
306987
307344
|
ikState.version_history = ikState.version_history.slice(-200);
|
|
306988
307345
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
306989
307346
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
306990
|
-
|
|
307347
|
+
writeFileSync32(ikFile, JSON.stringify(ikState, null, 2));
|
|
306991
307348
|
}
|
|
306992
307349
|
} catch {
|
|
306993
307350
|
}
|
|
@@ -307084,10 +307441,10 @@ async function startInteractive(config, repoPath) {
|
|
|
307084
307441
|
process.stdin.pause();
|
|
307085
307442
|
}
|
|
307086
307443
|
try {
|
|
307087
|
-
const oaDir =
|
|
307088
|
-
const nexusPidFile =
|
|
307089
|
-
if (
|
|
307090
|
-
const pid = parseInt(
|
|
307444
|
+
const oaDir = join81(repoRoot, ".oa");
|
|
307445
|
+
const nexusPidFile = join81(oaDir, "nexus", "daemon.pid");
|
|
307446
|
+
if (existsSync64(nexusPidFile)) {
|
|
307447
|
+
const pid = parseInt(readFileSync51(nexusPidFile, "utf8").trim(), 10);
|
|
307091
307448
|
if (pid > 0) {
|
|
307092
307449
|
try {
|
|
307093
307450
|
process.kill(pid, 0);
|
|
@@ -307581,7 +307938,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
|
|
|
307581
307938
|
let p2pGateway = null;
|
|
307582
307939
|
let peerMesh = null;
|
|
307583
307940
|
let inferenceRouter = null;
|
|
307584
|
-
const secretVault = new SecretVault(
|
|
307941
|
+
const secretVault = new SecretVault(join81(repoRoot, ".oa", "vault.enc"));
|
|
307585
307942
|
let adminSessionKey = null;
|
|
307586
307943
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
307587
307944
|
const streamRenderer = new StreamRenderer();
|
|
@@ -307804,13 +308161,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
307804
308161
|
const hits = allCompletions.filter((c4) => c4.toLowerCase().startsWith(lower));
|
|
307805
308162
|
return [hits, line];
|
|
307806
308163
|
}
|
|
307807
|
-
const HISTORY_DIR =
|
|
307808
|
-
const HISTORY_FILE =
|
|
308164
|
+
const HISTORY_DIR = join81(homedir24(), ".open-agents");
|
|
308165
|
+
const HISTORY_FILE = join81(HISTORY_DIR, "repl-history");
|
|
307809
308166
|
const MAX_HISTORY_LINES = 500;
|
|
307810
308167
|
let savedHistory = [];
|
|
307811
308168
|
try {
|
|
307812
|
-
if (
|
|
307813
|
-
const raw =
|
|
308169
|
+
if (existsSync64(HISTORY_FILE)) {
|
|
308170
|
+
const raw = readFileSync51(HISTORY_FILE, "utf8").trim();
|
|
307814
308171
|
if (raw)
|
|
307815
308172
|
savedHistory = raw.split("\n").reverse();
|
|
307816
308173
|
}
|
|
@@ -307913,12 +308270,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
307913
308270
|
if (!line.trim())
|
|
307914
308271
|
return;
|
|
307915
308272
|
try {
|
|
307916
|
-
|
|
308273
|
+
mkdirSync34(HISTORY_DIR, { recursive: true });
|
|
307917
308274
|
appendFileSync6(HISTORY_FILE, line + "\n", "utf8");
|
|
307918
308275
|
if (Math.random() < 0.02) {
|
|
307919
|
-
const all2 =
|
|
308276
|
+
const all2 = readFileSync51(HISTORY_FILE, "utf8").trim().split("\n");
|
|
307920
308277
|
if (all2.length > MAX_HISTORY_LINES) {
|
|
307921
|
-
|
|
308278
|
+
writeFileSync32(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
307922
308279
|
}
|
|
307923
308280
|
}
|
|
307924
308281
|
} catch {
|
|
@@ -308095,10 +308452,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308095
308452
|
const { unlinkSync: _rmStale } = await import("node:fs");
|
|
308096
308453
|
const { homedir: _hdir } = await import("node:os");
|
|
308097
308454
|
for (const dp of [
|
|
308098
|
-
|
|
308099
|
-
|
|
308455
|
+
join81(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
|
|
308456
|
+
join81(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
|
|
308100
308457
|
]) {
|
|
308101
|
-
if (
|
|
308458
|
+
if (existsSync64(dp))
|
|
308102
308459
|
try {
|
|
308103
308460
|
_rmStale(dp);
|
|
308104
308461
|
} catch {
|
|
@@ -308110,9 +308467,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308110
308467
|
const autoNexus = new NexusTool(repoRoot);
|
|
308111
308468
|
const _registerNexusDaemon = () => {
|
|
308112
308469
|
try {
|
|
308113
|
-
const nexusPidFile =
|
|
308114
|
-
if (
|
|
308115
|
-
const nPid = parseInt(
|
|
308470
|
+
const nexusPidFile = join81(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
308471
|
+
if (existsSync64(nexusPidFile)) {
|
|
308472
|
+
const nPid = parseInt(readFileSync51(nexusPidFile, "utf8").trim(), 10);
|
|
308116
308473
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
308117
308474
|
registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
|
|
308118
308475
|
statusBar.ensureMonitorTimer();
|
|
@@ -308153,7 +308510,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308153
308510
|
} catch {
|
|
308154
308511
|
}
|
|
308155
308512
|
try {
|
|
308156
|
-
const oaDir =
|
|
308513
|
+
const oaDir = join81(repoRoot, ".oa");
|
|
308157
308514
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
308158
308515
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
308159
308516
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -308185,7 +308542,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308185
308542
|
} catch {
|
|
308186
308543
|
}
|
|
308187
308544
|
try {
|
|
308188
|
-
const oaDir =
|
|
308545
|
+
const oaDir = join81(repoRoot, ".oa");
|
|
308189
308546
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
308190
308547
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
308191
308548
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -308226,11 +308583,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308226
308583
|
}
|
|
308227
308584
|
try {
|
|
308228
308585
|
const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
|
|
308229
|
-
const globalNamePath =
|
|
308586
|
+
const globalNamePath = join81(_hd(), ".open-agents", "agent-name");
|
|
308230
308587
|
let agName = "";
|
|
308231
308588
|
try {
|
|
308232
|
-
if (
|
|
308233
|
-
agName =
|
|
308589
|
+
if (existsSync64(globalNamePath))
|
|
308590
|
+
agName = readFileSync51(globalNamePath, "utf8").trim();
|
|
308234
308591
|
} catch {
|
|
308235
308592
|
}
|
|
308236
308593
|
if (!agName) {
|
|
@@ -308259,11 +308616,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308259
308616
|
}
|
|
308260
308617
|
if (!ollamaAlive) {
|
|
308261
308618
|
try {
|
|
308262
|
-
const savedSponsorsPath =
|
|
308619
|
+
const savedSponsorsPath = join81(repoRoot, ".oa", "sponsor", "known-sponsors.json");
|
|
308263
308620
|
let savedSponsors = [];
|
|
308264
308621
|
try {
|
|
308265
|
-
if (
|
|
308266
|
-
savedSponsors = JSON.parse(
|
|
308622
|
+
if (existsSync64(savedSponsorsPath)) {
|
|
308623
|
+
savedSponsors = JSON.parse(readFileSync51(savedSponsorsPath, "utf8"));
|
|
308267
308624
|
const oneHourAgo = Date.now() - 36e5;
|
|
308268
308625
|
savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
|
|
308269
308626
|
}
|
|
@@ -308327,18 +308684,33 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
308327
308684
|
});
|
|
308328
308685
|
setupTasks.push(startupChecksPromise.catch(() => {
|
|
308329
308686
|
}));
|
|
308330
|
-
Promise.resolve().then(() => (
|
|
308687
|
+
Promise.resolve().then(() => (init_daemon(), daemon_exports)).then(async ({ ensureDaemon: ensureDaemon2, isDaemonRunning: isDaemonRunning2 }) => {
|
|
308331
308688
|
const apiPort = parseInt(process.env["OA_PORT"] || "11435", 10);
|
|
308689
|
+
if (await isDaemonRunning2(apiPort)) {
|
|
308690
|
+
setTimeout(() => {
|
|
308691
|
+
if (statusBar.isActive)
|
|
308692
|
+
writeContent(() => renderInfo(`REST API: http://localhost:${apiPort} (shared daemon)`));
|
|
308693
|
+
}, 1500);
|
|
308694
|
+
return;
|
|
308695
|
+
}
|
|
308696
|
+
const daemonOk = await ensureDaemon2();
|
|
308697
|
+
if (daemonOk) {
|
|
308698
|
+
setTimeout(() => {
|
|
308699
|
+
if (statusBar.isActive)
|
|
308700
|
+
writeContent(() => renderInfo(`REST API: http://localhost:${apiPort} (daemon started)`));
|
|
308701
|
+
}, 1500);
|
|
308702
|
+
return;
|
|
308703
|
+
}
|
|
308704
|
+
const { startApiServer: startApiServer2 } = await Promise.resolve().then(() => (init_serve(), serve_exports));
|
|
308332
308705
|
const apiServer = startApiServer2({
|
|
308333
308706
|
port: apiPort,
|
|
308334
308707
|
ollamaUrl: currentConfig.backendUrl || "http://127.0.0.1:11434",
|
|
308335
308708
|
quiet: true
|
|
308336
|
-
// TUI mode — suppress all direct stderr/stdout output
|
|
308337
308709
|
});
|
|
308338
308710
|
apiServer.on?.("listening", () => {
|
|
308339
308711
|
setTimeout(() => {
|
|
308340
308712
|
if (statusBar.isActive)
|
|
308341
|
-
writeContent(() => renderInfo(`REST API: http://localhost:${apiPort}`));
|
|
308713
|
+
writeContent(() => renderInfo(`REST API: http://localhost:${apiPort} (inline \u2014 daemon unavailable)`));
|
|
308342
308714
|
}, 1500);
|
|
308343
308715
|
});
|
|
308344
308716
|
apiServer.on?.("error", () => {
|
|
@@ -309223,7 +309595,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309223
309595
|
kind,
|
|
309224
309596
|
targetUrl,
|
|
309225
309597
|
authKey,
|
|
309226
|
-
stateDir:
|
|
309598
|
+
stateDir: join81(repoRoot, ".oa"),
|
|
309227
309599
|
passthrough: passthrough ?? false,
|
|
309228
309600
|
loadbalance: loadbalance ?? false,
|
|
309229
309601
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -309269,7 +309641,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309269
309641
|
await tunnelGateway.stop();
|
|
309270
309642
|
tunnelGateway = null;
|
|
309271
309643
|
}
|
|
309272
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
309644
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join81(repoRoot, ".oa") });
|
|
309273
309645
|
newTunnel.on("stats", (stats) => {
|
|
309274
309646
|
statusBar.setExposeStatus({
|
|
309275
309647
|
status: stats.status,
|
|
@@ -309358,9 +309730,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309358
309730
|
if (!result.success)
|
|
309359
309731
|
throw new Error(result.error || "Connect failed");
|
|
309360
309732
|
try {
|
|
309361
|
-
const nexusPidFile =
|
|
309362
|
-
if (
|
|
309363
|
-
const pid = parseInt(
|
|
309733
|
+
const nexusPidFile = join81(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
309734
|
+
if (existsSync64(nexusPidFile)) {
|
|
309735
|
+
const pid = parseInt(readFileSync51(nexusPidFile, "utf8").trim(), 10);
|
|
309364
309736
|
if (pid > 0) {
|
|
309365
309737
|
registry2.register({
|
|
309366
309738
|
name: "Nexus",
|
|
@@ -309556,10 +309928,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309556
309928
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
309557
309929
|
}
|
|
309558
309930
|
try {
|
|
309559
|
-
const nexusDir =
|
|
309560
|
-
const pidFile =
|
|
309561
|
-
if (
|
|
309562
|
-
const pid = parseInt(
|
|
309931
|
+
const nexusDir = join81(repoRoot, OA_DIR, "nexus");
|
|
309932
|
+
const pidFile = join81(nexusDir, "daemon.pid");
|
|
309933
|
+
if (existsSync64(pidFile)) {
|
|
309934
|
+
const pid = parseInt(readFileSync51(pidFile, "utf8").trim(), 10);
|
|
309563
309935
|
if (pid > 0) {
|
|
309564
309936
|
try {
|
|
309565
309937
|
if (process.platform === "win32") {
|
|
@@ -309581,13 +309953,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309581
309953
|
} catch {
|
|
309582
309954
|
}
|
|
309583
309955
|
try {
|
|
309584
|
-
const voiceDir2 =
|
|
309956
|
+
const voiceDir2 = join81(homedir24(), ".open-agents", "voice");
|
|
309585
309957
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
309586
309958
|
for (const pf of voicePidFiles) {
|
|
309587
|
-
const pidPath =
|
|
309588
|
-
if (
|
|
309959
|
+
const pidPath = join81(voiceDir2, pf);
|
|
309960
|
+
if (existsSync64(pidPath)) {
|
|
309589
309961
|
try {
|
|
309590
|
-
const pid = parseInt(
|
|
309962
|
+
const pid = parseInt(readFileSync51(pidPath, "utf8").trim(), 10);
|
|
309591
309963
|
if (pid > 0) {
|
|
309592
309964
|
if (process.platform === "win32") {
|
|
309593
309965
|
try {
|
|
@@ -309611,8 +309983,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309611
309983
|
execSync39(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
309612
309984
|
} catch {
|
|
309613
309985
|
}
|
|
309614
|
-
const oaPath =
|
|
309615
|
-
if (
|
|
309986
|
+
const oaPath = join81(repoRoot, OA_DIR);
|
|
309987
|
+
if (existsSync64(oaPath)) {
|
|
309616
309988
|
let deleted = false;
|
|
309617
309989
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
309618
309990
|
try {
|
|
@@ -309695,19 +310067,19 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
309695
310067
|
try {
|
|
309696
310068
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
309697
310069
|
if (isPersonaPlexRunning2()) {
|
|
309698
|
-
const ppPidFile =
|
|
309699
|
-
const ppPortFile =
|
|
309700
|
-
if (
|
|
309701
|
-
const ppPid = parseInt(
|
|
309702
|
-
const ppPort =
|
|
310070
|
+
const ppPidFile = join81(homedir24(), ".open-agents", "voice", "personaplex", "daemon.pid");
|
|
310071
|
+
const ppPortFile = join81(homedir24(), ".open-agents", "voice", "personaplex", "daemon.port");
|
|
310072
|
+
if (existsSync64(ppPidFile)) {
|
|
310073
|
+
const ppPid = parseInt(readFileSync51(ppPidFile, "utf8").trim(), 10);
|
|
310074
|
+
const ppPort = existsSync64(ppPortFile) ? parseInt(readFileSync51(ppPortFile, "utf8").trim(), 10) : void 0;
|
|
309703
310075
|
if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
|
|
309704
310076
|
registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
|
|
309705
310077
|
}
|
|
309706
310078
|
}
|
|
309707
310079
|
}
|
|
309708
|
-
const nexusPidFile =
|
|
309709
|
-
if (
|
|
309710
|
-
const nPid = parseInt(
|
|
310080
|
+
const nexusPidFile = join81(repoRoot, ".oa", "nexus", "daemon.pid");
|
|
310081
|
+
if (existsSync64(nexusPidFile)) {
|
|
310082
|
+
const nPid = parseInt(readFileSync51(nexusPidFile, "utf8").trim(), 10);
|
|
309711
310083
|
if (nPid > 0 && !registry2.daemons.has("Nexus")) {
|
|
309712
310084
|
try {
|
|
309713
310085
|
process.kill(nPid, 0);
|
|
@@ -310049,8 +310421,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
310049
310421
|
}
|
|
310050
310422
|
}
|
|
310051
310423
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
310052
|
-
const isImage = isImagePath(cleanPath) &&
|
|
310053
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
310424
|
+
const isImage = isImagePath(cleanPath) && existsSync64(resolve35(repoRoot, cleanPath));
|
|
310425
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync64(resolve35(repoRoot, cleanPath));
|
|
310054
310426
|
if (activeTask) {
|
|
310055
310427
|
if (activeTask.runner.isPaused) {
|
|
310056
310428
|
activeTask.runner.resume();
|
|
@@ -310059,7 +310431,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
310059
310431
|
if (isImage) {
|
|
310060
310432
|
try {
|
|
310061
310433
|
const imgPath = resolve35(repoRoot, cleanPath);
|
|
310062
|
-
const imgBuffer =
|
|
310434
|
+
const imgBuffer = readFileSync51(imgPath);
|
|
310063
310435
|
const base642 = imgBuffer.toString("base64");
|
|
310064
310436
|
const ext = extname11(cleanPath).toLowerCase();
|
|
310065
310437
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -310274,7 +310646,7 @@ Summarize or analyze this transcription as appropriate.`;
|
|
|
310274
310646
|
|
|
310275
310647
|
NEW TASK: ${fullInput}`;
|
|
310276
310648
|
restoredSessionContext = null;
|
|
310277
|
-
} else if (
|
|
310649
|
+
} else if (existsSync64(join81(repoRoot, ".oa", "context", "session-diary.md"))) {
|
|
310278
310650
|
taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
|
|
310279
310651
|
|
|
310280
310652
|
${fullInput}`;
|
|
@@ -310592,13 +310964,13 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
310592
310964
|
const handle2 = startTask(task, config, repoRoot);
|
|
310593
310965
|
await handle2.promise;
|
|
310594
310966
|
try {
|
|
310595
|
-
const ikDir =
|
|
310596
|
-
const ikFile =
|
|
310967
|
+
const ikDir = join81(repoRoot, ".oa", "identity");
|
|
310968
|
+
const ikFile = join81(ikDir, "self-state.json");
|
|
310597
310969
|
let ikState;
|
|
310598
|
-
if (
|
|
310599
|
-
ikState = JSON.parse(
|
|
310970
|
+
if (existsSync64(ikFile)) {
|
|
310971
|
+
ikState = JSON.parse(readFileSync51(ikFile, "utf8"));
|
|
310600
310972
|
} else {
|
|
310601
|
-
|
|
310973
|
+
mkdirSync34(ikDir, { recursive: true });
|
|
310602
310974
|
ikState = {
|
|
310603
310975
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
310604
310976
|
version: 1,
|
|
@@ -310620,7 +310992,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
310620
310992
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
310621
310993
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
310622
310994
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
310623
|
-
|
|
310995
|
+
writeFileSync32(ikFile, JSON.stringify(ikState, null, 2));
|
|
310624
310996
|
} catch (ikErr) {
|
|
310625
310997
|
}
|
|
310626
310998
|
try {
|
|
@@ -310629,12 +311001,12 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
310629
311001
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
310630
311002
|
} catch {
|
|
310631
311003
|
try {
|
|
310632
|
-
const archeDir =
|
|
310633
|
-
const archeFile =
|
|
311004
|
+
const archeDir = join81(repoRoot, ".oa", "arche");
|
|
311005
|
+
const archeFile = join81(archeDir, "variants.json");
|
|
310634
311006
|
let variants = [];
|
|
310635
311007
|
try {
|
|
310636
|
-
if (
|
|
310637
|
-
variants = JSON.parse(
|
|
311008
|
+
if (existsSync64(archeFile))
|
|
311009
|
+
variants = JSON.parse(readFileSync51(archeFile, "utf8"));
|
|
310638
311010
|
} catch {
|
|
310639
311011
|
}
|
|
310640
311012
|
variants.push({
|
|
@@ -310649,15 +311021,15 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
310649
311021
|
});
|
|
310650
311022
|
if (variants.length > 50)
|
|
310651
311023
|
variants = variants.slice(-50);
|
|
310652
|
-
|
|
310653
|
-
|
|
311024
|
+
mkdirSync34(archeDir, { recursive: true });
|
|
311025
|
+
writeFileSync32(archeFile, JSON.stringify(variants, null, 2));
|
|
310654
311026
|
} catch {
|
|
310655
311027
|
}
|
|
310656
311028
|
}
|
|
310657
311029
|
try {
|
|
310658
|
-
const metaFile =
|
|
310659
|
-
if (
|
|
310660
|
-
const store2 = JSON.parse(
|
|
311030
|
+
const metaFile = join81(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
311031
|
+
if (existsSync64(metaFile)) {
|
|
311032
|
+
const store2 = JSON.parse(readFileSync51(metaFile, "utf8"));
|
|
310661
311033
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
310662
311034
|
let updated = false;
|
|
310663
311035
|
for (const item of surfaced) {
|
|
@@ -310668,7 +311040,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
|
|
|
310668
311040
|
updated = true;
|
|
310669
311041
|
}
|
|
310670
311042
|
if (updated) {
|
|
310671
|
-
|
|
311043
|
+
writeFileSync32(metaFile, JSON.stringify(store2, null, 2));
|
|
310672
311044
|
}
|
|
310673
311045
|
}
|
|
310674
311046
|
} catch {
|
|
@@ -310721,9 +311093,9 @@ Rules:
|
|
|
310721
311093
|
try {
|
|
310722
311094
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
310723
311095
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
310724
|
-
const dbDir =
|
|
310725
|
-
|
|
310726
|
-
const db = initDb2(
|
|
311096
|
+
const dbDir = join81(repoRoot, ".oa", "memory");
|
|
311097
|
+
mkdirSync34(dbDir, { recursive: true });
|
|
311098
|
+
const db = initDb2(join81(dbDir, "structured.db"));
|
|
310727
311099
|
const memStore = new ProceduralMemoryStore2(db);
|
|
310728
311100
|
memStore.createWithEmbedding({
|
|
310729
311101
|
content: content.slice(0, 600),
|
|
@@ -310738,12 +311110,12 @@ Rules:
|
|
|
310738
311110
|
db.close();
|
|
310739
311111
|
} catch {
|
|
310740
311112
|
}
|
|
310741
|
-
const metaDir =
|
|
310742
|
-
const storeFile =
|
|
311113
|
+
const metaDir = join81(repoRoot, ".oa", "memory", "metabolism");
|
|
311114
|
+
const storeFile = join81(metaDir, "store.json");
|
|
310743
311115
|
let store2 = [];
|
|
310744
311116
|
try {
|
|
310745
|
-
if (
|
|
310746
|
-
store2 = JSON.parse(
|
|
311117
|
+
if (existsSync64(storeFile))
|
|
311118
|
+
store2 = JSON.parse(readFileSync51(storeFile, "utf8"));
|
|
310747
311119
|
} catch {
|
|
310748
311120
|
}
|
|
310749
311121
|
store2.push({
|
|
@@ -310759,26 +311131,26 @@ Rules:
|
|
|
310759
311131
|
});
|
|
310760
311132
|
if (store2.length > 100)
|
|
310761
311133
|
store2 = store2.slice(-100);
|
|
310762
|
-
|
|
310763
|
-
|
|
311134
|
+
mkdirSync34(metaDir, { recursive: true });
|
|
311135
|
+
writeFileSync32(storeFile, JSON.stringify(store2, null, 2));
|
|
310764
311136
|
}
|
|
310765
311137
|
}
|
|
310766
311138
|
} catch {
|
|
310767
311139
|
}
|
|
310768
311140
|
try {
|
|
310769
|
-
const cohereSettingsFile =
|
|
311141
|
+
const cohereSettingsFile = join81(repoRoot, ".oa", "settings.json");
|
|
310770
311142
|
let cohereActive = false;
|
|
310771
311143
|
try {
|
|
310772
|
-
if (
|
|
310773
|
-
const settings = JSON.parse(
|
|
311144
|
+
if (existsSync64(cohereSettingsFile)) {
|
|
311145
|
+
const settings = JSON.parse(readFileSync51(cohereSettingsFile, "utf8"));
|
|
310774
311146
|
cohereActive = settings.cohere === true;
|
|
310775
311147
|
}
|
|
310776
311148
|
} catch {
|
|
310777
311149
|
}
|
|
310778
311150
|
if (cohereActive) {
|
|
310779
|
-
const metaFile =
|
|
310780
|
-
if (
|
|
310781
|
-
const store2 = JSON.parse(
|
|
311151
|
+
const metaFile = join81(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
311152
|
+
if (existsSync64(metaFile)) {
|
|
311153
|
+
const store2 = JSON.parse(readFileSync51(metaFile, "utf8"));
|
|
310782
311154
|
const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
310783
311155
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
310784
311156
|
try {
|
|
@@ -310803,18 +311175,18 @@ Rules:
|
|
|
310803
311175
|
}
|
|
310804
311176
|
} catch (err) {
|
|
310805
311177
|
try {
|
|
310806
|
-
const ikFile =
|
|
310807
|
-
if (
|
|
310808
|
-
const ikState = JSON.parse(
|
|
311178
|
+
const ikFile = join81(repoRoot, ".oa", "identity", "self-state.json");
|
|
311179
|
+
if (existsSync64(ikFile)) {
|
|
311180
|
+
const ikState = JSON.parse(readFileSync51(ikFile, "utf8"));
|
|
310809
311181
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
310810
311182
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
310811
311183
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
310812
311184
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
310813
|
-
|
|
311185
|
+
writeFileSync32(ikFile, JSON.stringify(ikState, null, 2));
|
|
310814
311186
|
}
|
|
310815
|
-
const metaFile =
|
|
310816
|
-
if (
|
|
310817
|
-
const store2 = JSON.parse(
|
|
311187
|
+
const metaFile = join81(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
311188
|
+
if (existsSync64(metaFile)) {
|
|
311189
|
+
const store2 = JSON.parse(readFileSync51(metaFile, "utf8"));
|
|
310818
311190
|
const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
|
|
310819
311191
|
for (const item of surfaced) {
|
|
310820
311192
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -310822,15 +311194,15 @@ Rules:
|
|
|
310822
311194
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
310823
311195
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
310824
311196
|
}
|
|
310825
|
-
|
|
311197
|
+
writeFileSync32(metaFile, JSON.stringify(store2, null, 2));
|
|
310826
311198
|
}
|
|
310827
311199
|
try {
|
|
310828
|
-
const archeDir =
|
|
310829
|
-
const archeFile =
|
|
311200
|
+
const archeDir = join81(repoRoot, ".oa", "arche");
|
|
311201
|
+
const archeFile = join81(archeDir, "variants.json");
|
|
310830
311202
|
let variants = [];
|
|
310831
311203
|
try {
|
|
310832
|
-
if (
|
|
310833
|
-
variants = JSON.parse(
|
|
311204
|
+
if (existsSync64(archeFile))
|
|
311205
|
+
variants = JSON.parse(readFileSync51(archeFile, "utf8"));
|
|
310834
311206
|
} catch {
|
|
310835
311207
|
}
|
|
310836
311208
|
variants.push({
|
|
@@ -310845,8 +311217,8 @@ Rules:
|
|
|
310845
311217
|
});
|
|
310846
311218
|
if (variants.length > 50)
|
|
310847
311219
|
variants = variants.slice(-50);
|
|
310848
|
-
|
|
310849
|
-
|
|
311220
|
+
mkdirSync34(archeDir, { recursive: true });
|
|
311221
|
+
writeFileSync32(archeFile, JSON.stringify(variants, null, 2));
|
|
310850
311222
|
} catch {
|
|
310851
311223
|
}
|
|
310852
311224
|
} catch {
|
|
@@ -310924,14 +311296,14 @@ __export(run_exports, {
|
|
|
310924
311296
|
statusCommand: () => statusCommand
|
|
310925
311297
|
});
|
|
310926
311298
|
import { resolve as resolve36 } from "node:path";
|
|
310927
|
-
import { spawn as
|
|
310928
|
-
import { mkdirSync as
|
|
311299
|
+
import { spawn as spawn25 } from "node:child_process";
|
|
311300
|
+
import { mkdirSync as mkdirSync35, writeFileSync as writeFileSync33, readFileSync as readFileSync52, readdirSync as readdirSync25, existsSync as existsSync65 } from "node:fs";
|
|
310929
311301
|
import { randomBytes as randomBytes20 } from "node:crypto";
|
|
310930
|
-
import { join as
|
|
311302
|
+
import { join as join82 } from "node:path";
|
|
310931
311303
|
function jobsDir2(repoPath) {
|
|
310932
311304
|
const root = resolve36(repoPath ?? process.cwd());
|
|
310933
|
-
const dir =
|
|
310934
|
-
|
|
311305
|
+
const dir = join82(root, ".oa", "jobs");
|
|
311306
|
+
mkdirSync35(dir, { recursive: true });
|
|
310935
311307
|
return dir;
|
|
310936
311308
|
}
|
|
310937
311309
|
async function runCommand(opts, config) {
|
|
@@ -311034,7 +311406,7 @@ async function runBackground(task, config, opts) {
|
|
|
311034
311406
|
const args = [task, "--json"];
|
|
311035
311407
|
if (config.model)
|
|
311036
311408
|
args.push("--model", config.model);
|
|
311037
|
-
const child =
|
|
311409
|
+
const child = spawn25(process.execPath, [oaBin, ...args], {
|
|
311038
311410
|
cwd: repoRoot,
|
|
311039
311411
|
env: { ...process.env, OA_JOB_ID: id },
|
|
311040
311412
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -311050,7 +311422,7 @@ async function runBackground(task, config, opts) {
|
|
|
311050
311422
|
}
|
|
311051
311423
|
});
|
|
311052
311424
|
job.pid = child.pid ?? 0;
|
|
311053
|
-
|
|
311425
|
+
writeFileSync33(join82(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311054
311426
|
let output = "";
|
|
311055
311427
|
child.stdout?.on("data", (chunk) => {
|
|
311056
311428
|
output += chunk.toString();
|
|
@@ -311066,7 +311438,7 @@ async function runBackground(task, config, opts) {
|
|
|
311066
311438
|
job.summary = result.summary;
|
|
311067
311439
|
job.durationMs = result.durationMs;
|
|
311068
311440
|
job.error = result.error;
|
|
311069
|
-
|
|
311441
|
+
writeFileSync33(join82(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
311070
311442
|
} catch {
|
|
311071
311443
|
}
|
|
311072
311444
|
});
|
|
@@ -311082,13 +311454,13 @@ async function runBackground(task, config, opts) {
|
|
|
311082
311454
|
}
|
|
311083
311455
|
function statusCommand(jobId, repoPath) {
|
|
311084
311456
|
const dir = jobsDir2(repoPath);
|
|
311085
|
-
const file =
|
|
311086
|
-
if (!
|
|
311457
|
+
const file = join82(dir, `${jobId}.json`);
|
|
311458
|
+
if (!existsSync65(file)) {
|
|
311087
311459
|
console.error(`Job not found: ${jobId}`);
|
|
311088
311460
|
console.log(`Available jobs: oa jobs`);
|
|
311089
311461
|
process.exit(1);
|
|
311090
311462
|
}
|
|
311091
|
-
const job = JSON.parse(
|
|
311463
|
+
const job = JSON.parse(readFileSync52(file, "utf-8"));
|
|
311092
311464
|
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`;
|
|
311093
311465
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
311094
311466
|
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
@@ -311111,7 +311483,7 @@ function jobsCommand(repoPath) {
|
|
|
311111
311483
|
console.log("Jobs:");
|
|
311112
311484
|
for (const file of files) {
|
|
311113
311485
|
try {
|
|
311114
|
-
const job = JSON.parse(
|
|
311486
|
+
const job = JSON.parse(readFileSync52(join82(dir, file), "utf-8"));
|
|
311115
311487
|
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
311116
311488
|
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`;
|
|
311117
311489
|
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
@@ -311131,7 +311503,7 @@ import { glob as glob2 } from "glob";
|
|
|
311131
311503
|
import ignore from "ignore";
|
|
311132
311504
|
import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
|
|
311133
311505
|
import { createHash as createHash6 } from "node:crypto";
|
|
311134
|
-
import { join as
|
|
311506
|
+
import { join as join83, relative as relative4, extname as extname12, basename as basename18 } from "node:path";
|
|
311135
311507
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
311136
311508
|
var init_codebase_indexer = __esm({
|
|
311137
311509
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -311175,7 +311547,7 @@ var init_codebase_indexer = __esm({
|
|
|
311175
311547
|
const ig = ignore.default();
|
|
311176
311548
|
if (this.config.respectGitignore) {
|
|
311177
311549
|
try {
|
|
311178
|
-
const gitignoreContent = await readFile23(
|
|
311550
|
+
const gitignoreContent = await readFile23(join83(this.config.rootDir, ".gitignore"), "utf-8");
|
|
311179
311551
|
ig.add(gitignoreContent);
|
|
311180
311552
|
} catch {
|
|
311181
311553
|
}
|
|
@@ -311190,7 +311562,7 @@ var init_codebase_indexer = __esm({
|
|
|
311190
311562
|
for (const relativePath of files) {
|
|
311191
311563
|
if (ig.ignores(relativePath))
|
|
311192
311564
|
continue;
|
|
311193
|
-
const fullPath =
|
|
311565
|
+
const fullPath = join83(this.config.rootDir, relativePath);
|
|
311194
311566
|
try {
|
|
311195
311567
|
const fileStat = await stat5(fullPath);
|
|
311196
311568
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -311236,7 +311608,7 @@ var init_codebase_indexer = __esm({
|
|
|
311236
311608
|
if (!child) {
|
|
311237
311609
|
child = {
|
|
311238
311610
|
name: part,
|
|
311239
|
-
path:
|
|
311611
|
+
path: join83(current.path, part),
|
|
311240
311612
|
type: "directory",
|
|
311241
311613
|
children: []
|
|
311242
311614
|
};
|
|
@@ -311319,13 +311691,13 @@ __export(index_repo_exports, {
|
|
|
311319
311691
|
indexRepoCommand: () => indexRepoCommand
|
|
311320
311692
|
});
|
|
311321
311693
|
import { resolve as resolve37 } from "node:path";
|
|
311322
|
-
import { existsSync as
|
|
311694
|
+
import { existsSync as existsSync66, statSync as statSync17 } from "node:fs";
|
|
311323
311695
|
import { cwd as cwd2 } from "node:process";
|
|
311324
311696
|
async function indexRepoCommand(opts, _config2) {
|
|
311325
311697
|
const repoRoot = resolve37(opts.repoPath ?? cwd2());
|
|
311326
311698
|
printHeader("Index Repository");
|
|
311327
311699
|
printInfo(`Indexing: ${repoRoot}`);
|
|
311328
|
-
if (!
|
|
311700
|
+
if (!existsSync66(repoRoot)) {
|
|
311329
311701
|
printError(`Path does not exist: ${repoRoot}`);
|
|
311330
311702
|
process.exit(1);
|
|
311331
311703
|
}
|
|
@@ -311577,8 +311949,8 @@ var config_exports2 = {};
|
|
|
311577
311949
|
__export(config_exports2, {
|
|
311578
311950
|
configCommand: () => configCommand
|
|
311579
311951
|
});
|
|
311580
|
-
import { join as
|
|
311581
|
-
import { homedir as
|
|
311952
|
+
import { join as join84, resolve as resolve38 } from "node:path";
|
|
311953
|
+
import { homedir as homedir25 } from "node:os";
|
|
311582
311954
|
import { cwd as cwd3 } from "node:process";
|
|
311583
311955
|
function redactIfSensitive(key, value2) {
|
|
311584
311956
|
if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
|
|
@@ -311660,7 +312032,7 @@ function handleShow(opts, config) {
|
|
|
311660
312032
|
}
|
|
311661
312033
|
}
|
|
311662
312034
|
printSection("Config File");
|
|
311663
|
-
printInfo(`~/.open-agents/config.json (${
|
|
312035
|
+
printInfo(`~/.open-agents/config.json (${join84(homedir25(), ".open-agents", "config.json")})`);
|
|
311664
312036
|
printSection("Priority Chain");
|
|
311665
312037
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
311666
312038
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -311699,7 +312071,7 @@ function handleSet(opts, _config2) {
|
|
|
311699
312071
|
const coerced = coerceForSettings(key, value2);
|
|
311700
312072
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
311701
312073
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
|
|
311702
|
-
printInfo(`Saved to ${
|
|
312074
|
+
printInfo(`Saved to ${join84(repoRoot, ".oa", "settings.json")}`);
|
|
311703
312075
|
printInfo("This override applies only when running in this workspace.");
|
|
311704
312076
|
} catch (err) {
|
|
311705
312077
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -311811,11 +312183,27 @@ async function serveCommand(opts, config) {
|
|
|
311811
312183
|
}
|
|
311812
312184
|
}
|
|
311813
312185
|
const ollamaUrl = config.backendUrl || "http://127.0.0.1:11434";
|
|
311814
|
-
|
|
311815
|
-
|
|
311816
|
-
|
|
312186
|
+
const isDaemon = opts.daemon || process.env["OA_DAEMON"] === "1";
|
|
312187
|
+
const isQuiet = opts.quiet || isDaemon;
|
|
312188
|
+
if (!isQuiet) {
|
|
312189
|
+
printHeader("Open Agents REST API");
|
|
312190
|
+
printInfo(`Starting API server on port ${port}...`);
|
|
312191
|
+
printInfo(`Backend: ${config.backendType} (${ollamaUrl})`);
|
|
312192
|
+
}
|
|
311817
312193
|
try {
|
|
311818
|
-
const server = startApiServer({ port, ollamaUrl });
|
|
312194
|
+
const server = startApiServer({ port, ollamaUrl, quiet: isQuiet });
|
|
312195
|
+
if (isDaemon) {
|
|
312196
|
+
let lastActivity = Date.now();
|
|
312197
|
+
const IDLE_TIMEOUT_MS = 12e4;
|
|
312198
|
+
server.on("request", () => {
|
|
312199
|
+
lastActivity = Date.now();
|
|
312200
|
+
});
|
|
312201
|
+
const idleChecker = setInterval(() => {
|
|
312202
|
+
if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) {
|
|
312203
|
+
}
|
|
312204
|
+
}, 3e4);
|
|
312205
|
+
idleChecker.unref();
|
|
312206
|
+
}
|
|
311819
312207
|
await new Promise((resolve39) => {
|
|
311820
312208
|
process.on("SIGINT", () => {
|
|
311821
312209
|
server.close();
|
|
@@ -311829,10 +312217,13 @@ async function serveCommand(opts, config) {
|
|
|
311829
312217
|
} catch (err) {
|
|
311830
312218
|
const msg = err instanceof Error ? err.message : String(err);
|
|
311831
312219
|
if (msg.includes("EADDRINUSE")) {
|
|
311832
|
-
|
|
311833
|
-
|
|
312220
|
+
if (!isQuiet) {
|
|
312221
|
+
printError(`Port ${port} already in use. Another OA instance may be running.`);
|
|
312222
|
+
printInfo(`Try: oa serve --port ${port + 1}`);
|
|
312223
|
+
}
|
|
311834
312224
|
} else {
|
|
311835
|
-
|
|
312225
|
+
if (!isQuiet)
|
|
312226
|
+
printError(`API server failed: ${msg}`);
|
|
311836
312227
|
}
|
|
311837
312228
|
}
|
|
311838
312229
|
}
|
|
@@ -311851,8 +312242,8 @@ __export(eval_exports, {
|
|
|
311851
312242
|
evalCommand: () => evalCommand
|
|
311852
312243
|
});
|
|
311853
312244
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
311854
|
-
import { mkdirSync as
|
|
311855
|
-
import { join as
|
|
312245
|
+
import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync34 } from "node:fs";
|
|
312246
|
+
import { join as join85 } from "node:path";
|
|
311856
312247
|
async function evalCommand(opts, config) {
|
|
311857
312248
|
const suiteName = opts.suite ?? "basic";
|
|
311858
312249
|
const suite = SUITES[suiteName];
|
|
@@ -311977,9 +312368,9 @@ async function evalCommand(opts, config) {
|
|
|
311977
312368
|
process.exit(failed > 0 ? 1 : 0);
|
|
311978
312369
|
}
|
|
311979
312370
|
function createTempEvalRepo() {
|
|
311980
|
-
const dir =
|
|
311981
|
-
|
|
311982
|
-
|
|
312371
|
+
const dir = join85(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
312372
|
+
mkdirSync36(dir, { recursive: true });
|
|
312373
|
+
writeFileSync34(join85(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
311983
312374
|
return dir;
|
|
311984
312375
|
}
|
|
311985
312376
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -312038,8 +312429,8 @@ init_output();
|
|
|
312038
312429
|
init_updater();
|
|
312039
312430
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
312040
312431
|
import { createRequire as createRequire6 } from "node:module";
|
|
312041
|
-
import { fileURLToPath as
|
|
312042
|
-
import { dirname as
|
|
312432
|
+
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
312433
|
+
import { dirname as dirname26, join as join86 } from "node:path";
|
|
312043
312434
|
|
|
312044
312435
|
// packages/cli/dist/cli.js
|
|
312045
312436
|
import { createInterface } from "node:readline";
|
|
@@ -312146,7 +312537,7 @@ init_output();
|
|
|
312146
312537
|
function getVersion5() {
|
|
312147
312538
|
try {
|
|
312148
312539
|
const require3 = createRequire6(import.meta.url);
|
|
312149
|
-
const pkgPath =
|
|
312540
|
+
const pkgPath = join86(dirname26(fileURLToPath18(import.meta.url)), "..", "package.json");
|
|
312150
312541
|
const pkg = require3(pkgPath);
|
|
312151
312542
|
return pkg.version;
|
|
312152
312543
|
} catch {
|
|
@@ -312385,7 +312776,9 @@ async function main() {
|
|
|
312385
312776
|
await serveCommand2({
|
|
312386
312777
|
port: parsed.servePort,
|
|
312387
312778
|
model: parsed.model,
|
|
312388
|
-
verbose: parsed.verbose
|
|
312779
|
+
verbose: parsed.verbose,
|
|
312780
|
+
daemon: process.env["OA_DAEMON"] === "1",
|
|
312781
|
+
quiet: process.argv.includes("--quiet") || process.env["OA_DAEMON"] === "1"
|
|
312389
312782
|
}, config);
|
|
312390
312783
|
break;
|
|
312391
312784
|
}
|
|
@@ -312421,12 +312814,12 @@ function crashLog(label, err) {
|
|
|
312421
312814
|
const logLine = `[${timestamp}] ${label}: ${msg}
|
|
312422
312815
|
`;
|
|
312423
312816
|
try {
|
|
312424
|
-
const { appendFileSync: appendFileSync7, mkdirSync:
|
|
312425
|
-
const { join:
|
|
312426
|
-
const { homedir:
|
|
312427
|
-
const logDir =
|
|
312428
|
-
|
|
312429
|
-
appendFileSync7(
|
|
312817
|
+
const { appendFileSync: appendFileSync7, mkdirSync: mkdirSync37 } = __require("node:fs");
|
|
312818
|
+
const { join: join87 } = __require("node:path");
|
|
312819
|
+
const { homedir: homedir26 } = __require("node:os");
|
|
312820
|
+
const logDir = join87(homedir26(), ".open-agents");
|
|
312821
|
+
mkdirSync37(logDir, { recursive: true });
|
|
312822
|
+
appendFileSync7(join87(logDir, "crash.log"), logLine);
|
|
312430
312823
|
} catch {
|
|
312431
312824
|
}
|
|
312432
312825
|
try {
|