open-agents-ai 0.168.0 → 0.170.0
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 +1115 -836
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10483,8 +10483,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
|
|
|
10483
10483
|
const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
|
|
10484
10484
|
const filePath = join16(dir, `${name}.json`);
|
|
10485
10485
|
if (existsSync13(filePath)) {
|
|
10486
|
-
const { unlinkSync:
|
|
10487
|
-
|
|
10486
|
+
const { unlinkSync: unlinkSync12 } = __require("node:fs");
|
|
10487
|
+
unlinkSync12(filePath);
|
|
10488
10488
|
return true;
|
|
10489
10489
|
}
|
|
10490
10490
|
return false;
|
|
@@ -11659,8 +11659,8 @@ async function loadTranscribeCli() {
|
|
|
11659
11659
|
const nvmBase = join19(homedir6(), ".nvm", "versions", "node");
|
|
11660
11660
|
if (existsSync16(nvmBase)) {
|
|
11661
11661
|
try {
|
|
11662
|
-
const { readdirSync:
|
|
11663
|
-
for (const ver of
|
|
11662
|
+
const { readdirSync: readdirSync20 } = await import("node:fs");
|
|
11663
|
+
for (const ver of readdirSync20(nvmBase)) {
|
|
11664
11664
|
const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
11665
11665
|
if (existsSync16(join19(tcPath, "dist", "index.js"))) {
|
|
11666
11666
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -12713,13 +12713,13 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
12713
12713
|
}
|
|
12714
12714
|
const snapshot = JSON.stringify(this.selfState, null, 2);
|
|
12715
12715
|
try {
|
|
12716
|
-
const { createHash:
|
|
12716
|
+
const { createHash: createHash6 } = await import("node:crypto");
|
|
12717
12717
|
const snapshotDir = join21(this.cwd, ".oa", "identity", "snapshots");
|
|
12718
12718
|
await mkdir5(snapshotDir, { recursive: true });
|
|
12719
12719
|
const version = this.selfState.version;
|
|
12720
12720
|
const snapshotPath = join21(snapshotDir, `v${version}.json`);
|
|
12721
12721
|
await writeFile9(snapshotPath, snapshot, "utf8");
|
|
12722
|
-
const hash =
|
|
12722
|
+
const hash = createHash6("sha256").update(snapshot).digest("hex");
|
|
12723
12723
|
await writeFile9(join21(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
|
|
12724
12724
|
let ipfsCid = "";
|
|
12725
12725
|
try {
|
|
@@ -12852,8 +12852,8 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
12852
12852
|
}
|
|
12853
12853
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
12854
12854
|
createDefaultState() {
|
|
12855
|
-
const { createHash:
|
|
12856
|
-
const machineId =
|
|
12855
|
+
const { createHash: createHash6 } = __require("node:crypto");
|
|
12856
|
+
const machineId = createHash6("sha256").update(this.cwd).digest("hex").slice(0, 12);
|
|
12857
12857
|
return {
|
|
12858
12858
|
self_id: `oa-${machineId}`,
|
|
12859
12859
|
version: 1,
|
|
@@ -13402,9 +13402,9 @@ print("${sentinel}")
|
|
|
13402
13402
|
if (!this.proc || this.proc.killed) {
|
|
13403
13403
|
return { success: false, path: "" };
|
|
13404
13404
|
}
|
|
13405
|
-
const { mkdirSync:
|
|
13405
|
+
const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = await import("node:fs");
|
|
13406
13406
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13407
|
-
|
|
13407
|
+
mkdirSync25(sessionDir, { recursive: true });
|
|
13408
13408
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13409
13409
|
try {
|
|
13410
13410
|
const inspectCode = `
|
|
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13428
13428
|
trajectoryCount: this.trajectory.length,
|
|
13429
13429
|
subCallCount: this.subCallCount
|
|
13430
13430
|
};
|
|
13431
|
-
|
|
13431
|
+
writeFileSync24(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13432
13432
|
return { success: true, path: sessionPath };
|
|
13433
13433
|
}
|
|
13434
13434
|
} catch {
|
|
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13440
13440
|
* what was previously computed. */
|
|
13441
13441
|
async loadSessionInfo() {
|
|
13442
13442
|
try {
|
|
13443
|
-
const { readFileSync:
|
|
13443
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = await import("node:fs");
|
|
13444
13444
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13445
|
-
if (!
|
|
13445
|
+
if (!existsSync51(sessionPath))
|
|
13446
13446
|
return null;
|
|
13447
|
-
return JSON.parse(
|
|
13447
|
+
return JSON.parse(readFileSync39(sessionPath, "utf8"));
|
|
13448
13448
|
} catch {
|
|
13449
13449
|
return null;
|
|
13450
13450
|
}
|
|
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
|
|
|
13621
13621
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
13622
13622
|
let lessons = [];
|
|
13623
13623
|
try {
|
|
13624
|
-
const { readdirSync:
|
|
13625
|
-
const files =
|
|
13624
|
+
const { readdirSync: readdirSync20, readFileSync: readFileSync39 } = await import("node:fs");
|
|
13625
|
+
const files = readdirSync20(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
13626
13626
|
for (const file of files) {
|
|
13627
|
-
const lines =
|
|
13627
|
+
const lines = readFileSync39(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
13628
13628
|
for (const line of lines) {
|
|
13629
13629
|
try {
|
|
13630
13630
|
const entry = JSON.parse(line);
|
|
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14008
14008
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14009
14009
|
*/
|
|
14010
14010
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14011
|
-
const { readFileSync:
|
|
14011
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
|
|
14012
14012
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14013
14013
|
const storeFile = join23(metaDir, "store.json");
|
|
14014
|
-
if (!
|
|
14014
|
+
if (!existsSync51(storeFile))
|
|
14015
14015
|
return "";
|
|
14016
14016
|
let store = [];
|
|
14017
14017
|
try {
|
|
14018
|
-
store = JSON.parse(
|
|
14018
|
+
store = JSON.parse(readFileSync39(storeFile, "utf8"));
|
|
14019
14019
|
} catch {
|
|
14020
14020
|
return "";
|
|
14021
14021
|
}
|
|
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14037
14037
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14038
14038
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14039
14039
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14040
|
-
const { readFileSync:
|
|
14040
|
+
const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
|
|
14041
14041
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14042
14042
|
const storeFile = join23(metaDir, "store.json");
|
|
14043
|
-
if (!
|
|
14043
|
+
if (!existsSync51(storeFile))
|
|
14044
14044
|
return;
|
|
14045
14045
|
let store = [];
|
|
14046
14046
|
try {
|
|
14047
|
-
store = JSON.parse(
|
|
14047
|
+
store = JSON.parse(readFileSync39(storeFile, "utf8"));
|
|
14048
14048
|
} catch {
|
|
14049
14049
|
return;
|
|
14050
14050
|
}
|
|
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14068
14068
|
updated = true;
|
|
14069
14069
|
}
|
|
14070
14070
|
if (updated) {
|
|
14071
|
-
|
|
14072
|
-
|
|
14071
|
+
mkdirSync25(metaDir, { recursive: true });
|
|
14072
|
+
writeFileSync24(storeFile, JSON.stringify(store, null, 2));
|
|
14073
14073
|
}
|
|
14074
14074
|
}
|
|
14075
14075
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14491
14491
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14492
14492
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14493
14493
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14494
|
-
const { readFileSync:
|
|
14494
|
+
const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
|
|
14495
14495
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14496
|
-
if (!
|
|
14496
|
+
if (!existsSync51(archiveFile))
|
|
14497
14497
|
return "";
|
|
14498
14498
|
let variants = [];
|
|
14499
14499
|
try {
|
|
14500
|
-
variants = JSON.parse(
|
|
14500
|
+
variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
|
|
14501
14501
|
} catch {
|
|
14502
14502
|
return "";
|
|
14503
14503
|
}
|
|
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14515
14515
|
}
|
|
14516
14516
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14517
14517
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14518
|
-
const { readFileSync:
|
|
14518
|
+
const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
|
|
14519
14519
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14520
14520
|
const archiveFile = join25(dir, "variants.json");
|
|
14521
14521
|
let variants = [];
|
|
14522
14522
|
try {
|
|
14523
|
-
if (
|
|
14524
|
-
variants = JSON.parse(
|
|
14523
|
+
if (existsSync51(archiveFile))
|
|
14524
|
+
variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
|
|
14525
14525
|
} catch {
|
|
14526
14526
|
}
|
|
14527
14527
|
variants.push({
|
|
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14536
14536
|
});
|
|
14537
14537
|
if (variants.length > 50)
|
|
14538
14538
|
variants = variants.slice(-50);
|
|
14539
|
-
|
|
14540
|
-
|
|
14539
|
+
mkdirSync25(dir, { recursive: true });
|
|
14540
|
+
writeFileSync24(archiveFile, JSON.stringify(variants, null, 2));
|
|
14541
14541
|
}
|
|
14542
14542
|
async saveArchive(variants) {
|
|
14543
14543
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -21201,19 +21201,293 @@ var init_environment_snapshot = __esm({
|
|
|
21201
21201
|
}
|
|
21202
21202
|
});
|
|
21203
21203
|
|
|
21204
|
+
// packages/execution/dist/tools/video-understand.js
|
|
21205
|
+
import { execSync as execSync24 } from "node:child_process";
|
|
21206
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync20, readdirSync as readdirSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
21207
|
+
import { join as join41, basename as basename10 } from "node:path";
|
|
21208
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
21209
|
+
function isYouTubeUrl2(url) {
|
|
21210
|
+
return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
|
|
21211
|
+
}
|
|
21212
|
+
function ensureYtDlp2() {
|
|
21213
|
+
try {
|
|
21214
|
+
execSync24("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
|
|
21215
|
+
return true;
|
|
21216
|
+
} catch {
|
|
21217
|
+
try {
|
|
21218
|
+
execSync24("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
|
|
21219
|
+
return true;
|
|
21220
|
+
} catch {
|
|
21221
|
+
return false;
|
|
21222
|
+
}
|
|
21223
|
+
}
|
|
21224
|
+
}
|
|
21225
|
+
function ensureFfmpeg() {
|
|
21226
|
+
try {
|
|
21227
|
+
execSync24("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
|
|
21228
|
+
return true;
|
|
21229
|
+
} catch {
|
|
21230
|
+
return false;
|
|
21231
|
+
}
|
|
21232
|
+
}
|
|
21233
|
+
function imageHash(imagePath) {
|
|
21234
|
+
try {
|
|
21235
|
+
const data = readFileSync20(imagePath);
|
|
21236
|
+
return createHash2("md5").update(data).digest("hex").slice(0, 12);
|
|
21237
|
+
} catch {
|
|
21238
|
+
return "unknown";
|
|
21239
|
+
}
|
|
21240
|
+
}
|
|
21241
|
+
function deduplicateFrames(frames, similarityThreshold = 0) {
|
|
21242
|
+
if (frames.length <= 1)
|
|
21243
|
+
return frames;
|
|
21244
|
+
let prevHash = "";
|
|
21245
|
+
for (const frame of frames) {
|
|
21246
|
+
if (frame.hash === prevHash) {
|
|
21247
|
+
frame.isDuplicate = true;
|
|
21248
|
+
}
|
|
21249
|
+
prevHash = frame.hash;
|
|
21250
|
+
}
|
|
21251
|
+
return frames;
|
|
21252
|
+
}
|
|
21253
|
+
function formatTime2(seconds) {
|
|
21254
|
+
const m = Math.floor(seconds / 60);
|
|
21255
|
+
const s = Math.floor(seconds % 60);
|
|
21256
|
+
const ms = Math.floor(seconds % 1 * 10);
|
|
21257
|
+
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${ms}`;
|
|
21258
|
+
}
|
|
21259
|
+
var VideoUnderstandTool;
|
|
21260
|
+
var init_video_understand = __esm({
|
|
21261
|
+
"packages/execution/dist/tools/video-understand.js"() {
|
|
21262
|
+
"use strict";
|
|
21263
|
+
VideoUnderstandTool = class {
|
|
21264
|
+
name = "video_understand";
|
|
21265
|
+
description = "Analyze a video from URL or local file. Produces timestamped transcript aligned with keyframe descriptions. Supports YouTube URLs and direct video files. Pipeline: download \u2192 transcribe (Whisper) \u2192 extract keyframes (scene detection) \u2192 describe frames \u2192 align timestamps \u2192 save structured output.";
|
|
21266
|
+
parameters = {
|
|
21267
|
+
type: "object",
|
|
21268
|
+
properties: {
|
|
21269
|
+
url: { type: "string", description: "YouTube URL or direct video URL" },
|
|
21270
|
+
path: { type: "string", description: "Local video file path (alternative to url)" },
|
|
21271
|
+
model: { type: "string", description: "Whisper model: tiny, base, small, medium (default: base)" },
|
|
21272
|
+
frame_interval: { type: "number", description: "Seconds between forced frame samples (default: 30)" },
|
|
21273
|
+
scene_threshold: { type: "number", description: "Scene change sensitivity 0-1 (default: 0.1)" },
|
|
21274
|
+
skip_frames: { type: "boolean", description: "Skip frame extraction (audio-only, default: false)" }
|
|
21275
|
+
},
|
|
21276
|
+
required: []
|
|
21277
|
+
};
|
|
21278
|
+
workingDir;
|
|
21279
|
+
constructor(workingDir) {
|
|
21280
|
+
this.workingDir = workingDir;
|
|
21281
|
+
}
|
|
21282
|
+
async execute(args) {
|
|
21283
|
+
const start = performance.now();
|
|
21284
|
+
const url = args["url"];
|
|
21285
|
+
const localPath = args["path"];
|
|
21286
|
+
const whisperModel = String(args["model"] ?? "base");
|
|
21287
|
+
const frameInterval = Number(args["frame_interval"] ?? 30);
|
|
21288
|
+
const sceneThreshold = Number(args["scene_threshold"] ?? 0.1);
|
|
21289
|
+
const skipFrames = Boolean(args["skip_frames"]);
|
|
21290
|
+
if (!url && !localPath) {
|
|
21291
|
+
return { success: false, output: "", error: "url or path required", durationMs: performance.now() - start };
|
|
21292
|
+
}
|
|
21293
|
+
const outDir = join41(this.workingDir, ".oa", "video-analysis");
|
|
21294
|
+
mkdirSync9(outDir, { recursive: true });
|
|
21295
|
+
const tmpDir = join41(outDir, `tmp-${Date.now()}`);
|
|
21296
|
+
mkdirSync9(tmpDir, { recursive: true });
|
|
21297
|
+
try {
|
|
21298
|
+
let videoPath;
|
|
21299
|
+
let audioPath;
|
|
21300
|
+
let title;
|
|
21301
|
+
if (url) {
|
|
21302
|
+
if (isYouTubeUrl2(url)) {
|
|
21303
|
+
if (!ensureYtDlp2()) {
|
|
21304
|
+
return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start };
|
|
21305
|
+
}
|
|
21306
|
+
try {
|
|
21307
|
+
execSync24(`yt-dlp -f "worst[ext=mp4]" -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21308
|
+
} catch {
|
|
21309
|
+
execSync24(`yt-dlp -f worst -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21310
|
+
}
|
|
21311
|
+
execSync24(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join41(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21312
|
+
try {
|
|
21313
|
+
title = execSync24(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
21314
|
+
} catch {
|
|
21315
|
+
}
|
|
21316
|
+
} else {
|
|
21317
|
+
execSync24(`curl -sL -o "${join41(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
|
|
21318
|
+
execSync24(`ffmpeg -i "${join41(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join41(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
21319
|
+
}
|
|
21320
|
+
videoPath = readdirSync7(tmpDir).find((f) => f.startsWith("video")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("video"))) : join41(tmpDir, "video.mp4");
|
|
21321
|
+
audioPath = readdirSync7(tmpDir).find((f) => f.startsWith("audio")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("audio"))) : join41(tmpDir, "audio.mp3");
|
|
21322
|
+
} else {
|
|
21323
|
+
videoPath = localPath;
|
|
21324
|
+
audioPath = join41(tmpDir, "audio.mp3");
|
|
21325
|
+
execSync24(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
|
|
21326
|
+
}
|
|
21327
|
+
let segments = [];
|
|
21328
|
+
let language = "en";
|
|
21329
|
+
let duration = 0;
|
|
21330
|
+
try {
|
|
21331
|
+
const jsonOut = join41(tmpDir, "transcript.json");
|
|
21332
|
+
execSync24(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
|
|
21333
|
+
const jsonFile = readdirSync7(tmpDir).find((f) => f.endsWith(".json") && f !== "result.json");
|
|
21334
|
+
if (jsonFile) {
|
|
21335
|
+
const data = JSON.parse(readFileSync20(join41(tmpDir, jsonFile), "utf-8"));
|
|
21336
|
+
segments = (data.segments || []).map((s) => ({
|
|
21337
|
+
start: s.start ?? 0,
|
|
21338
|
+
end: s.end ?? 0,
|
|
21339
|
+
text: (s.text || "").trim(),
|
|
21340
|
+
speaker: s.speaker
|
|
21341
|
+
}));
|
|
21342
|
+
language = data.language || "en";
|
|
21343
|
+
duration = data.duration || 0;
|
|
21344
|
+
}
|
|
21345
|
+
} catch (err) {
|
|
21346
|
+
segments = [];
|
|
21347
|
+
}
|
|
21348
|
+
let frames = [];
|
|
21349
|
+
if (!skipFrames && ensureFfmpeg() && existsSync27(videoPath)) {
|
|
21350
|
+
const framesDir = join41(tmpDir, "frames");
|
|
21351
|
+
mkdirSync9(framesDir, { recursive: true });
|
|
21352
|
+
const fps = 25;
|
|
21353
|
+
const intervalFrames = Math.max(1, frameInterval * fps);
|
|
21354
|
+
try {
|
|
21355
|
+
execSync24(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join41(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
|
|
21356
|
+
} catch {
|
|
21357
|
+
}
|
|
21358
|
+
const frameFiles = readdirSync7(framesDir).filter((f) => f.endsWith(".jpg")).sort();
|
|
21359
|
+
for (let i = 0; i < frameFiles.length; i++) {
|
|
21360
|
+
const framePath = join41(framesDir, frameFiles[i]);
|
|
21361
|
+
const hash = imageHash(framePath);
|
|
21362
|
+
const timestamp2 = duration > 0 ? i / Math.max(1, frameFiles.length - 1) * duration : i * frameInterval;
|
|
21363
|
+
frames.push({
|
|
21364
|
+
path: framePath,
|
|
21365
|
+
timestamp: timestamp2,
|
|
21366
|
+
hash,
|
|
21367
|
+
isDuplicate: false
|
|
21368
|
+
});
|
|
21369
|
+
}
|
|
21370
|
+
deduplicateFrames(frames);
|
|
21371
|
+
const permanentDir = join41(outDir, `frames-${Date.now()}`);
|
|
21372
|
+
mkdirSync9(permanentDir, { recursive: true });
|
|
21373
|
+
for (const frame of frames.filter((f) => !f.isDuplicate)) {
|
|
21374
|
+
const dest = join41(permanentDir, basename10(frame.path));
|
|
21375
|
+
try {
|
|
21376
|
+
writeFileSync9(dest, readFileSync20(frame.path));
|
|
21377
|
+
frame.path = dest;
|
|
21378
|
+
} catch {
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
}
|
|
21382
|
+
const uniqueFrames = frames.filter((f) => !f.isDuplicate);
|
|
21383
|
+
const alignedTimeline = segments.map((seg) => {
|
|
21384
|
+
const mid = (seg.start + seg.end) / 2;
|
|
21385
|
+
let nearestFrame;
|
|
21386
|
+
let minDist = Infinity;
|
|
21387
|
+
for (const frame of uniqueFrames) {
|
|
21388
|
+
const dist = Math.abs(frame.timestamp - mid);
|
|
21389
|
+
if (dist < minDist) {
|
|
21390
|
+
minDist = dist;
|
|
21391
|
+
nearestFrame = frame;
|
|
21392
|
+
}
|
|
21393
|
+
}
|
|
21394
|
+
return {
|
|
21395
|
+
start: seg.start,
|
|
21396
|
+
end: seg.end,
|
|
21397
|
+
speech: seg.text,
|
|
21398
|
+
frameDescription: nearestFrame?.description,
|
|
21399
|
+
frameOcr: nearestFrame?.ocrText
|
|
21400
|
+
};
|
|
21401
|
+
});
|
|
21402
|
+
const result = {
|
|
21403
|
+
source: url || localPath || "unknown",
|
|
21404
|
+
title,
|
|
21405
|
+
duration,
|
|
21406
|
+
language,
|
|
21407
|
+
segments,
|
|
21408
|
+
frames: frames.filter((f) => !f.isDuplicate),
|
|
21409
|
+
alignedTimeline
|
|
21410
|
+
};
|
|
21411
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
21412
|
+
const resultFile = join41(outDir, `understanding-${timestamp}.json`);
|
|
21413
|
+
writeFileSync9(resultFile, JSON.stringify(result, null, 2), "utf-8");
|
|
21414
|
+
try {
|
|
21415
|
+
const memDir = join41(this.workingDir, ".oa", "memory");
|
|
21416
|
+
mkdirSync9(memDir, { recursive: true });
|
|
21417
|
+
const memFile = join41(memDir, "video-analyses.json");
|
|
21418
|
+
let entries = [];
|
|
21419
|
+
try {
|
|
21420
|
+
entries = JSON.parse(readFileSync20(memFile, "utf-8"));
|
|
21421
|
+
} catch {
|
|
21422
|
+
}
|
|
21423
|
+
entries.push({
|
|
21424
|
+
source: url || localPath,
|
|
21425
|
+
title,
|
|
21426
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21427
|
+
duration,
|
|
21428
|
+
language,
|
|
21429
|
+
segmentCount: segments.length,
|
|
21430
|
+
frameCount: uniqueFrames.length,
|
|
21431
|
+
resultPath: resultFile,
|
|
21432
|
+
summary: segments.slice(0, 3).map((s) => s.text).join(" ").slice(0, 200)
|
|
21433
|
+
});
|
|
21434
|
+
if (entries.length > 30)
|
|
21435
|
+
entries = entries.slice(-30);
|
|
21436
|
+
writeFileSync9(memFile, JSON.stringify(entries, null, 2), "utf-8");
|
|
21437
|
+
} catch {
|
|
21438
|
+
}
|
|
21439
|
+
const lines = [];
|
|
21440
|
+
lines.push(`# Video Analysis${title ? `: ${title}` : ""}`);
|
|
21441
|
+
lines.push(`Source: ${url || localPath}`);
|
|
21442
|
+
lines.push(`Duration: ${duration.toFixed(1)}s | Language: ${language} | Segments: ${segments.length} | Frames: ${uniqueFrames.length}`);
|
|
21443
|
+
lines.push(`Saved: ${resultFile}`);
|
|
21444
|
+
lines.push("");
|
|
21445
|
+
lines.push("## Transcript");
|
|
21446
|
+
for (const seg of segments) {
|
|
21447
|
+
lines.push(`[${formatTime2(seg.start)} \u2192 ${formatTime2(seg.end)}] ${seg.text}`);
|
|
21448
|
+
}
|
|
21449
|
+
if (uniqueFrames.length > 0) {
|
|
21450
|
+
lines.push("");
|
|
21451
|
+
lines.push(`## Frames (${uniqueFrames.length} unique, ${frames.length - uniqueFrames.length} duplicates removed)`);
|
|
21452
|
+
for (const frame of uniqueFrames) {
|
|
21453
|
+
lines.push(` [${formatTime2(frame.timestamp)}] ${basename10(frame.path)}${frame.description ? ` \u2014 ${frame.description}` : ""}`);
|
|
21454
|
+
}
|
|
21455
|
+
}
|
|
21456
|
+
try {
|
|
21457
|
+
execSync24(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
|
|
21458
|
+
} catch {
|
|
21459
|
+
}
|
|
21460
|
+
return {
|
|
21461
|
+
success: true,
|
|
21462
|
+
output: lines.join("\n"),
|
|
21463
|
+
durationMs: performance.now() - start
|
|
21464
|
+
};
|
|
21465
|
+
} catch (err) {
|
|
21466
|
+
return {
|
|
21467
|
+
success: false,
|
|
21468
|
+
output: "",
|
|
21469
|
+
error: `Video analysis failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
21470
|
+
durationMs: performance.now() - start
|
|
21471
|
+
};
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21474
|
+
};
|
|
21475
|
+
}
|
|
21476
|
+
});
|
|
21477
|
+
|
|
21204
21478
|
// packages/execution/dist/venv-paths.js
|
|
21205
|
-
import { join as
|
|
21479
|
+
import { join as join42 } from "node:path";
|
|
21206
21480
|
function venvPython(venvDir) {
|
|
21207
|
-
return isWin ?
|
|
21481
|
+
return isWin ? join42(venvDir, "Scripts", "python.exe") : join42(venvDir, "bin", "python");
|
|
21208
21482
|
}
|
|
21209
21483
|
function venvPip(venvDir) {
|
|
21210
|
-
return isWin ?
|
|
21484
|
+
return isWin ? join42(venvDir, "Scripts", "pip.exe") : join42(venvDir, "bin", "pip");
|
|
21211
21485
|
}
|
|
21212
21486
|
function venvBinDir(venvDir) {
|
|
21213
|
-
return isWin ?
|
|
21487
|
+
return isWin ? join42(venvDir, "Scripts") : join42(venvDir, "bin");
|
|
21214
21488
|
}
|
|
21215
21489
|
function venvExe(venvDir, name) {
|
|
21216
|
-
return isWin ?
|
|
21490
|
+
return isWin ? join42(venvDir, "Scripts", `${name}.exe`) : join42(venvDir, "bin", name);
|
|
21217
21491
|
}
|
|
21218
21492
|
var isWin;
|
|
21219
21493
|
var init_venv_paths = __esm({
|
|
@@ -21224,14 +21498,14 @@ var init_venv_paths = __esm({
|
|
|
21224
21498
|
});
|
|
21225
21499
|
|
|
21226
21500
|
// packages/execution/dist/tools/fortemi-bridge.js
|
|
21227
|
-
import { existsSync as
|
|
21228
|
-
import { join as
|
|
21501
|
+
import { existsSync as existsSync28, readFileSync as readFileSync21 } from "node:fs";
|
|
21502
|
+
import { join as join43 } from "node:path";
|
|
21229
21503
|
function loadBridgeState(repoRoot) {
|
|
21230
|
-
const bridgeFile =
|
|
21231
|
-
if (!
|
|
21504
|
+
const bridgeFile = join43(repoRoot, ".oa", "fortemi-bridge.json");
|
|
21505
|
+
if (!existsSync28(bridgeFile))
|
|
21232
21506
|
return null;
|
|
21233
21507
|
try {
|
|
21234
|
-
return JSON.parse(
|
|
21508
|
+
return JSON.parse(readFileSync21(bridgeFile, "utf8"));
|
|
21235
21509
|
} catch {
|
|
21236
21510
|
return null;
|
|
21237
21511
|
}
|
|
@@ -21479,7 +21753,7 @@ var init_gitWorktree = __esm({
|
|
|
21479
21753
|
});
|
|
21480
21754
|
|
|
21481
21755
|
// packages/execution/dist/patchApplier.js
|
|
21482
|
-
import { readFileSync as
|
|
21756
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync10, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
|
|
21483
21757
|
import { dirname as dirname12 } from "node:path";
|
|
21484
21758
|
import { spawn as spawn15 } from "node:child_process";
|
|
21485
21759
|
async function applyPatch(patch) {
|
|
@@ -21495,22 +21769,22 @@ async function applyPatch(patch) {
|
|
|
21495
21769
|
}
|
|
21496
21770
|
}
|
|
21497
21771
|
function applyBlockReplace(patch) {
|
|
21498
|
-
const original =
|
|
21772
|
+
const original = readFileSync22(patch.filePath, "utf-8");
|
|
21499
21773
|
if (!original.includes(patch.oldContent)) {
|
|
21500
21774
|
throw new Error(`Block not found in "${patch.filePath}": the oldContent string was not found in the file.`);
|
|
21501
21775
|
}
|
|
21502
21776
|
const updated = original.replace(patch.oldContent, patch.newContent);
|
|
21503
|
-
|
|
21777
|
+
writeFileSync10(patch.filePath, updated, "utf-8");
|
|
21504
21778
|
}
|
|
21505
21779
|
function applyRewrite(patch) {
|
|
21506
|
-
|
|
21780
|
+
writeFileSync10(patch.filePath, patch.newContent, "utf-8");
|
|
21507
21781
|
}
|
|
21508
21782
|
function applyNewFile(patch) {
|
|
21509
|
-
if (
|
|
21783
|
+
if (existsSync29(patch.filePath)) {
|
|
21510
21784
|
throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
|
|
21511
21785
|
}
|
|
21512
|
-
|
|
21513
|
-
|
|
21786
|
+
mkdirSync10(dirname12(patch.filePath), { recursive: true });
|
|
21787
|
+
writeFileSync10(patch.filePath, patch.newContent, "utf-8");
|
|
21514
21788
|
}
|
|
21515
21789
|
async function applyUnifiedDiff(patch) {
|
|
21516
21790
|
const { filePath, diff } = patch;
|
|
@@ -22041,6 +22315,7 @@ __export(dist_exports, {
|
|
|
22041
22315
|
ToolExecutor: () => ToolExecutor,
|
|
22042
22316
|
TranscribeFileTool: () => TranscribeFileTool,
|
|
22043
22317
|
TranscribeUrlTool: () => TranscribeUrlTool,
|
|
22318
|
+
VideoUnderstandTool: () => VideoUnderstandTool,
|
|
22044
22319
|
VisionTool: () => VisionTool,
|
|
22045
22320
|
WebCrawlTool: () => WebCrawlTool,
|
|
22046
22321
|
WebFetchTool: () => WebFetchTool,
|
|
@@ -22175,6 +22450,7 @@ var init_dist2 = __esm({
|
|
|
22175
22450
|
init_process_health();
|
|
22176
22451
|
init_full_sub_agent();
|
|
22177
22452
|
init_environment_snapshot();
|
|
22453
|
+
init_video_understand();
|
|
22178
22454
|
init_venv_paths();
|
|
22179
22455
|
init_nexus();
|
|
22180
22456
|
init_fortemi_bridge();
|
|
@@ -22862,17 +23138,17 @@ var init_dist3 = __esm({
|
|
|
22862
23138
|
});
|
|
22863
23139
|
|
|
22864
23140
|
// packages/orchestrator/dist/promptLoader.js
|
|
22865
|
-
import { readFileSync as
|
|
22866
|
-
import { join as
|
|
23141
|
+
import { readFileSync as readFileSync23, existsSync as existsSync30 } from "node:fs";
|
|
23142
|
+
import { join as join44, dirname as dirname13 } from "node:path";
|
|
22867
23143
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
22868
23144
|
function loadPrompt(promptPath, vars) {
|
|
22869
23145
|
let content = cache.get(promptPath);
|
|
22870
23146
|
if (content === void 0) {
|
|
22871
|
-
const fullPath =
|
|
22872
|
-
if (!
|
|
23147
|
+
const fullPath = join44(PROMPTS_DIR, promptPath);
|
|
23148
|
+
if (!existsSync30(fullPath)) {
|
|
22873
23149
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
22874
23150
|
}
|
|
22875
|
-
content =
|
|
23151
|
+
content = readFileSync23(fullPath, "utf-8");
|
|
22876
23152
|
cache.set(promptPath, content);
|
|
22877
23153
|
}
|
|
22878
23154
|
if (!vars)
|
|
@@ -22885,7 +23161,7 @@ var init_promptLoader = __esm({
|
|
|
22885
23161
|
"use strict";
|
|
22886
23162
|
__filename = fileURLToPath7(import.meta.url);
|
|
22887
23163
|
__dirname4 = dirname13(__filename);
|
|
22888
|
-
PROMPTS_DIR =
|
|
23164
|
+
PROMPTS_DIR = join44(__dirname4, "..", "prompts");
|
|
22889
23165
|
cache = /* @__PURE__ */ new Map();
|
|
22890
23166
|
}
|
|
22891
23167
|
});
|
|
@@ -23265,7 +23541,7 @@ var init_code_retriever = __esm({
|
|
|
23265
23541
|
import { execFile as execFile6 } from "node:child_process";
|
|
23266
23542
|
import { promisify as promisify5 } from "node:util";
|
|
23267
23543
|
import { readFile as readFile20, readdir as readdir5, stat as stat3 } from "node:fs/promises";
|
|
23268
|
-
import { join as
|
|
23544
|
+
import { join as join45, extname as extname8 } from "node:path";
|
|
23269
23545
|
async function searchByPath(pathPattern, options) {
|
|
23270
23546
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
23271
23547
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -23407,7 +23683,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
23407
23683
|
continue;
|
|
23408
23684
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
23409
23685
|
continue;
|
|
23410
|
-
const absPath =
|
|
23686
|
+
const absPath = join45(dir, entry.name);
|
|
23411
23687
|
if (entry.isDirectory()) {
|
|
23412
23688
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
23413
23689
|
} else if (entry.isFile()) {
|
|
@@ -23714,7 +23990,7 @@ var init_graphExpand = __esm({
|
|
|
23714
23990
|
|
|
23715
23991
|
// packages/retrieval/dist/snippetPacker.js
|
|
23716
23992
|
import { readFile as readFile21 } from "node:fs/promises";
|
|
23717
|
-
import { join as
|
|
23993
|
+
import { join as join46 } from "node:path";
|
|
23718
23994
|
async function packSnippets(requests, opts = {}) {
|
|
23719
23995
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
23720
23996
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -23740,7 +24016,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
23740
24016
|
return { packed, dropped, totalTokens };
|
|
23741
24017
|
}
|
|
23742
24018
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
23743
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
24019
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join46(repoRoot, req.filePath);
|
|
23744
24020
|
let content;
|
|
23745
24021
|
try {
|
|
23746
24022
|
content = await readFile21(absPath, "utf-8");
|
|
@@ -26473,10 +26749,10 @@ ${marker}` : marker);
|
|
|
26473
26749
|
if (!this._workingDirectory)
|
|
26474
26750
|
return;
|
|
26475
26751
|
try {
|
|
26476
|
-
const { mkdirSync:
|
|
26477
|
-
const { join:
|
|
26478
|
-
const sessionDir =
|
|
26479
|
-
|
|
26752
|
+
const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = __require("node:fs");
|
|
26753
|
+
const { join: join71 } = __require("node:path");
|
|
26754
|
+
const sessionDir = join71(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
26755
|
+
mkdirSync25(sessionDir, { recursive: true });
|
|
26480
26756
|
const checkpoint = {
|
|
26481
26757
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26482
26758
|
sessionId: this._sessionId,
|
|
@@ -26488,7 +26764,7 @@ ${marker}` : marker);
|
|
|
26488
26764
|
memexEntryCount: this._memexArchive.size,
|
|
26489
26765
|
fileRegistrySize: this._fileRegistry.size
|
|
26490
26766
|
};
|
|
26491
|
-
|
|
26767
|
+
writeFileSync24(join71(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
26492
26768
|
} catch {
|
|
26493
26769
|
}
|
|
26494
26770
|
}
|
|
@@ -27564,7 +27840,6 @@ ${transcript}`
|
|
|
27564
27840
|
continue;
|
|
27565
27841
|
}
|
|
27566
27842
|
if (chunk.type === "content" && chunk.content) {
|
|
27567
|
-
content += chunk.content;
|
|
27568
27843
|
const fragment = chunk.content;
|
|
27569
27844
|
let kind;
|
|
27570
27845
|
if (chunk.thinking) {
|
|
@@ -27582,6 +27857,9 @@ ${transcript}`
|
|
|
27582
27857
|
inThinkTag = false;
|
|
27583
27858
|
kind = "content";
|
|
27584
27859
|
}
|
|
27860
|
+
if (kind === "content") {
|
|
27861
|
+
content += fragment;
|
|
27862
|
+
}
|
|
27585
27863
|
this.emit({
|
|
27586
27864
|
type: "stream_token",
|
|
27587
27865
|
content: fragment,
|
|
@@ -27817,9 +28095,9 @@ ${transcript}`
|
|
|
27817
28095
|
});
|
|
27818
28096
|
|
|
27819
28097
|
// packages/orchestrator/dist/nexusBackend.js
|
|
27820
|
-
import { existsSync as
|
|
28098
|
+
import { existsSync as existsSync31, statSync as statSync10, openSync, readSync, closeSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync11 } from "node:fs";
|
|
27821
28099
|
import { watch as fsWatch } from "node:fs";
|
|
27822
|
-
import { join as
|
|
28100
|
+
import { join as join47 } from "node:path";
|
|
27823
28101
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
27824
28102
|
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
27825
28103
|
var NexusAgenticBackend;
|
|
@@ -27969,8 +28247,8 @@ var init_nexusBackend = __esm({
|
|
|
27969
28247
|
* Falls back to unary + word-split if streaming setup fails.
|
|
27970
28248
|
*/
|
|
27971
28249
|
async *chatCompletionStream(request) {
|
|
27972
|
-
const streamFile =
|
|
27973
|
-
|
|
28250
|
+
const streamFile = join47(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
|
|
28251
|
+
writeFileSync11(streamFile, "", "utf8");
|
|
27974
28252
|
const daemonArgs = {
|
|
27975
28253
|
model: this.model,
|
|
27976
28254
|
messages: JSON.stringify(request.messages),
|
|
@@ -27990,7 +28268,7 @@ var init_nexusBackend = __esm({
|
|
|
27990
28268
|
} catch (sendErr) {
|
|
27991
28269
|
this.consecutiveFailures++;
|
|
27992
28270
|
try {
|
|
27993
|
-
|
|
28271
|
+
unlinkSync5(streamFile);
|
|
27994
28272
|
} catch {
|
|
27995
28273
|
}
|
|
27996
28274
|
throw sendErr;
|
|
@@ -28005,7 +28283,7 @@ var init_nexusBackend = __esm({
|
|
|
28005
28283
|
}
|
|
28006
28284
|
if (!isStreaming) {
|
|
28007
28285
|
try {
|
|
28008
|
-
|
|
28286
|
+
unlinkSync5(streamFile);
|
|
28009
28287
|
} catch {
|
|
28010
28288
|
}
|
|
28011
28289
|
let parsed;
|
|
@@ -28161,7 +28439,7 @@ var init_nexusBackend = __esm({
|
|
|
28161
28439
|
}
|
|
28162
28440
|
} finally {
|
|
28163
28441
|
try {
|
|
28164
|
-
|
|
28442
|
+
unlinkSync5(streamFile);
|
|
28165
28443
|
} catch {
|
|
28166
28444
|
}
|
|
28167
28445
|
}
|
|
@@ -29004,9 +29282,9 @@ __export(listen_exports, {
|
|
|
29004
29282
|
isVideoPath: () => isVideoPath,
|
|
29005
29283
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
29006
29284
|
});
|
|
29007
|
-
import { spawn as spawn16, execSync as
|
|
29008
|
-
import { existsSync as
|
|
29009
|
-
import { join as
|
|
29285
|
+
import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
|
|
29286
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, readdirSync as readdirSync8 } from "node:fs";
|
|
29287
|
+
import { join as join48, dirname as dirname14 } from "node:path";
|
|
29010
29288
|
import { homedir as homedir10 } from "node:os";
|
|
29011
29289
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
29012
29290
|
import { EventEmitter } from "node:events";
|
|
@@ -29026,7 +29304,7 @@ function findMicCaptureCommand() {
|
|
|
29026
29304
|
const platform6 = process.platform;
|
|
29027
29305
|
if (platform6 === "linux") {
|
|
29028
29306
|
try {
|
|
29029
|
-
|
|
29307
|
+
execSync25("which arecord", { stdio: "pipe" });
|
|
29030
29308
|
return {
|
|
29031
29309
|
cmd: "arecord",
|
|
29032
29310
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -29036,7 +29314,7 @@ function findMicCaptureCommand() {
|
|
|
29036
29314
|
}
|
|
29037
29315
|
if (platform6 === "darwin") {
|
|
29038
29316
|
try {
|
|
29039
|
-
|
|
29317
|
+
execSync25("which sox", { stdio: "pipe" });
|
|
29040
29318
|
return {
|
|
29041
29319
|
cmd: "sox",
|
|
29042
29320
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -29045,7 +29323,7 @@ function findMicCaptureCommand() {
|
|
|
29045
29323
|
}
|
|
29046
29324
|
}
|
|
29047
29325
|
try {
|
|
29048
|
-
|
|
29326
|
+
execSync25("which ffmpeg", { stdio: "pipe" });
|
|
29049
29327
|
if (platform6 === "linux") {
|
|
29050
29328
|
return {
|
|
29051
29329
|
cmd: "ffmpeg",
|
|
@@ -29092,39 +29370,39 @@ function findMicCaptureCommand() {
|
|
|
29092
29370
|
function findLiveWhisperScript() {
|
|
29093
29371
|
const thisDir = dirname14(fileURLToPath8(import.meta.url));
|
|
29094
29372
|
const candidates = [
|
|
29095
|
-
|
|
29096
|
-
|
|
29097
|
-
|
|
29373
|
+
join48(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
29374
|
+
join48(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
29375
|
+
join48(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
29098
29376
|
// npm install layout — scripts bundled alongside dist
|
|
29099
|
-
|
|
29100
|
-
|
|
29377
|
+
join48(thisDir, "../scripts/live-whisper.py"),
|
|
29378
|
+
join48(thisDir, "../../scripts/live-whisper.py")
|
|
29101
29379
|
];
|
|
29102
29380
|
for (const p of candidates) {
|
|
29103
|
-
if (
|
|
29381
|
+
if (existsSync32(p))
|
|
29104
29382
|
return p;
|
|
29105
29383
|
}
|
|
29106
29384
|
try {
|
|
29107
|
-
const globalRoot =
|
|
29385
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29108
29386
|
encoding: "utf-8",
|
|
29109
29387
|
timeout: 5e3,
|
|
29110
29388
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29111
29389
|
}).trim();
|
|
29112
29390
|
const candidates2 = [
|
|
29113
|
-
|
|
29114
|
-
|
|
29391
|
+
join48(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
29392
|
+
join48(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
29115
29393
|
];
|
|
29116
29394
|
for (const p of candidates2) {
|
|
29117
|
-
if (
|
|
29395
|
+
if (existsSync32(p))
|
|
29118
29396
|
return p;
|
|
29119
29397
|
}
|
|
29120
29398
|
} catch {
|
|
29121
29399
|
}
|
|
29122
|
-
const nvmBase =
|
|
29123
|
-
if (
|
|
29400
|
+
const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
|
|
29401
|
+
if (existsSync32(nvmBase)) {
|
|
29124
29402
|
try {
|
|
29125
|
-
for (const ver of
|
|
29126
|
-
const p =
|
|
29127
|
-
if (
|
|
29403
|
+
for (const ver of readdirSync8(nvmBase)) {
|
|
29404
|
+
const p = join48(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
29405
|
+
if (existsSync32(p))
|
|
29128
29406
|
return p;
|
|
29129
29407
|
}
|
|
29130
29408
|
} catch {
|
|
@@ -29137,12 +29415,12 @@ function ensureTranscribeCliBackground() {
|
|
|
29137
29415
|
return;
|
|
29138
29416
|
_bgInstallPromise = (async () => {
|
|
29139
29417
|
try {
|
|
29140
|
-
const globalRoot =
|
|
29418
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29141
29419
|
encoding: "utf-8",
|
|
29142
29420
|
timeout: 5e3,
|
|
29143
29421
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29144
29422
|
}).trim();
|
|
29145
|
-
if (
|
|
29423
|
+
if (existsSync32(join48(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
29146
29424
|
return true;
|
|
29147
29425
|
}
|
|
29148
29426
|
} catch {
|
|
@@ -29343,7 +29621,7 @@ var init_listen = __esm({
|
|
|
29343
29621
|
}
|
|
29344
29622
|
if (!this.transcribeCliAvailable) {
|
|
29345
29623
|
try {
|
|
29346
|
-
|
|
29624
|
+
execSync25("which transcribe-cli", { stdio: "pipe" });
|
|
29347
29625
|
this.transcribeCliAvailable = true;
|
|
29348
29626
|
} catch {
|
|
29349
29627
|
this.transcribeCliAvailable = false;
|
|
@@ -29360,29 +29638,29 @@ var init_listen = __esm({
|
|
|
29360
29638
|
} catch {
|
|
29361
29639
|
}
|
|
29362
29640
|
try {
|
|
29363
|
-
const globalRoot =
|
|
29641
|
+
const globalRoot = execSync25("npm root -g", {
|
|
29364
29642
|
encoding: "utf-8",
|
|
29365
29643
|
timeout: 5e3,
|
|
29366
29644
|
stdio: ["pipe", "pipe", "pipe"]
|
|
29367
29645
|
}).trim();
|
|
29368
|
-
const tcPath =
|
|
29369
|
-
if (
|
|
29646
|
+
const tcPath = join48(globalRoot, "transcribe-cli");
|
|
29647
|
+
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
29370
29648
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
29371
29649
|
const req = createRequire4(import.meta.url);
|
|
29372
|
-
return req(
|
|
29650
|
+
return req(join48(tcPath, "dist", "index.js"));
|
|
29373
29651
|
}
|
|
29374
29652
|
} catch {
|
|
29375
29653
|
}
|
|
29376
|
-
const nvmBase =
|
|
29377
|
-
if (
|
|
29654
|
+
const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
|
|
29655
|
+
if (existsSync32(nvmBase)) {
|
|
29378
29656
|
try {
|
|
29379
|
-
const { readdirSync:
|
|
29380
|
-
for (const ver of
|
|
29381
|
-
const tcPath =
|
|
29382
|
-
if (
|
|
29657
|
+
const { readdirSync: readdirSync20 } = await import("node:fs");
|
|
29658
|
+
for (const ver of readdirSync20(nvmBase)) {
|
|
29659
|
+
const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
29660
|
+
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
29383
29661
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
29384
29662
|
const req = createRequire4(import.meta.url);
|
|
29385
|
-
return req(
|
|
29663
|
+
return req(join48(tcPath, "dist", "index.js"));
|
|
29386
29664
|
}
|
|
29387
29665
|
}
|
|
29388
29666
|
} catch {
|
|
@@ -29410,7 +29688,7 @@ var init_listen = __esm({
|
|
|
29410
29688
|
}
|
|
29411
29689
|
if (!tc) {
|
|
29412
29690
|
try {
|
|
29413
|
-
|
|
29691
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29414
29692
|
this.transcribeCliAvailable = null;
|
|
29415
29693
|
tc = await this.loadTranscribeCli();
|
|
29416
29694
|
} catch {
|
|
@@ -29593,7 +29871,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29593
29871
|
}
|
|
29594
29872
|
if (!tc) {
|
|
29595
29873
|
try {
|
|
29596
|
-
|
|
29874
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29597
29875
|
this.transcribeCliAvailable = null;
|
|
29598
29876
|
tc = await this.loadTranscribeCli();
|
|
29599
29877
|
} catch {
|
|
@@ -29647,7 +29925,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29647
29925
|
}
|
|
29648
29926
|
if (!tc) {
|
|
29649
29927
|
try {
|
|
29650
|
-
|
|
29928
|
+
execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
29651
29929
|
this.transcribeCliAvailable = null;
|
|
29652
29930
|
tc = await this.loadTranscribeCli();
|
|
29653
29931
|
} catch {
|
|
@@ -29663,11 +29941,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29663
29941
|
wordTimestamps: false
|
|
29664
29942
|
});
|
|
29665
29943
|
if (outputDir) {
|
|
29666
|
-
const { basename:
|
|
29667
|
-
const transcriptDir =
|
|
29668
|
-
|
|
29669
|
-
const outFile =
|
|
29670
|
-
|
|
29944
|
+
const { basename: basename18 } = await import("node:path");
|
|
29945
|
+
const transcriptDir = join48(outputDir, ".oa", "transcripts");
|
|
29946
|
+
mkdirSync11(transcriptDir, { recursive: true });
|
|
29947
|
+
const outFile = join48(transcriptDir, `${basename18(filePath)}.txt`);
|
|
29948
|
+
writeFileSync12(outFile, result.text, "utf-8");
|
|
29671
29949
|
}
|
|
29672
29950
|
return {
|
|
29673
29951
|
text: result.text,
|
|
@@ -31915,7 +32193,7 @@ var require_websocket = __commonJS({
|
|
|
31915
32193
|
var http = __require("http");
|
|
31916
32194
|
var net = __require("net");
|
|
31917
32195
|
var tls = __require("tls");
|
|
31918
|
-
var { randomBytes: randomBytes15, createHash:
|
|
32196
|
+
var { randomBytes: randomBytes15, createHash: createHash6 } = __require("crypto");
|
|
31919
32197
|
var { Duplex, Readable } = __require("stream");
|
|
31920
32198
|
var { URL: URL3 } = __require("url");
|
|
31921
32199
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -32575,7 +32853,7 @@ var require_websocket = __commonJS({
|
|
|
32575
32853
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
32576
32854
|
return;
|
|
32577
32855
|
}
|
|
32578
|
-
const digest =
|
|
32856
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
32579
32857
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
32580
32858
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
32581
32859
|
return;
|
|
@@ -32942,7 +33220,7 @@ var require_websocket_server = __commonJS({
|
|
|
32942
33220
|
var EventEmitter7 = __require("events");
|
|
32943
33221
|
var http = __require("http");
|
|
32944
33222
|
var { Duplex } = __require("stream");
|
|
32945
|
-
var { createHash:
|
|
33223
|
+
var { createHash: createHash6 } = __require("crypto");
|
|
32946
33224
|
var extension = require_extension();
|
|
32947
33225
|
var PerMessageDeflate = require_permessage_deflate();
|
|
32948
33226
|
var subprotocol = require_subprotocol();
|
|
@@ -33243,7 +33521,7 @@ var require_websocket_server = __commonJS({
|
|
|
33243
33521
|
);
|
|
33244
33522
|
}
|
|
33245
33523
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
33246
|
-
const digest =
|
|
33524
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
33247
33525
|
const headers = [
|
|
33248
33526
|
"HTTP/1.1 101 Switching Protocols",
|
|
33249
33527
|
"Upgrade: websocket",
|
|
@@ -34154,7 +34432,7 @@ var init_render = __esm({
|
|
|
34154
34432
|
|
|
34155
34433
|
// packages/cli/dist/tui/voice-session.js
|
|
34156
34434
|
import { createServer as createServer2 } from "node:http";
|
|
34157
|
-
import { spawn as spawn17, execSync as
|
|
34435
|
+
import { spawn as spawn17, execSync as execSync26 } from "node:child_process";
|
|
34158
34436
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
34159
34437
|
function generateFrontendHTML() {
|
|
34160
34438
|
return `<!DOCTYPE html>
|
|
@@ -34887,8 +35165,8 @@ import { EventEmitter as EventEmitter3 } from "node:events";
|
|
|
34887
35165
|
import { randomBytes as randomBytes12 } from "node:crypto";
|
|
34888
35166
|
import { URL as URL2 } from "node:url";
|
|
34889
35167
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
34890
|
-
import { existsSync as
|
|
34891
|
-
import { join as
|
|
35168
|
+
import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync13, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12, readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
|
|
35169
|
+
import { join as join49 } from "node:path";
|
|
34892
35170
|
function cleanForwardHeaders(raw, targetHost) {
|
|
34893
35171
|
const out = {};
|
|
34894
35172
|
for (const [key, value] of Object.entries(raw)) {
|
|
@@ -34916,10 +35194,10 @@ function fmtTokens(n) {
|
|
|
34916
35194
|
}
|
|
34917
35195
|
function readExposeState(stateDir) {
|
|
34918
35196
|
try {
|
|
34919
|
-
const path =
|
|
34920
|
-
if (!
|
|
35197
|
+
const path = join49(stateDir, STATE_FILE_NAME);
|
|
35198
|
+
if (!existsSync33(path))
|
|
34921
35199
|
return null;
|
|
34922
|
-
const raw =
|
|
35200
|
+
const raw = readFileSync24(path, "utf8");
|
|
34923
35201
|
const data = JSON.parse(raw);
|
|
34924
35202
|
if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort)
|
|
34925
35203
|
return null;
|
|
@@ -34930,14 +35208,14 @@ function readExposeState(stateDir) {
|
|
|
34930
35208
|
}
|
|
34931
35209
|
function writeExposeState(stateDir, state) {
|
|
34932
35210
|
try {
|
|
34933
|
-
|
|
34934
|
-
|
|
35211
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
35212
|
+
writeFileSync13(join49(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
34935
35213
|
} catch {
|
|
34936
35214
|
}
|
|
34937
35215
|
}
|
|
34938
35216
|
function removeExposeState(stateDir) {
|
|
34939
35217
|
try {
|
|
34940
|
-
|
|
35218
|
+
unlinkSync6(join49(stateDir, STATE_FILE_NAME));
|
|
34941
35219
|
} catch {
|
|
34942
35220
|
}
|
|
34943
35221
|
}
|
|
@@ -35026,10 +35304,10 @@ async function collectSystemMetricsAsync() {
|
|
|
35026
35304
|
}
|
|
35027
35305
|
function readP2PExposeState(stateDir) {
|
|
35028
35306
|
try {
|
|
35029
|
-
const path =
|
|
35030
|
-
if (!
|
|
35307
|
+
const path = join49(stateDir, P2P_STATE_FILE_NAME);
|
|
35308
|
+
if (!existsSync33(path))
|
|
35031
35309
|
return null;
|
|
35032
|
-
const raw =
|
|
35310
|
+
const raw = readFileSync24(path, "utf8");
|
|
35033
35311
|
const data = JSON.parse(raw);
|
|
35034
35312
|
if (!data.peerId || !data.authKey)
|
|
35035
35313
|
return null;
|
|
@@ -35040,14 +35318,14 @@ function readP2PExposeState(stateDir) {
|
|
|
35040
35318
|
}
|
|
35041
35319
|
function writeP2PExposeState(stateDir, state) {
|
|
35042
35320
|
try {
|
|
35043
|
-
|
|
35044
|
-
|
|
35321
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
35322
|
+
writeFileSync13(join49(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
35045
35323
|
} catch {
|
|
35046
35324
|
}
|
|
35047
35325
|
}
|
|
35048
35326
|
function removeP2PExposeState(stateDir) {
|
|
35049
35327
|
try {
|
|
35050
|
-
|
|
35328
|
+
unlinkSync6(join49(stateDir, P2P_STATE_FILE_NAME));
|
|
35051
35329
|
} catch {
|
|
35052
35330
|
}
|
|
35053
35331
|
}
|
|
@@ -35895,10 +36173,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
35895
36173
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
35896
36174
|
}
|
|
35897
36175
|
const nexusDir = this._nexusTool.getNexusDir();
|
|
35898
|
-
const statusPath =
|
|
36176
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
35899
36177
|
for (let i = 0; i < 80; i++) {
|
|
35900
36178
|
try {
|
|
35901
|
-
const raw =
|
|
36179
|
+
const raw = readFileSync24(statusPath, "utf8");
|
|
35902
36180
|
if (raw.length > 10) {
|
|
35903
36181
|
const status = JSON.parse(raw);
|
|
35904
36182
|
if (status.connected && status.peerId) {
|
|
@@ -35929,9 +36207,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
35929
36207
|
});
|
|
35930
36208
|
}
|
|
35931
36209
|
try {
|
|
35932
|
-
const invocDir =
|
|
35933
|
-
if (
|
|
35934
|
-
this._prevInvocCount =
|
|
36210
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36211
|
+
if (existsSync33(invocDir)) {
|
|
36212
|
+
this._prevInvocCount = readdirSync9(invocDir).filter((f) => f.endsWith(".json")).length;
|
|
35935
36213
|
this._stats.totalRequests = this._prevInvocCount;
|
|
35936
36214
|
}
|
|
35937
36215
|
} catch {
|
|
@@ -35959,13 +36237,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
35959
36237
|
if (!state)
|
|
35960
36238
|
return null;
|
|
35961
36239
|
const nexusDir = nexusTool.getNexusDir();
|
|
35962
|
-
const statusPath =
|
|
36240
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
35963
36241
|
try {
|
|
35964
|
-
if (!
|
|
36242
|
+
if (!existsSync33(statusPath)) {
|
|
35965
36243
|
removeP2PExposeState(stateDir);
|
|
35966
36244
|
return null;
|
|
35967
36245
|
}
|
|
35968
|
-
const status = JSON.parse(
|
|
36246
|
+
const status = JSON.parse(readFileSync24(statusPath, "utf8"));
|
|
35969
36247
|
if (!status.connected || !status.peerId) {
|
|
35970
36248
|
removeP2PExposeState(stateDir);
|
|
35971
36249
|
return null;
|
|
@@ -36018,10 +36296,10 @@ ${this.formatConnectionInfo()}`);
|
|
|
36018
36296
|
let lastMeteringLineCount = 0;
|
|
36019
36297
|
this._activityPollTimer = setInterval(() => {
|
|
36020
36298
|
try {
|
|
36021
|
-
const invocDir =
|
|
36022
|
-
if (!
|
|
36299
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36300
|
+
if (!existsSync33(invocDir))
|
|
36023
36301
|
return;
|
|
36024
|
-
const files =
|
|
36302
|
+
const files = readdirSync9(invocDir).filter((f) => f.endsWith(".json"));
|
|
36025
36303
|
const invocCount = files.length;
|
|
36026
36304
|
const newRequests = invocCount - this._prevInvocCount;
|
|
36027
36305
|
if (newRequests > 0) {
|
|
@@ -36034,17 +36312,17 @@ ${this.formatConnectionInfo()}`);
|
|
|
36034
36312
|
let recentActive = 0;
|
|
36035
36313
|
for (const f of files.slice(-10)) {
|
|
36036
36314
|
try {
|
|
36037
|
-
const st = statSync11(
|
|
36315
|
+
const st = statSync11(join49(invocDir, f));
|
|
36038
36316
|
if (now - st.mtimeMs < 1e4)
|
|
36039
36317
|
recentActive++;
|
|
36040
36318
|
} catch {
|
|
36041
36319
|
}
|
|
36042
36320
|
}
|
|
36043
|
-
const meteringFile =
|
|
36321
|
+
const meteringFile = join49(nexusDir, "metering.jsonl");
|
|
36044
36322
|
let meteringLines = lastMeteringLineCount;
|
|
36045
36323
|
try {
|
|
36046
|
-
if (
|
|
36047
|
-
const content =
|
|
36324
|
+
if (existsSync33(meteringFile)) {
|
|
36325
|
+
const content = readFileSync24(meteringFile, "utf8");
|
|
36048
36326
|
meteringLines = content.split("\n").filter((l) => l.trim()).length;
|
|
36049
36327
|
}
|
|
36050
36328
|
} catch {
|
|
@@ -36070,9 +36348,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36070
36348
|
this._activityPollTimer.unref();
|
|
36071
36349
|
this._pollTimer = setInterval(() => {
|
|
36072
36350
|
try {
|
|
36073
|
-
const statusPath =
|
|
36074
|
-
if (
|
|
36075
|
-
const status = JSON.parse(
|
|
36351
|
+
const statusPath = join49(nexusDir, "status.json");
|
|
36352
|
+
if (existsSync33(statusPath)) {
|
|
36353
|
+
const status = JSON.parse(readFileSync24(statusPath, "utf8"));
|
|
36076
36354
|
if (status.peerId && !this._peerId) {
|
|
36077
36355
|
this._peerId = status.peerId;
|
|
36078
36356
|
}
|
|
@@ -36081,9 +36359,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36081
36359
|
} catch {
|
|
36082
36360
|
}
|
|
36083
36361
|
try {
|
|
36084
|
-
const invocDir =
|
|
36085
|
-
if (
|
|
36086
|
-
const files =
|
|
36362
|
+
const invocDir = join49(nexusDir, "invocations");
|
|
36363
|
+
if (existsSync33(invocDir)) {
|
|
36364
|
+
const files = readdirSync9(invocDir);
|
|
36087
36365
|
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
36088
36366
|
if (invocCount > this._stats.totalRequests) {
|
|
36089
36367
|
this._stats.totalRequests = invocCount;
|
|
@@ -36093,9 +36371,9 @@ ${this.formatConnectionInfo()}`);
|
|
|
36093
36371
|
} catch {
|
|
36094
36372
|
}
|
|
36095
36373
|
try {
|
|
36096
|
-
const meteringFile =
|
|
36097
|
-
if (
|
|
36098
|
-
const content =
|
|
36374
|
+
const meteringFile = join49(nexusDir, "metering.jsonl");
|
|
36375
|
+
if (existsSync33(meteringFile)) {
|
|
36376
|
+
const content = readFileSync24(meteringFile, "utf8");
|
|
36099
36377
|
if (content.length > lastMeteringSize) {
|
|
36100
36378
|
const newContent = content.slice(lastMeteringSize);
|
|
36101
36379
|
lastMeteringSize = content.length;
|
|
@@ -36303,9 +36581,9 @@ var init_types = __esm({
|
|
|
36303
36581
|
});
|
|
36304
36582
|
|
|
36305
36583
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
36306
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as
|
|
36307
|
-
import { readFileSync as
|
|
36308
|
-
import { join as
|
|
36584
|
+
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as createHash3 } from "node:crypto";
|
|
36585
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync14, existsSync as existsSync34, mkdirSync as mkdirSync13 } from "node:fs";
|
|
36586
|
+
import { join as join50, dirname as dirname15 } from "node:path";
|
|
36309
36587
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
36310
36588
|
var init_secret_vault = __esm({
|
|
36311
36589
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -36517,18 +36795,18 @@ var init_secret_vault = __esm({
|
|
|
36517
36795
|
const tag = cipher.getAuthTag();
|
|
36518
36796
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
36519
36797
|
const dir = dirname15(this.storePath);
|
|
36520
|
-
if (!
|
|
36521
|
-
|
|
36522
|
-
|
|
36798
|
+
if (!existsSync34(dir))
|
|
36799
|
+
mkdirSync13(dir, { recursive: true });
|
|
36800
|
+
writeFileSync14(this.storePath, blob, { mode: 384 });
|
|
36523
36801
|
}
|
|
36524
36802
|
/**
|
|
36525
36803
|
* Load vault from disk, decrypting with the given passphrase.
|
|
36526
36804
|
* Returns the number of secrets loaded.
|
|
36527
36805
|
*/
|
|
36528
36806
|
load(passphrase) {
|
|
36529
|
-
if (!this.storePath || !
|
|
36807
|
+
if (!this.storePath || !existsSync34(this.storePath))
|
|
36530
36808
|
return 0;
|
|
36531
|
-
const blob =
|
|
36809
|
+
const blob = readFileSync25(this.storePath);
|
|
36532
36810
|
if (blob.length < SALT_LEN + IV_LEN + 16) {
|
|
36533
36811
|
throw new Error("Vault file is corrupted (too small)");
|
|
36534
36812
|
}
|
|
@@ -36554,7 +36832,7 @@ var init_secret_vault = __esm({
|
|
|
36554
36832
|
/** Generate a deterministic fingerprint of vault contents (for sync verification) */
|
|
36555
36833
|
fingerprint() {
|
|
36556
36834
|
const names = Array.from(this.secrets.keys()).sort();
|
|
36557
|
-
const hash =
|
|
36835
|
+
const hash = createHash3("sha256");
|
|
36558
36836
|
for (const name of names) {
|
|
36559
36837
|
hash.update(name + ":");
|
|
36560
36838
|
hash.update(this.secrets.get(name).value);
|
|
@@ -36569,7 +36847,7 @@ var init_secret_vault = __esm({
|
|
|
36569
36847
|
// packages/cli/dist/tui/p2p/peer-mesh.js
|
|
36570
36848
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
36571
36849
|
import { createServer as createServer4 } from "node:http";
|
|
36572
|
-
import { randomBytes as randomBytes14, createHash as
|
|
36850
|
+
import { randomBytes as randomBytes14, createHash as createHash4, generateKeyPairSync } from "node:crypto";
|
|
36573
36851
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
36574
36852
|
var init_peer_mesh = __esm({
|
|
36575
36853
|
"packages/cli/dist/tui/p2p/peer-mesh.js"() {
|
|
@@ -36618,7 +36896,7 @@ var init_peer_mesh = __esm({
|
|
|
36618
36896
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
36619
36897
|
this.publicKey = publicKey.export({ type: "spki", format: "der" });
|
|
36620
36898
|
this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
|
|
36621
|
-
this.peerId =
|
|
36899
|
+
this.peerId = createHash4("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
36622
36900
|
this.capabilities = options.capabilities;
|
|
36623
36901
|
this.displayName = options.displayName;
|
|
36624
36902
|
this._authKey = options.authKey ?? randomBytes14(24).toString("base64url");
|
|
@@ -37649,26 +37927,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
37649
37927
|
async function fetchPeerModels(peerId, authKey) {
|
|
37650
37928
|
try {
|
|
37651
37929
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
37652
|
-
const { existsSync:
|
|
37653
|
-
const { join:
|
|
37930
|
+
const { existsSync: existsSync51, readFileSync: readFileSync39 } = await import("node:fs");
|
|
37931
|
+
const { join: join71 } = await import("node:path");
|
|
37654
37932
|
const cwd4 = process.cwd();
|
|
37655
37933
|
const nexusTool = new NexusTool2(cwd4);
|
|
37656
37934
|
const nexusDir = nexusTool.getNexusDir();
|
|
37657
37935
|
let isLocalPeer = false;
|
|
37658
37936
|
try {
|
|
37659
|
-
const statusPath =
|
|
37660
|
-
if (
|
|
37661
|
-
const status = JSON.parse(
|
|
37937
|
+
const statusPath = join71(nexusDir, "status.json");
|
|
37938
|
+
if (existsSync51(statusPath)) {
|
|
37939
|
+
const status = JSON.parse(readFileSync39(statusPath, "utf8"));
|
|
37662
37940
|
if (status.peerId === peerId)
|
|
37663
37941
|
isLocalPeer = true;
|
|
37664
37942
|
}
|
|
37665
37943
|
} catch {
|
|
37666
37944
|
}
|
|
37667
37945
|
if (isLocalPeer) {
|
|
37668
|
-
const pricingPath =
|
|
37669
|
-
if (
|
|
37946
|
+
const pricingPath = join71(nexusDir, "pricing.json");
|
|
37947
|
+
if (existsSync51(pricingPath)) {
|
|
37670
37948
|
try {
|
|
37671
|
-
const pricing = JSON.parse(
|
|
37949
|
+
const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
|
|
37672
37950
|
const localModels = (pricing.models || []).map((m) => ({
|
|
37673
37951
|
name: m.model || "unknown",
|
|
37674
37952
|
size: m.parameterSize || "",
|
|
@@ -37682,10 +37960,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
37682
37960
|
}
|
|
37683
37961
|
}
|
|
37684
37962
|
}
|
|
37685
|
-
const cachePath =
|
|
37686
|
-
if (
|
|
37963
|
+
const cachePath = join71(nexusDir, "peer-models-cache.json");
|
|
37964
|
+
if (existsSync51(cachePath)) {
|
|
37687
37965
|
try {
|
|
37688
|
-
const cache4 = JSON.parse(
|
|
37966
|
+
const cache4 = JSON.parse(readFileSync39(cachePath, "utf8"));
|
|
37689
37967
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
37690
37968
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
37691
37969
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -37800,10 +38078,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
37800
38078
|
} catch {
|
|
37801
38079
|
}
|
|
37802
38080
|
if (isLocalPeer) {
|
|
37803
|
-
const pricingPath =
|
|
37804
|
-
if (
|
|
38081
|
+
const pricingPath = join71(nexusDir, "pricing.json");
|
|
38082
|
+
if (existsSync51(pricingPath)) {
|
|
37805
38083
|
try {
|
|
37806
|
-
const pricing = JSON.parse(
|
|
38084
|
+
const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
|
|
37807
38085
|
return (pricing.models || []).map((m) => ({
|
|
37808
38086
|
name: m.model || "unknown",
|
|
37809
38087
|
size: m.parameterSize || "",
|
|
@@ -38083,17 +38361,17 @@ var init_render2 = __esm({
|
|
|
38083
38361
|
});
|
|
38084
38362
|
|
|
38085
38363
|
// packages/prompts/dist/promptLoader.js
|
|
38086
|
-
import { readFileSync as
|
|
38087
|
-
import { join as
|
|
38364
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35 } from "node:fs";
|
|
38365
|
+
import { join as join51, dirname as dirname16 } from "node:path";
|
|
38088
38366
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
38089
38367
|
function loadPrompt2(promptPath, vars) {
|
|
38090
38368
|
let content = cache2.get(promptPath);
|
|
38091
38369
|
if (content === void 0) {
|
|
38092
|
-
const fullPath =
|
|
38093
|
-
if (!
|
|
38370
|
+
const fullPath = join51(PROMPTS_DIR2, promptPath);
|
|
38371
|
+
if (!existsSync35(fullPath)) {
|
|
38094
38372
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
38095
38373
|
}
|
|
38096
|
-
content =
|
|
38374
|
+
content = readFileSync26(fullPath, "utf-8");
|
|
38097
38375
|
cache2.set(promptPath, content);
|
|
38098
38376
|
}
|
|
38099
38377
|
if (!vars)
|
|
@@ -38106,9 +38384,9 @@ var init_promptLoader2 = __esm({
|
|
|
38106
38384
|
"use strict";
|
|
38107
38385
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
38108
38386
|
__dirname5 = dirname16(__filename2);
|
|
38109
|
-
devPath =
|
|
38110
|
-
publishedPath =
|
|
38111
|
-
PROMPTS_DIR2 =
|
|
38387
|
+
devPath = join51(__dirname5, "..", "templates");
|
|
38388
|
+
publishedPath = join51(__dirname5, "..", "prompts", "templates");
|
|
38389
|
+
PROMPTS_DIR2 = existsSync35(devPath) ? devPath : publishedPath;
|
|
38112
38390
|
cache2 = /* @__PURE__ */ new Map();
|
|
38113
38391
|
}
|
|
38114
38392
|
});
|
|
@@ -38219,7 +38497,7 @@ var init_task_templates = __esm({
|
|
|
38219
38497
|
});
|
|
38220
38498
|
|
|
38221
38499
|
// packages/prompts/dist/index.js
|
|
38222
|
-
import { join as
|
|
38500
|
+
import { join as join52, dirname as dirname17 } from "node:path";
|
|
38223
38501
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
38224
38502
|
var _dir, _packageRoot;
|
|
38225
38503
|
var init_dist6 = __esm({
|
|
@@ -38230,7 +38508,7 @@ var init_dist6 = __esm({
|
|
|
38230
38508
|
init_task_templates();
|
|
38231
38509
|
init_render2();
|
|
38232
38510
|
_dir = dirname17(fileURLToPath10(import.meta.url));
|
|
38233
|
-
_packageRoot =
|
|
38511
|
+
_packageRoot = join52(_dir, "..");
|
|
38234
38512
|
}
|
|
38235
38513
|
});
|
|
38236
38514
|
|
|
@@ -38263,21 +38541,21 @@ __export(oa_directory_exports, {
|
|
|
38263
38541
|
writeIndexData: () => writeIndexData,
|
|
38264
38542
|
writeIndexMeta: () => writeIndexMeta
|
|
38265
38543
|
});
|
|
38266
|
-
import { existsSync as
|
|
38267
|
-
import { join as
|
|
38544
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync15, readdirSync as readdirSync10, statSync as statSync12, unlinkSync as unlinkSync7 } from "node:fs";
|
|
38545
|
+
import { join as join53, relative as relative3, basename as basename11, extname as extname9 } from "node:path";
|
|
38268
38546
|
import { homedir as homedir11 } from "node:os";
|
|
38269
38547
|
function initOaDirectory(repoRoot) {
|
|
38270
|
-
const oaPath =
|
|
38548
|
+
const oaPath = join53(repoRoot, OA_DIR);
|
|
38271
38549
|
for (const sub of SUBDIRS) {
|
|
38272
|
-
|
|
38550
|
+
mkdirSync14(join53(oaPath, sub), { recursive: true });
|
|
38273
38551
|
}
|
|
38274
38552
|
try {
|
|
38275
|
-
const gitignorePath =
|
|
38553
|
+
const gitignorePath = join53(repoRoot, ".gitignore");
|
|
38276
38554
|
const settingsPattern = ".oa/settings.json";
|
|
38277
|
-
if (
|
|
38278
|
-
const content =
|
|
38555
|
+
if (existsSync36(gitignorePath)) {
|
|
38556
|
+
const content = readFileSync27(gitignorePath, "utf-8");
|
|
38279
38557
|
if (!content.includes(settingsPattern)) {
|
|
38280
|
-
|
|
38558
|
+
writeFileSync15(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
38281
38559
|
}
|
|
38282
38560
|
}
|
|
38283
38561
|
} catch {
|
|
@@ -38285,41 +38563,41 @@ function initOaDirectory(repoRoot) {
|
|
|
38285
38563
|
return oaPath;
|
|
38286
38564
|
}
|
|
38287
38565
|
function hasOaDirectory(repoRoot) {
|
|
38288
|
-
return
|
|
38566
|
+
return existsSync36(join53(repoRoot, OA_DIR, "index"));
|
|
38289
38567
|
}
|
|
38290
38568
|
function loadProjectSettings(repoRoot) {
|
|
38291
|
-
const settingsPath =
|
|
38569
|
+
const settingsPath = join53(repoRoot, OA_DIR, "settings.json");
|
|
38292
38570
|
try {
|
|
38293
|
-
if (
|
|
38294
|
-
return JSON.parse(
|
|
38571
|
+
if (existsSync36(settingsPath)) {
|
|
38572
|
+
return JSON.parse(readFileSync27(settingsPath, "utf-8"));
|
|
38295
38573
|
}
|
|
38296
38574
|
} catch {
|
|
38297
38575
|
}
|
|
38298
38576
|
return {};
|
|
38299
38577
|
}
|
|
38300
38578
|
function saveProjectSettings(repoRoot, settings) {
|
|
38301
|
-
const oaPath =
|
|
38302
|
-
|
|
38579
|
+
const oaPath = join53(repoRoot, OA_DIR);
|
|
38580
|
+
mkdirSync14(oaPath, { recursive: true });
|
|
38303
38581
|
const existing = loadProjectSettings(repoRoot);
|
|
38304
38582
|
const merged = { ...existing, ...settings };
|
|
38305
|
-
|
|
38583
|
+
writeFileSync15(join53(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38306
38584
|
}
|
|
38307
38585
|
function loadGlobalSettings() {
|
|
38308
|
-
const settingsPath =
|
|
38586
|
+
const settingsPath = join53(homedir11(), ".open-agents", "settings.json");
|
|
38309
38587
|
try {
|
|
38310
|
-
if (
|
|
38311
|
-
return JSON.parse(
|
|
38588
|
+
if (existsSync36(settingsPath)) {
|
|
38589
|
+
return JSON.parse(readFileSync27(settingsPath, "utf-8"));
|
|
38312
38590
|
}
|
|
38313
38591
|
} catch {
|
|
38314
38592
|
}
|
|
38315
38593
|
return {};
|
|
38316
38594
|
}
|
|
38317
38595
|
function saveGlobalSettings(settings) {
|
|
38318
|
-
const dir =
|
|
38319
|
-
|
|
38596
|
+
const dir = join53(homedir11(), ".open-agents");
|
|
38597
|
+
mkdirSync14(dir, { recursive: true });
|
|
38320
38598
|
const existing = loadGlobalSettings();
|
|
38321
38599
|
const merged = { ...existing, ...settings };
|
|
38322
|
-
|
|
38600
|
+
writeFileSync15(join53(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38323
38601
|
}
|
|
38324
38602
|
function resolveSettings(repoRoot) {
|
|
38325
38603
|
const global = loadGlobalSettings();
|
|
@@ -38334,12 +38612,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38334
38612
|
while (dir && !visited.has(dir)) {
|
|
38335
38613
|
visited.add(dir);
|
|
38336
38614
|
for (const name of CONTEXT_FILES) {
|
|
38337
|
-
const filePath =
|
|
38615
|
+
const filePath = join53(dir, name);
|
|
38338
38616
|
const normalizedName = name.toLowerCase();
|
|
38339
|
-
if (
|
|
38617
|
+
if (existsSync36(filePath) && !seen.has(filePath)) {
|
|
38340
38618
|
seen.add(filePath);
|
|
38341
38619
|
try {
|
|
38342
|
-
let content =
|
|
38620
|
+
let content = readFileSync27(filePath, "utf-8");
|
|
38343
38621
|
if (content.length > maxContentLen) {
|
|
38344
38622
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
38345
38623
|
}
|
|
@@ -38353,11 +38631,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38353
38631
|
}
|
|
38354
38632
|
}
|
|
38355
38633
|
}
|
|
38356
|
-
const projectMap =
|
|
38357
|
-
if (
|
|
38634
|
+
const projectMap = join53(dir, OA_DIR, "context", "project-map.md");
|
|
38635
|
+
if (existsSync36(projectMap) && !seen.has(projectMap)) {
|
|
38358
38636
|
seen.add(projectMap);
|
|
38359
38637
|
try {
|
|
38360
|
-
let content =
|
|
38638
|
+
let content = readFileSync27(projectMap, "utf-8");
|
|
38361
38639
|
if (content.length > maxContentLen) {
|
|
38362
38640
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
38363
38641
|
}
|
|
@@ -38369,7 +38647,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38369
38647
|
} catch {
|
|
38370
38648
|
}
|
|
38371
38649
|
}
|
|
38372
|
-
const parent =
|
|
38650
|
+
const parent = join53(dir, "..");
|
|
38373
38651
|
if (parent === dir)
|
|
38374
38652
|
break;
|
|
38375
38653
|
dir = parent;
|
|
@@ -38387,34 +38665,34 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
38387
38665
|
return found;
|
|
38388
38666
|
}
|
|
38389
38667
|
function readIndexMeta(repoRoot) {
|
|
38390
|
-
const metaPath =
|
|
38668
|
+
const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
|
|
38391
38669
|
try {
|
|
38392
|
-
return JSON.parse(
|
|
38670
|
+
return JSON.parse(readFileSync27(metaPath, "utf-8"));
|
|
38393
38671
|
} catch {
|
|
38394
38672
|
return null;
|
|
38395
38673
|
}
|
|
38396
38674
|
}
|
|
38397
38675
|
function writeIndexMeta(repoRoot, meta) {
|
|
38398
|
-
const metaPath =
|
|
38399
|
-
|
|
38400
|
-
|
|
38676
|
+
const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
|
|
38677
|
+
mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
38678
|
+
writeFileSync15(metaPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
38401
38679
|
}
|
|
38402
38680
|
function readIndexData(repoRoot, filename) {
|
|
38403
|
-
const filePath =
|
|
38681
|
+
const filePath = join53(repoRoot, OA_DIR, "index", filename);
|
|
38404
38682
|
try {
|
|
38405
|
-
return JSON.parse(
|
|
38683
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38406
38684
|
} catch {
|
|
38407
38685
|
return null;
|
|
38408
38686
|
}
|
|
38409
38687
|
}
|
|
38410
38688
|
function writeIndexData(repoRoot, filename, data) {
|
|
38411
|
-
const filePath =
|
|
38412
|
-
|
|
38413
|
-
|
|
38689
|
+
const filePath = join53(repoRoot, OA_DIR, "index", filename);
|
|
38690
|
+
mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
|
|
38691
|
+
writeFileSync15(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
38414
38692
|
}
|
|
38415
38693
|
function generateProjectMap(repoRoot) {
|
|
38416
38694
|
const sections = [];
|
|
38417
|
-
const repoName2 =
|
|
38695
|
+
const repoName2 = basename11(repoRoot);
|
|
38418
38696
|
sections.push(`# Project Map: ${repoName2}
|
|
38419
38697
|
`);
|
|
38420
38698
|
sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -38458,28 +38736,28 @@ ${tree}\`\`\`
|
|
|
38458
38736
|
sections.push("");
|
|
38459
38737
|
}
|
|
38460
38738
|
const content = sections.join("\n");
|
|
38461
|
-
const contextDir =
|
|
38462
|
-
|
|
38463
|
-
|
|
38739
|
+
const contextDir = join53(repoRoot, OA_DIR, "context");
|
|
38740
|
+
mkdirSync14(contextDir, { recursive: true });
|
|
38741
|
+
writeFileSync15(join53(contextDir, "project-map.md"), content, "utf-8");
|
|
38464
38742
|
return content;
|
|
38465
38743
|
}
|
|
38466
38744
|
function saveSession(repoRoot, session) {
|
|
38467
|
-
const historyDir =
|
|
38468
|
-
|
|
38469
|
-
|
|
38745
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38746
|
+
mkdirSync14(historyDir, { recursive: true });
|
|
38747
|
+
writeFileSync15(join53(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
38470
38748
|
}
|
|
38471
38749
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
38472
|
-
const historyDir =
|
|
38473
|
-
if (!
|
|
38750
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38751
|
+
if (!existsSync36(historyDir))
|
|
38474
38752
|
return [];
|
|
38475
38753
|
try {
|
|
38476
|
-
const files =
|
|
38477
|
-
const stat5 = statSync12(
|
|
38754
|
+
const files = readdirSync10(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
38755
|
+
const stat5 = statSync12(join53(historyDir, f));
|
|
38478
38756
|
return { file: f, mtime: stat5.mtimeMs };
|
|
38479
38757
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
38480
38758
|
return files.map((f) => {
|
|
38481
38759
|
try {
|
|
38482
|
-
return JSON.parse(
|
|
38760
|
+
return JSON.parse(readFileSync27(join53(historyDir, f.file), "utf-8"));
|
|
38483
38761
|
} catch {
|
|
38484
38762
|
return null;
|
|
38485
38763
|
}
|
|
@@ -38489,18 +38767,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
38489
38767
|
}
|
|
38490
38768
|
}
|
|
38491
38769
|
function savePendingTask(repoRoot, task) {
|
|
38492
|
-
const historyDir =
|
|
38493
|
-
|
|
38494
|
-
|
|
38770
|
+
const historyDir = join53(repoRoot, OA_DIR, "history");
|
|
38771
|
+
mkdirSync14(historyDir, { recursive: true });
|
|
38772
|
+
writeFileSync15(join53(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
38495
38773
|
}
|
|
38496
38774
|
function loadPendingTask(repoRoot) {
|
|
38497
|
-
const filePath =
|
|
38775
|
+
const filePath = join53(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
38498
38776
|
try {
|
|
38499
|
-
if (!
|
|
38777
|
+
if (!existsSync36(filePath))
|
|
38500
38778
|
return null;
|
|
38501
|
-
const data = JSON.parse(
|
|
38779
|
+
const data = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38502
38780
|
try {
|
|
38503
|
-
|
|
38781
|
+
unlinkSync7(filePath);
|
|
38504
38782
|
} catch {
|
|
38505
38783
|
}
|
|
38506
38784
|
return data;
|
|
@@ -38509,13 +38787,13 @@ function loadPendingTask(repoRoot) {
|
|
|
38509
38787
|
}
|
|
38510
38788
|
}
|
|
38511
38789
|
function saveSessionContext(repoRoot, entry) {
|
|
38512
|
-
const contextDir =
|
|
38513
|
-
|
|
38514
|
-
const filePath =
|
|
38790
|
+
const contextDir = join53(repoRoot, OA_DIR, "context");
|
|
38791
|
+
mkdirSync14(contextDir, { recursive: true });
|
|
38792
|
+
const filePath = join53(contextDir, CONTEXT_SAVE_FILE);
|
|
38515
38793
|
let ctx;
|
|
38516
38794
|
try {
|
|
38517
|
-
if (
|
|
38518
|
-
ctx = JSON.parse(
|
|
38795
|
+
if (existsSync36(filePath)) {
|
|
38796
|
+
ctx = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38519
38797
|
} else {
|
|
38520
38798
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
38521
38799
|
}
|
|
@@ -38527,14 +38805,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
38527
38805
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
38528
38806
|
}
|
|
38529
38807
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38530
|
-
|
|
38808
|
+
writeFileSync15(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
38531
38809
|
}
|
|
38532
38810
|
function loadSessionContext(repoRoot) {
|
|
38533
|
-
const filePath =
|
|
38811
|
+
const filePath = join53(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
38534
38812
|
try {
|
|
38535
|
-
if (!
|
|
38813
|
+
if (!existsSync36(filePath))
|
|
38536
38814
|
return null;
|
|
38537
|
-
return JSON.parse(
|
|
38815
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38538
38816
|
} catch {
|
|
38539
38817
|
return null;
|
|
38540
38818
|
}
|
|
@@ -38580,12 +38858,12 @@ function detectManifests(repoRoot) {
|
|
|
38580
38858
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
38581
38859
|
];
|
|
38582
38860
|
for (const check of checks) {
|
|
38583
|
-
const filePath =
|
|
38584
|
-
if (
|
|
38861
|
+
const filePath = join53(repoRoot, check.file);
|
|
38862
|
+
if (existsSync36(filePath)) {
|
|
38585
38863
|
let name;
|
|
38586
38864
|
if (check.nameField) {
|
|
38587
38865
|
try {
|
|
38588
|
-
const data = JSON.parse(
|
|
38866
|
+
const data = JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38589
38867
|
name = data[check.nameField];
|
|
38590
38868
|
} catch {
|
|
38591
38869
|
}
|
|
@@ -38614,7 +38892,7 @@ function findKeyFiles(repoRoot) {
|
|
|
38614
38892
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
38615
38893
|
];
|
|
38616
38894
|
for (const check of checks) {
|
|
38617
|
-
if (
|
|
38895
|
+
if (existsSync36(join53(repoRoot, check.pattern))) {
|
|
38618
38896
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
38619
38897
|
}
|
|
38620
38898
|
}
|
|
@@ -38625,7 +38903,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38625
38903
|
return "";
|
|
38626
38904
|
let result = "";
|
|
38627
38905
|
try {
|
|
38628
|
-
const entries =
|
|
38906
|
+
const entries = readdirSync10(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
|
|
38629
38907
|
if (a.isDirectory() && !b.isDirectory())
|
|
38630
38908
|
return -1;
|
|
38631
38909
|
if (!a.isDirectory() && b.isDirectory())
|
|
@@ -38640,12 +38918,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38640
38918
|
if (entry.isDirectory()) {
|
|
38641
38919
|
let fileCount = 0;
|
|
38642
38920
|
try {
|
|
38643
|
-
fileCount =
|
|
38921
|
+
fileCount = readdirSync10(join53(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
38644
38922
|
} catch {
|
|
38645
38923
|
}
|
|
38646
38924
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
38647
38925
|
`;
|
|
38648
|
-
result += buildDirTree(
|
|
38926
|
+
result += buildDirTree(join53(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
38649
38927
|
} else if (depth < maxDepth) {
|
|
38650
38928
|
result += `${prefix}${connector}${entry.name}
|
|
38651
38929
|
`;
|
|
@@ -38657,17 +38935,17 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
38657
38935
|
}
|
|
38658
38936
|
function loadUsageFile(filePath) {
|
|
38659
38937
|
try {
|
|
38660
|
-
if (
|
|
38661
|
-
return JSON.parse(
|
|
38938
|
+
if (existsSync36(filePath)) {
|
|
38939
|
+
return JSON.parse(readFileSync27(filePath, "utf-8"));
|
|
38662
38940
|
}
|
|
38663
38941
|
} catch {
|
|
38664
38942
|
}
|
|
38665
38943
|
return { records: [] };
|
|
38666
38944
|
}
|
|
38667
38945
|
function saveUsageFile(filePath, data) {
|
|
38668
|
-
const dir =
|
|
38669
|
-
|
|
38670
|
-
|
|
38946
|
+
const dir = join53(filePath, "..");
|
|
38947
|
+
mkdirSync14(dir, { recursive: true });
|
|
38948
|
+
writeFileSync15(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
38671
38949
|
}
|
|
38672
38950
|
function recordUsage(kind, value, opts) {
|
|
38673
38951
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -38695,15 +38973,15 @@ function recordUsage(kind, value, opts) {
|
|
|
38695
38973
|
}
|
|
38696
38974
|
saveUsageFile(filePath, data);
|
|
38697
38975
|
};
|
|
38698
|
-
update(
|
|
38976
|
+
update(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
38699
38977
|
if (opts?.repoRoot) {
|
|
38700
|
-
update(
|
|
38978
|
+
update(join53(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
38701
38979
|
}
|
|
38702
38980
|
}
|
|
38703
38981
|
function loadUsageHistory(kind, repoRoot) {
|
|
38704
|
-
const globalPath =
|
|
38982
|
+
const globalPath = join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
|
|
38705
38983
|
const globalData = loadUsageFile(globalPath);
|
|
38706
|
-
const localData = repoRoot ? loadUsageFile(
|
|
38984
|
+
const localData = repoRoot ? loadUsageFile(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
38707
38985
|
const map = /* @__PURE__ */ new Map();
|
|
38708
38986
|
for (const r of globalData.records) {
|
|
38709
38987
|
if (r.kind !== kind)
|
|
@@ -38734,9 +39012,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
38734
39012
|
saveUsageFile(filePath, data);
|
|
38735
39013
|
}
|
|
38736
39014
|
};
|
|
38737
|
-
remove(
|
|
39015
|
+
remove(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
|
|
38738
39016
|
if (repoRoot) {
|
|
38739
|
-
remove(
|
|
39017
|
+
remove(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
38740
39018
|
}
|
|
38741
39019
|
}
|
|
38742
39020
|
var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -38784,10 +39062,10 @@ var init_oa_directory = __esm({
|
|
|
38784
39062
|
|
|
38785
39063
|
// packages/cli/dist/tui/setup.js
|
|
38786
39064
|
import * as readline from "node:readline";
|
|
38787
|
-
import { execSync as
|
|
39065
|
+
import { execSync as execSync27, spawn as spawn19, exec as exec2 } from "node:child_process";
|
|
38788
39066
|
import { promisify as promisify6 } from "node:util";
|
|
38789
|
-
import { existsSync as
|
|
38790
|
-
import { join as
|
|
39067
|
+
import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
|
|
39068
|
+
import { join as join54 } from "node:path";
|
|
38791
39069
|
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
38792
39070
|
function detectSystemSpecs() {
|
|
38793
39071
|
let totalRamGB = 0;
|
|
@@ -38795,7 +39073,7 @@ function detectSystemSpecs() {
|
|
|
38795
39073
|
let gpuVramGB = 0;
|
|
38796
39074
|
let gpuName = "";
|
|
38797
39075
|
try {
|
|
38798
|
-
const memInfo =
|
|
39076
|
+
const memInfo = execSync27("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
38799
39077
|
encoding: "utf8",
|
|
38800
39078
|
timeout: 5e3
|
|
38801
39079
|
});
|
|
@@ -38815,7 +39093,7 @@ function detectSystemSpecs() {
|
|
|
38815
39093
|
} catch {
|
|
38816
39094
|
}
|
|
38817
39095
|
try {
|
|
38818
|
-
const nvidiaSmi =
|
|
39096
|
+
const nvidiaSmi = execSync27("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
38819
39097
|
const lines = nvidiaSmi.trim().split("\n");
|
|
38820
39098
|
if (lines.length > 0) {
|
|
38821
39099
|
for (const line of lines) {
|
|
@@ -38994,7 +39272,7 @@ function ensureCurl() {
|
|
|
38994
39272
|
for (const s of strategies) {
|
|
38995
39273
|
if (hasCmd(s.check)) {
|
|
38996
39274
|
try {
|
|
38997
|
-
|
|
39275
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
38998
39276
|
if (hasCmd("curl")) {
|
|
38999
39277
|
process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
|
|
39000
39278
|
`);
|
|
@@ -39008,7 +39286,7 @@ function ensureCurl() {
|
|
|
39008
39286
|
}
|
|
39009
39287
|
if (plat === "darwin") {
|
|
39010
39288
|
try {
|
|
39011
|
-
|
|
39289
|
+
execSync27("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
|
|
39012
39290
|
if (hasCmd("curl"))
|
|
39013
39291
|
return true;
|
|
39014
39292
|
} catch {
|
|
@@ -39043,7 +39321,7 @@ function installOllamaLinux() {
|
|
|
39043
39321
|
|
|
39044
39322
|
`);
|
|
39045
39323
|
try {
|
|
39046
|
-
|
|
39324
|
+
execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
39047
39325
|
stdio: "inherit",
|
|
39048
39326
|
timeout: 3e5
|
|
39049
39327
|
});
|
|
@@ -39071,10 +39349,10 @@ async function installOllamaMac(_rl) {
|
|
|
39071
39349
|
|
|
39072
39350
|
`);
|
|
39073
39351
|
try {
|
|
39074
|
-
|
|
39352
|
+
execSync27('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
39075
39353
|
if (!hasCmd("brew")) {
|
|
39076
39354
|
try {
|
|
39077
|
-
const brewPrefix =
|
|
39355
|
+
const brewPrefix = existsSync37("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
39078
39356
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
39079
39357
|
} catch {
|
|
39080
39358
|
}
|
|
@@ -39104,7 +39382,7 @@ async function installOllamaMac(_rl) {
|
|
|
39104
39382
|
|
|
39105
39383
|
`);
|
|
39106
39384
|
try {
|
|
39107
|
-
|
|
39385
|
+
execSync27("brew install ollama", {
|
|
39108
39386
|
stdio: "inherit",
|
|
39109
39387
|
timeout: 3e5
|
|
39110
39388
|
});
|
|
@@ -39131,7 +39409,7 @@ function installOllamaWindows() {
|
|
|
39131
39409
|
|
|
39132
39410
|
`);
|
|
39133
39411
|
try {
|
|
39134
|
-
|
|
39412
|
+
execSync27('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
39135
39413
|
stdio: "inherit",
|
|
39136
39414
|
timeout: 3e5
|
|
39137
39415
|
});
|
|
@@ -39212,7 +39490,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
39212
39490
|
}
|
|
39213
39491
|
function pullModelWithAutoUpdate(tag) {
|
|
39214
39492
|
try {
|
|
39215
|
-
|
|
39493
|
+
execSync27(`ollama pull ${tag}`, {
|
|
39216
39494
|
stdio: "inherit",
|
|
39217
39495
|
timeout: 36e5
|
|
39218
39496
|
// 1 hour max
|
|
@@ -39232,7 +39510,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
39232
39510
|
|
|
39233
39511
|
`);
|
|
39234
39512
|
try {
|
|
39235
|
-
|
|
39513
|
+
execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
39236
39514
|
stdio: "inherit",
|
|
39237
39515
|
timeout: 3e5
|
|
39238
39516
|
// 5 min max for install
|
|
@@ -39243,7 +39521,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
39243
39521
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
39244
39522
|
|
|
39245
39523
|
`);
|
|
39246
|
-
|
|
39524
|
+
execSync27(`ollama pull ${tag}`, {
|
|
39247
39525
|
stdio: "inherit",
|
|
39248
39526
|
timeout: 36e5
|
|
39249
39527
|
});
|
|
@@ -39345,7 +39623,7 @@ function ensurePython3() {
|
|
|
39345
39623
|
if (plat === "darwin") {
|
|
39346
39624
|
if (hasCmd("brew")) {
|
|
39347
39625
|
try {
|
|
39348
|
-
|
|
39626
|
+
execSync27("brew install python3", { stdio: "inherit", timeout: 3e5 });
|
|
39349
39627
|
if (hasCmd("python3")) {
|
|
39350
39628
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
|
|
39351
39629
|
`);
|
|
@@ -39358,7 +39636,7 @@ function ensurePython3() {
|
|
|
39358
39636
|
for (const s of strategies) {
|
|
39359
39637
|
if (hasCmd(s.check)) {
|
|
39360
39638
|
try {
|
|
39361
|
-
|
|
39639
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
39362
39640
|
if (hasCmd("python3") || hasCmd("python")) {
|
|
39363
39641
|
process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
|
|
39364
39642
|
`);
|
|
@@ -39374,11 +39652,11 @@ function ensurePython3() {
|
|
|
39374
39652
|
}
|
|
39375
39653
|
function checkPythonVenv() {
|
|
39376
39654
|
try {
|
|
39377
|
-
|
|
39655
|
+
execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39378
39656
|
return true;
|
|
39379
39657
|
} catch {
|
|
39380
39658
|
try {
|
|
39381
|
-
|
|
39659
|
+
execSync27("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39382
39660
|
return true;
|
|
39383
39661
|
} catch {
|
|
39384
39662
|
return false;
|
|
@@ -39397,7 +39675,7 @@ function ensurePythonVenv() {
|
|
|
39397
39675
|
for (const s of strategies) {
|
|
39398
39676
|
if (hasCmd(s.check)) {
|
|
39399
39677
|
try {
|
|
39400
|
-
|
|
39678
|
+
execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
|
|
39401
39679
|
if (checkPythonVenv()) {
|
|
39402
39680
|
process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
|
|
39403
39681
|
`);
|
|
@@ -39828,12 +40106,12 @@ async function doSetup(config, rl) {
|
|
|
39828
40106
|
`PARAMETER num_predict ${numPredict}`,
|
|
39829
40107
|
`PARAMETER stop "<|endoftext|>"`
|
|
39830
40108
|
].join("\n");
|
|
39831
|
-
const modelDir2 =
|
|
39832
|
-
|
|
39833
|
-
const modelfilePath =
|
|
39834
|
-
|
|
40109
|
+
const modelDir2 = join54(homedir12(), ".open-agents", "models");
|
|
40110
|
+
mkdirSync15(modelDir2, { recursive: true });
|
|
40111
|
+
const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
|
|
40112
|
+
writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
|
|
39835
40113
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
39836
|
-
|
|
40114
|
+
execSync27(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
39837
40115
|
stdio: "pipe",
|
|
39838
40116
|
timeout: 12e4
|
|
39839
40117
|
});
|
|
@@ -39876,7 +40154,7 @@ async function isModelAvailable(config) {
|
|
|
39876
40154
|
}
|
|
39877
40155
|
function isFirstRun() {
|
|
39878
40156
|
try {
|
|
39879
|
-
return !
|
|
40157
|
+
return !existsSync37(join54(homedir12(), ".open-agents", "config.json"));
|
|
39880
40158
|
} catch {
|
|
39881
40159
|
return true;
|
|
39882
40160
|
}
|
|
@@ -39884,7 +40162,7 @@ function isFirstRun() {
|
|
|
39884
40162
|
function hasCmd(cmd) {
|
|
39885
40163
|
try {
|
|
39886
40164
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
39887
|
-
|
|
40165
|
+
execSync27(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
39888
40166
|
return true;
|
|
39889
40167
|
} catch {
|
|
39890
40168
|
return false;
|
|
@@ -39913,11 +40191,11 @@ function detectPkgManager() {
|
|
|
39913
40191
|
return null;
|
|
39914
40192
|
}
|
|
39915
40193
|
function getVenvDir() {
|
|
39916
|
-
return
|
|
40194
|
+
return join54(homedir12(), ".open-agents", "venv");
|
|
39917
40195
|
}
|
|
39918
40196
|
function hasVenvModule() {
|
|
39919
40197
|
try {
|
|
39920
|
-
|
|
40198
|
+
execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
39921
40199
|
return true;
|
|
39922
40200
|
} catch {
|
|
39923
40201
|
return false;
|
|
@@ -39926,9 +40204,9 @@ function hasVenvModule() {
|
|
|
39926
40204
|
function ensureVenv(log) {
|
|
39927
40205
|
const venvDir = getVenvDir();
|
|
39928
40206
|
const isWin2 = process.platform === "win32";
|
|
39929
|
-
const pipPath = isWin2 ?
|
|
40207
|
+
const pipPath = isWin2 ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
|
|
39930
40208
|
const pythonCmd = isWin2 ? "python" : "python3";
|
|
39931
|
-
if (
|
|
40209
|
+
if (existsSync37(pipPath))
|
|
39932
40210
|
return venvDir;
|
|
39933
40211
|
log("Creating Python venv for vision deps...");
|
|
39934
40212
|
if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
|
|
@@ -39940,10 +40218,10 @@ function ensureVenv(log) {
|
|
|
39940
40218
|
return null;
|
|
39941
40219
|
}
|
|
39942
40220
|
try {
|
|
39943
|
-
|
|
40221
|
+
mkdirSync15(join54(homedir12(), ".open-agents"), { recursive: true });
|
|
39944
40222
|
const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
|
|
39945
|
-
|
|
39946
|
-
|
|
40223
|
+
execSync27(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
40224
|
+
execSync27(`"${pipPath}" install --upgrade pip`, {
|
|
39947
40225
|
stdio: "pipe",
|
|
39948
40226
|
timeout: 6e4
|
|
39949
40227
|
});
|
|
@@ -39956,7 +40234,7 @@ function ensureVenv(log) {
|
|
|
39956
40234
|
}
|
|
39957
40235
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
39958
40236
|
try {
|
|
39959
|
-
|
|
40237
|
+
execSync27(`sudo -n ${cmd}`, {
|
|
39960
40238
|
stdio: "pipe",
|
|
39961
40239
|
timeout: timeoutMs,
|
|
39962
40240
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -39969,7 +40247,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
39969
40247
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
39970
40248
|
try {
|
|
39971
40249
|
const escaped = cmd.replace(/'/g, "'\\''");
|
|
39972
|
-
|
|
40250
|
+
execSync27(`sudo -S bash -c '${escaped}'`, {
|
|
39973
40251
|
input: password + "\n",
|
|
39974
40252
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39975
40253
|
timeout: timeoutMs,
|
|
@@ -40076,7 +40354,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40076
40354
|
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
40077
40355
|
} else {
|
|
40078
40356
|
try {
|
|
40079
|
-
|
|
40357
|
+
execSync27(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
40080
40358
|
ok = true;
|
|
40081
40359
|
} catch {
|
|
40082
40360
|
ok = false;
|
|
@@ -40113,7 +40391,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40113
40391
|
const venvCmds = {
|
|
40114
40392
|
apt: () => {
|
|
40115
40393
|
try {
|
|
40116
|
-
const pyVer =
|
|
40394
|
+
const pyVer = execSync27(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
40117
40395
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
40118
40396
|
} catch {
|
|
40119
40397
|
return "apt-get install -y python3-venv";
|
|
@@ -40134,19 +40412,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40134
40412
|
}
|
|
40135
40413
|
}
|
|
40136
40414
|
const venvDir = getVenvDir();
|
|
40137
|
-
const venvBin =
|
|
40138
|
-
const venvMoondream =
|
|
40415
|
+
const venvBin = join54(venvDir, "bin");
|
|
40416
|
+
const venvMoondream = join54(venvBin, "moondream-station");
|
|
40139
40417
|
const venv = ensureVenv(log);
|
|
40140
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
40141
|
-
const venvPip2 =
|
|
40418
|
+
if (venv && !hasCmd("moondream-station") && !existsSync37(venvMoondream)) {
|
|
40419
|
+
const venvPip2 = join54(venvBin, "pip");
|
|
40142
40420
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
40143
40421
|
try {
|
|
40144
|
-
|
|
40145
|
-
if (
|
|
40422
|
+
execSync27(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
40423
|
+
if (existsSync37(venvMoondream)) {
|
|
40146
40424
|
log("moondream-station installed successfully.");
|
|
40147
40425
|
} else {
|
|
40148
40426
|
try {
|
|
40149
|
-
const check =
|
|
40427
|
+
const check = execSync27(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
40150
40428
|
if (check.includes("moondream")) {
|
|
40151
40429
|
log("moondream-station package installed.");
|
|
40152
40430
|
}
|
|
@@ -40159,11 +40437,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40159
40437
|
}
|
|
40160
40438
|
}
|
|
40161
40439
|
if (venv) {
|
|
40162
|
-
const venvPython2 =
|
|
40163
|
-
const venvPip2 =
|
|
40440
|
+
const venvPython2 = join54(venvBin, "python");
|
|
40441
|
+
const venvPip2 = join54(venvBin, "pip");
|
|
40164
40442
|
let ocrStackInstalled = false;
|
|
40165
40443
|
try {
|
|
40166
|
-
|
|
40444
|
+
execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
40167
40445
|
ocrStackInstalled = true;
|
|
40168
40446
|
} catch {
|
|
40169
40447
|
}
|
|
@@ -40171,9 +40449,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
40171
40449
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
40172
40450
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
40173
40451
|
try {
|
|
40174
|
-
|
|
40452
|
+
execSync27(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
40175
40453
|
try {
|
|
40176
|
-
|
|
40454
|
+
execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
40177
40455
|
log("OCR Python stack installed successfully.");
|
|
40178
40456
|
} catch {
|
|
40179
40457
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -40207,7 +40485,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40207
40485
|
const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
|
|
40208
40486
|
const cfArch = archMap[arch2] ?? "amd64";
|
|
40209
40487
|
try {
|
|
40210
|
-
|
|
40488
|
+
execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
|
|
40211
40489
|
if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
|
|
40212
40490
|
process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
|
|
40213
40491
|
}
|
|
@@ -40218,7 +40496,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40218
40496
|
} catch {
|
|
40219
40497
|
}
|
|
40220
40498
|
try {
|
|
40221
|
-
|
|
40499
|
+
execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
|
|
40222
40500
|
if (hasCmd("cloudflared")) {
|
|
40223
40501
|
log("cloudflared installed.");
|
|
40224
40502
|
return true;
|
|
@@ -40227,7 +40505,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
40227
40505
|
}
|
|
40228
40506
|
} else if (os === "darwin") {
|
|
40229
40507
|
try {
|
|
40230
|
-
|
|
40508
|
+
execSync27("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
|
|
40231
40509
|
if (hasCmd("cloudflared")) {
|
|
40232
40510
|
log("cloudflared installed via Homebrew.");
|
|
40233
40511
|
return true;
|
|
@@ -40304,10 +40582,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
40304
40582
|
`PARAMETER num_predict ${numPredict}`,
|
|
40305
40583
|
`PARAMETER stop "<|endoftext|>"`
|
|
40306
40584
|
].join("\n");
|
|
40307
|
-
const modelDir2 =
|
|
40308
|
-
|
|
40309
|
-
const modelfilePath =
|
|
40310
|
-
|
|
40585
|
+
const modelDir2 = join54(homedir12(), ".open-agents", "models");
|
|
40586
|
+
mkdirSync15(modelDir2, { recursive: true });
|
|
40587
|
+
const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
|
|
40588
|
+
writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
|
|
40311
40589
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
40312
40590
|
timeout: 12e4
|
|
40313
40591
|
});
|
|
@@ -40369,7 +40647,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
|
|
|
40369
40647
|
}
|
|
40370
40648
|
async function ensureNeovim() {
|
|
40371
40649
|
try {
|
|
40372
|
-
const nvimPath =
|
|
40650
|
+
const nvimPath = execSync27("which nvim 2>/dev/null || where nvim 2>nul", {
|
|
40373
40651
|
encoding: "utf8",
|
|
40374
40652
|
stdio: "pipe",
|
|
40375
40653
|
timeout: 5e3
|
|
@@ -40381,24 +40659,24 @@ async function ensureNeovim() {
|
|
|
40381
40659
|
const platform6 = process.platform;
|
|
40382
40660
|
const arch2 = process.arch;
|
|
40383
40661
|
if (platform6 === "linux") {
|
|
40384
|
-
const binDir =
|
|
40385
|
-
const nvimDest =
|
|
40662
|
+
const binDir = join54(homedir12(), ".local", "bin");
|
|
40663
|
+
const nvimDest = join54(binDir, "nvim");
|
|
40386
40664
|
try {
|
|
40387
|
-
|
|
40665
|
+
mkdirSync15(binDir, { recursive: true });
|
|
40388
40666
|
} catch {
|
|
40389
40667
|
}
|
|
40390
40668
|
const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
|
|
40391
40669
|
const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
|
|
40392
40670
|
console.log(` Downloading Neovim (${appImageName})...`);
|
|
40393
40671
|
try {
|
|
40394
|
-
|
|
40395
|
-
|
|
40672
|
+
execSync27(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
|
|
40673
|
+
execSync27(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
|
|
40396
40674
|
} catch (err) {
|
|
40397
40675
|
console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
|
|
40398
40676
|
return null;
|
|
40399
40677
|
}
|
|
40400
40678
|
try {
|
|
40401
|
-
const ver =
|
|
40679
|
+
const ver = execSync27(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
|
|
40402
40680
|
console.log(` Installed: ${ver}`);
|
|
40403
40681
|
} catch {
|
|
40404
40682
|
console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
|
|
@@ -40413,8 +40691,8 @@ async function ensureNeovim() {
|
|
|
40413
40691
|
if (hasCmd("brew")) {
|
|
40414
40692
|
console.log(" Installing Neovim via Homebrew...");
|
|
40415
40693
|
try {
|
|
40416
|
-
|
|
40417
|
-
const nvimPath =
|
|
40694
|
+
execSync27("brew install neovim", { stdio: "inherit", timeout: 12e4 });
|
|
40695
|
+
const nvimPath = execSync27("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
|
|
40418
40696
|
return nvimPath || null;
|
|
40419
40697
|
} catch {
|
|
40420
40698
|
console.log(" brew install neovim failed.");
|
|
@@ -40428,7 +40706,7 @@ async function ensureNeovim() {
|
|
|
40428
40706
|
if (hasCmd("choco")) {
|
|
40429
40707
|
console.log(" Installing Neovim via Chocolatey...");
|
|
40430
40708
|
try {
|
|
40431
|
-
|
|
40709
|
+
execSync27("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
|
|
40432
40710
|
return "nvim";
|
|
40433
40711
|
} catch {
|
|
40434
40712
|
console.log(" choco install neovim failed.");
|
|
@@ -40437,7 +40715,7 @@ async function ensureNeovim() {
|
|
|
40437
40715
|
if (hasCmd("winget")) {
|
|
40438
40716
|
console.log(" Installing Neovim via winget...");
|
|
40439
40717
|
try {
|
|
40440
|
-
|
|
40718
|
+
execSync27("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
|
|
40441
40719
|
stdio: "inherit",
|
|
40442
40720
|
timeout: 12e4
|
|
40443
40721
|
});
|
|
@@ -40453,9 +40731,9 @@ async function ensureNeovim() {
|
|
|
40453
40731
|
}
|
|
40454
40732
|
function ensurePathInShellRc(binDir) {
|
|
40455
40733
|
const shell = process.env.SHELL ?? "";
|
|
40456
|
-
const rcFile = shell.includes("zsh") ?
|
|
40734
|
+
const rcFile = shell.includes("zsh") ? join54(homedir12(), ".zshrc") : join54(homedir12(), ".bashrc");
|
|
40457
40735
|
try {
|
|
40458
|
-
const rcContent =
|
|
40736
|
+
const rcContent = existsSync37(rcFile) ? readFileSync28(rcFile, "utf8") : "";
|
|
40459
40737
|
if (rcContent.includes(binDir))
|
|
40460
40738
|
return;
|
|
40461
40739
|
const exportLine = `
|
|
@@ -41170,7 +41448,7 @@ var init_tui_select = __esm({
|
|
|
41170
41448
|
});
|
|
41171
41449
|
|
|
41172
41450
|
// packages/cli/dist/tui/drop-panel.js
|
|
41173
|
-
import { existsSync as
|
|
41451
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
41174
41452
|
import { extname as extname10, resolve as resolve29 } from "node:path";
|
|
41175
41453
|
function ansi4(code, text) {
|
|
41176
41454
|
return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
@@ -41285,7 +41563,7 @@ function showDropPanel(opts) {
|
|
|
41285
41563
|
filePath = decodeURIComponent(filePath.slice(7));
|
|
41286
41564
|
}
|
|
41287
41565
|
filePath = resolve29(filePath);
|
|
41288
|
-
if (!
|
|
41566
|
+
if (!existsSync38(filePath)) {
|
|
41289
41567
|
errorMsg = `File not found: ${filePath}`;
|
|
41290
41568
|
render();
|
|
41291
41569
|
return;
|
|
@@ -41356,10 +41634,10 @@ var init_drop_panel = __esm({
|
|
|
41356
41634
|
});
|
|
41357
41635
|
|
|
41358
41636
|
// packages/cli/dist/tui/neovim-mode.js
|
|
41359
|
-
import { existsSync as
|
|
41637
|
+
import { existsSync as existsSync39, unlinkSync as unlinkSync8 } from "node:fs";
|
|
41360
41638
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
41361
|
-
import { join as
|
|
41362
|
-
import { execSync as
|
|
41639
|
+
import { join as join55 } from "node:path";
|
|
41640
|
+
import { execSync as execSync28 } from "node:child_process";
|
|
41363
41641
|
function isNeovimActive() {
|
|
41364
41642
|
return _state !== null && !_state.cleanedUp;
|
|
41365
41643
|
}
|
|
@@ -41377,7 +41655,7 @@ async function startNeovimMode(opts) {
|
|
|
41377
41655
|
}
|
|
41378
41656
|
let nvimPath;
|
|
41379
41657
|
try {
|
|
41380
|
-
nvimPath =
|
|
41658
|
+
nvimPath = execSync28("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
|
|
41381
41659
|
if (!nvimPath)
|
|
41382
41660
|
throw new Error();
|
|
41383
41661
|
} catch {
|
|
@@ -41406,10 +41684,10 @@ async function startNeovimMode(opts) {
|
|
|
41406
41684
|
);
|
|
41407
41685
|
} catch {
|
|
41408
41686
|
}
|
|
41409
|
-
const socketPath =
|
|
41687
|
+
const socketPath = join55(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
41410
41688
|
try {
|
|
41411
|
-
if (
|
|
41412
|
-
|
|
41689
|
+
if (existsSync39(socketPath))
|
|
41690
|
+
unlinkSync8(socketPath);
|
|
41413
41691
|
} catch {
|
|
41414
41692
|
}
|
|
41415
41693
|
const ptyCols = opts.cols;
|
|
@@ -41635,13 +41913,13 @@ function resizeNeovim(cols, contentRows) {
|
|
|
41635
41913
|
}
|
|
41636
41914
|
async function connectRPC(state, neovimPkg, cols) {
|
|
41637
41915
|
let attempts = 0;
|
|
41638
|
-
while (!
|
|
41916
|
+
while (!existsSync39(state.socketPath) && attempts < 30) {
|
|
41639
41917
|
await new Promise((r) => setTimeout(r, 200));
|
|
41640
41918
|
attempts++;
|
|
41641
41919
|
if (state.cleanedUp)
|
|
41642
41920
|
return;
|
|
41643
41921
|
}
|
|
41644
|
-
if (!
|
|
41922
|
+
if (!existsSync39(state.socketPath))
|
|
41645
41923
|
return;
|
|
41646
41924
|
const nvim = neovimPkg.attach({ socket: state.socketPath });
|
|
41647
41925
|
state.nvim = nvim;
|
|
@@ -41778,8 +42056,8 @@ function doCleanup(state) {
|
|
|
41778
42056
|
state.pty = null;
|
|
41779
42057
|
}
|
|
41780
42058
|
try {
|
|
41781
|
-
if (
|
|
41782
|
-
|
|
42059
|
+
if (existsSync39(state.socketPath))
|
|
42060
|
+
unlinkSync8(state.socketPath);
|
|
41783
42061
|
} catch {
|
|
41784
42062
|
}
|
|
41785
42063
|
if (state.stdinHandler) {
|
|
@@ -41835,10 +42113,10 @@ __export(voice_exports, {
|
|
|
41835
42113
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
41836
42114
|
resetNarrationContext: () => resetNarrationContext
|
|
41837
42115
|
});
|
|
41838
|
-
import { existsSync as
|
|
41839
|
-
import { join as
|
|
42116
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readFileSync as readFileSync29, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
|
|
42117
|
+
import { join as join56, dirname as dirname18 } from "node:path";
|
|
41840
42118
|
import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
|
|
41841
|
-
import { execSync as
|
|
42119
|
+
import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
|
|
41842
42120
|
import { createRequire } from "node:module";
|
|
41843
42121
|
function sanitizeForTTS(text) {
|
|
41844
42122
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
@@ -41861,40 +42139,40 @@ function listVoiceModels() {
|
|
|
41861
42139
|
}));
|
|
41862
42140
|
}
|
|
41863
42141
|
function voiceDir() {
|
|
41864
|
-
return
|
|
42142
|
+
return join56(homedir13(), ".open-agents", "voice");
|
|
41865
42143
|
}
|
|
41866
42144
|
function modelsDir() {
|
|
41867
|
-
return
|
|
42145
|
+
return join56(voiceDir(), "models");
|
|
41868
42146
|
}
|
|
41869
42147
|
function modelDir(id) {
|
|
41870
|
-
return
|
|
42148
|
+
return join56(modelsDir(), id);
|
|
41871
42149
|
}
|
|
41872
42150
|
function modelOnnxPath(id) {
|
|
41873
|
-
return
|
|
42151
|
+
return join56(modelDir(id), "model.onnx");
|
|
41874
42152
|
}
|
|
41875
42153
|
function modelConfigPath(id) {
|
|
41876
|
-
return
|
|
42154
|
+
return join56(modelDir(id), "config.json");
|
|
41877
42155
|
}
|
|
41878
42156
|
function luxttsVenvDir() {
|
|
41879
|
-
return
|
|
42157
|
+
return join56(voiceDir(), "luxtts-venv");
|
|
41880
42158
|
}
|
|
41881
42159
|
function luxttsVenvPy() {
|
|
41882
|
-
return platform3() === "win32" ?
|
|
42160
|
+
return platform3() === "win32" ? join56(luxttsVenvDir(), "Scripts", "python.exe") : join56(luxttsVenvDir(), "bin", "python3");
|
|
41883
42161
|
}
|
|
41884
42162
|
function luxttsRepoDir() {
|
|
41885
|
-
return
|
|
42163
|
+
return join56(voiceDir(), "LuxTTS");
|
|
41886
42164
|
}
|
|
41887
42165
|
function luxttsCloneRefsDir() {
|
|
41888
|
-
return
|
|
42166
|
+
return join56(voiceDir(), "clone-refs");
|
|
41889
42167
|
}
|
|
41890
42168
|
function luxttsInferScript() {
|
|
41891
|
-
return
|
|
42169
|
+
return join56(voiceDir(), "luxtts-infer.py");
|
|
41892
42170
|
}
|
|
41893
42171
|
function writeDetectTorchScript(targetPath) {
|
|
41894
|
-
if (
|
|
42172
|
+
if (existsSync40(targetPath))
|
|
41895
42173
|
return;
|
|
41896
42174
|
try {
|
|
41897
|
-
|
|
42175
|
+
mkdirSync16(dirname18(targetPath), { recursive: true });
|
|
41898
42176
|
} catch {
|
|
41899
42177
|
}
|
|
41900
42178
|
const script = `#!/usr/bin/env python3
|
|
@@ -41967,7 +42245,7 @@ def main():
|
|
|
41967
42245
|
if __name__ == "__main__": main()
|
|
41968
42246
|
`;
|
|
41969
42247
|
try {
|
|
41970
|
-
|
|
42248
|
+
writeFileSync17(targetPath, script, { mode: 493 });
|
|
41971
42249
|
} catch {
|
|
41972
42250
|
}
|
|
41973
42251
|
}
|
|
@@ -42777,8 +43055,8 @@ var init_voice = __esm({
|
|
|
42777
43055
|
const refsDir = luxttsCloneRefsDir();
|
|
42778
43056
|
const targets = ["glados", "overwatch"];
|
|
42779
43057
|
for (const modelId of targets) {
|
|
42780
|
-
const refFile =
|
|
42781
|
-
if (
|
|
43058
|
+
const refFile = join56(refsDir, `${modelId}-ref.wav`);
|
|
43059
|
+
if (existsSync40(refFile))
|
|
42782
43060
|
continue;
|
|
42783
43061
|
try {
|
|
42784
43062
|
await this.generateCloneRef(modelId);
|
|
@@ -42857,24 +43135,24 @@ var init_voice = __esm({
|
|
|
42857
43135
|
}
|
|
42858
43136
|
p = p.replace(/\\ /g, " ");
|
|
42859
43137
|
if (p.startsWith("~/") || p === "~") {
|
|
42860
|
-
p =
|
|
43138
|
+
p = join56(homedir13(), p.slice(1));
|
|
42861
43139
|
}
|
|
42862
|
-
if (!
|
|
43140
|
+
if (!existsSync40(p)) {
|
|
42863
43141
|
return `File not found: ${p}
|
|
42864
43142
|
(original input: ${audioPath})`;
|
|
42865
43143
|
}
|
|
42866
43144
|
audioPath = p;
|
|
42867
43145
|
const refsDir = luxttsCloneRefsDir();
|
|
42868
|
-
if (!
|
|
42869
|
-
|
|
43146
|
+
if (!existsSync40(refsDir))
|
|
43147
|
+
mkdirSync16(refsDir, { recursive: true });
|
|
42870
43148
|
const ext = audioPath.split(".").pop() || "wav";
|
|
42871
43149
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
42872
43150
|
const ts = Date.now().toString(36);
|
|
42873
43151
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
42874
|
-
const destPath =
|
|
43152
|
+
const destPath = join56(refsDir, destFilename);
|
|
42875
43153
|
try {
|
|
42876
|
-
const data =
|
|
42877
|
-
|
|
43154
|
+
const data = readFileSync29(audioPath);
|
|
43155
|
+
writeFileSync17(destPath, data);
|
|
42878
43156
|
} catch (err) {
|
|
42879
43157
|
return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
|
|
42880
43158
|
}
|
|
@@ -42914,9 +43192,9 @@ var init_voice = __esm({
|
|
|
42914
43192
|
return `Failed to synthesize reference audio from ${source.label}.`;
|
|
42915
43193
|
}
|
|
42916
43194
|
const refsDir = luxttsCloneRefsDir();
|
|
42917
|
-
if (!
|
|
42918
|
-
|
|
42919
|
-
const destPath =
|
|
43195
|
+
if (!existsSync40(refsDir))
|
|
43196
|
+
mkdirSync16(refsDir, { recursive: true });
|
|
43197
|
+
const destPath = join56(refsDir, `${sourceModelId}-ref.wav`);
|
|
42920
43198
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
42921
43199
|
this.writeWav(audioData, sampleRate, destPath);
|
|
42922
43200
|
this.luxttsCloneRef = destPath;
|
|
@@ -42932,23 +43210,23 @@ var init_voice = __esm({
|
|
|
42932
43210
|
// -------------------------------------------------------------------------
|
|
42933
43211
|
/** Metadata file for friendly names of clone refs */
|
|
42934
43212
|
static cloneMetaFile() {
|
|
42935
|
-
return
|
|
43213
|
+
return join56(luxttsCloneRefsDir(), "meta.json");
|
|
42936
43214
|
}
|
|
42937
43215
|
loadCloneMeta() {
|
|
42938
43216
|
const p = _VoiceEngine.cloneMetaFile();
|
|
42939
|
-
if (!
|
|
43217
|
+
if (!existsSync40(p))
|
|
42940
43218
|
return {};
|
|
42941
43219
|
try {
|
|
42942
|
-
return JSON.parse(
|
|
43220
|
+
return JSON.parse(readFileSync29(p, "utf8"));
|
|
42943
43221
|
} catch {
|
|
42944
43222
|
return {};
|
|
42945
43223
|
}
|
|
42946
43224
|
}
|
|
42947
43225
|
saveCloneMeta(meta) {
|
|
42948
43226
|
const dir = luxttsCloneRefsDir();
|
|
42949
|
-
if (!
|
|
42950
|
-
|
|
42951
|
-
|
|
43227
|
+
if (!existsSync40(dir))
|
|
43228
|
+
mkdirSync16(dir, { recursive: true });
|
|
43229
|
+
writeFileSync17(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
|
|
42952
43230
|
}
|
|
42953
43231
|
/** Audio file extensions recognized as clone references */
|
|
42954
43232
|
static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
|
|
@@ -42958,15 +43236,15 @@ var init_voice = __esm({
|
|
|
42958
43236
|
*/
|
|
42959
43237
|
listCloneRefs() {
|
|
42960
43238
|
const dir = luxttsCloneRefsDir();
|
|
42961
|
-
if (!
|
|
43239
|
+
if (!existsSync40(dir))
|
|
42962
43240
|
return [];
|
|
42963
43241
|
const meta = this.loadCloneMeta();
|
|
42964
|
-
const files =
|
|
43242
|
+
const files = readdirSync11(dir).filter((f) => {
|
|
42965
43243
|
const ext = f.split(".").pop()?.toLowerCase() ?? "";
|
|
42966
43244
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
42967
43245
|
});
|
|
42968
43246
|
return files.map((f) => {
|
|
42969
|
-
const p =
|
|
43247
|
+
const p = join56(dir, f);
|
|
42970
43248
|
let size = 0;
|
|
42971
43249
|
try {
|
|
42972
43250
|
size = statSync13(p).size;
|
|
@@ -42983,11 +43261,11 @@ var init_voice = __esm({
|
|
|
42983
43261
|
}
|
|
42984
43262
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
42985
43263
|
deleteCloneRef(filename) {
|
|
42986
|
-
const p =
|
|
42987
|
-
if (!
|
|
43264
|
+
const p = join56(luxttsCloneRefsDir(), filename);
|
|
43265
|
+
if (!existsSync40(p))
|
|
42988
43266
|
return false;
|
|
42989
43267
|
try {
|
|
42990
|
-
|
|
43268
|
+
unlinkSync9(p);
|
|
42991
43269
|
const meta = this.loadCloneMeta();
|
|
42992
43270
|
delete meta[filename];
|
|
42993
43271
|
this.saveCloneMeta(meta);
|
|
@@ -43008,8 +43286,8 @@ var init_voice = __esm({
|
|
|
43008
43286
|
}
|
|
43009
43287
|
/** Set the active clone reference by filename. */
|
|
43010
43288
|
setActiveCloneRef(filename) {
|
|
43011
|
-
const p =
|
|
43012
|
-
if (!
|
|
43289
|
+
const p = join56(luxttsCloneRefsDir(), filename);
|
|
43290
|
+
if (!existsSync40(p))
|
|
43013
43291
|
return `File not found: ${filename}`;
|
|
43014
43292
|
this.luxttsCloneRef = p;
|
|
43015
43293
|
return `Active clone voice set to: ${filename}`;
|
|
@@ -43265,7 +43543,7 @@ var init_voice = __esm({
|
|
|
43265
43543
|
}
|
|
43266
43544
|
if (prefetchedWav) {
|
|
43267
43545
|
try {
|
|
43268
|
-
|
|
43546
|
+
unlinkSync9(prefetchedWav.path);
|
|
43269
43547
|
} catch {
|
|
43270
43548
|
}
|
|
43271
43549
|
}
|
|
@@ -43334,11 +43612,11 @@ var init_voice = __esm({
|
|
|
43334
43612
|
}
|
|
43335
43613
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
43336
43614
|
}
|
|
43337
|
-
const wavPath =
|
|
43615
|
+
const wavPath = join56(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
43338
43616
|
this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
|
|
43339
43617
|
await this.playWav(wavPath);
|
|
43340
43618
|
try {
|
|
43341
|
-
|
|
43619
|
+
unlinkSync9(wavPath);
|
|
43342
43620
|
} catch {
|
|
43343
43621
|
}
|
|
43344
43622
|
}
|
|
@@ -43451,7 +43729,7 @@ var init_voice = __esm({
|
|
|
43451
43729
|
buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
|
|
43452
43730
|
pos += 2;
|
|
43453
43731
|
}
|
|
43454
|
-
|
|
43732
|
+
writeFileSync17(path, buffer);
|
|
43455
43733
|
}
|
|
43456
43734
|
// -------------------------------------------------------------------------
|
|
43457
43735
|
// Phonemization
|
|
@@ -43529,7 +43807,7 @@ var init_voice = __esm({
|
|
|
43529
43807
|
return buffer;
|
|
43530
43808
|
}
|
|
43531
43809
|
writeWav(samples, sampleRate, path) {
|
|
43532
|
-
|
|
43810
|
+
writeFileSync17(path, this.buildWavBuffer(samples, sampleRate));
|
|
43533
43811
|
}
|
|
43534
43812
|
// -------------------------------------------------------------------------
|
|
43535
43813
|
// Audio playback (system default speakers)
|
|
@@ -43579,7 +43857,7 @@ var init_voice = __esm({
|
|
|
43579
43857
|
}
|
|
43580
43858
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
43581
43859
|
try {
|
|
43582
|
-
|
|
43860
|
+
execSync29(`which ${player}`, { stdio: "pipe" });
|
|
43583
43861
|
return [player, path];
|
|
43584
43862
|
} catch {
|
|
43585
43863
|
}
|
|
@@ -43608,7 +43886,7 @@ var init_voice = __esm({
|
|
|
43608
43886
|
return this.python3Path;
|
|
43609
43887
|
for (const bin of ["python3", "python"]) {
|
|
43610
43888
|
try {
|
|
43611
|
-
const path =
|
|
43889
|
+
const path = execSync29(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
|
|
43612
43890
|
if (path) {
|
|
43613
43891
|
this.python3Path = path;
|
|
43614
43892
|
return path;
|
|
@@ -43674,7 +43952,7 @@ var init_voice = __esm({
|
|
|
43674
43952
|
return false;
|
|
43675
43953
|
}
|
|
43676
43954
|
try {
|
|
43677
|
-
|
|
43955
|
+
execSync29(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
|
|
43678
43956
|
this.mlxInstalled = true;
|
|
43679
43957
|
return true;
|
|
43680
43958
|
} catch {
|
|
@@ -43727,7 +44005,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43727
44005
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
43728
44006
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
43729
44007
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
43730
|
-
const wavPath =
|
|
44008
|
+
const wavPath = join56(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
43731
44009
|
const pyScript = [
|
|
43732
44010
|
"import sys, json",
|
|
43733
44011
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -43735,20 +44013,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43735
44013
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43736
44014
|
].join("; ");
|
|
43737
44015
|
try {
|
|
43738
|
-
|
|
44016
|
+
execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43739
44017
|
} catch (err) {
|
|
43740
44018
|
try {
|
|
43741
44019
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43742
|
-
|
|
44020
|
+
execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43743
44021
|
} catch (err2) {
|
|
43744
44022
|
return;
|
|
43745
44023
|
}
|
|
43746
44024
|
}
|
|
43747
|
-
if (!
|
|
44025
|
+
if (!existsSync40(wavPath))
|
|
43748
44026
|
return;
|
|
43749
44027
|
if (volume !== 1) {
|
|
43750
44028
|
try {
|
|
43751
|
-
const wavData =
|
|
44029
|
+
const wavData = readFileSync29(wavPath);
|
|
43752
44030
|
if (wavData.length > 44) {
|
|
43753
44031
|
const header = wavData.subarray(0, 44);
|
|
43754
44032
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -43756,14 +44034,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43756
44034
|
samples[i] = Math.round(samples[i] * volume);
|
|
43757
44035
|
}
|
|
43758
44036
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
43759
|
-
|
|
44037
|
+
writeFileSync17(wavPath, scaled);
|
|
43760
44038
|
}
|
|
43761
44039
|
} catch {
|
|
43762
44040
|
}
|
|
43763
44041
|
}
|
|
43764
44042
|
if (this.onPCMOutput) {
|
|
43765
44043
|
try {
|
|
43766
|
-
const wavData =
|
|
44044
|
+
const wavData = readFileSync29(wavPath);
|
|
43767
44045
|
if (wavData.length > 44) {
|
|
43768
44046
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
43769
44047
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -43774,7 +44052,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43774
44052
|
}
|
|
43775
44053
|
await this.playWav(wavPath);
|
|
43776
44054
|
try {
|
|
43777
|
-
|
|
44055
|
+
unlinkSync9(wavPath);
|
|
43778
44056
|
} catch {
|
|
43779
44057
|
}
|
|
43780
44058
|
}
|
|
@@ -43795,7 +44073,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43795
44073
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
43796
44074
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
43797
44075
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
43798
|
-
const wavPath =
|
|
44076
|
+
const wavPath = join56(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
43799
44077
|
const pyScript = [
|
|
43800
44078
|
"import sys, json",
|
|
43801
44079
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -43803,20 +44081,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43803
44081
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
43804
44082
|
].join("; ");
|
|
43805
44083
|
try {
|
|
43806
|
-
|
|
44084
|
+
execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43807
44085
|
} catch {
|
|
43808
44086
|
try {
|
|
43809
44087
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
43810
|
-
|
|
44088
|
+
execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
43811
44089
|
} catch {
|
|
43812
44090
|
return null;
|
|
43813
44091
|
}
|
|
43814
44092
|
}
|
|
43815
|
-
if (!
|
|
44093
|
+
if (!existsSync40(wavPath))
|
|
43816
44094
|
return null;
|
|
43817
44095
|
try {
|
|
43818
|
-
const data =
|
|
43819
|
-
|
|
44096
|
+
const data = readFileSync29(wavPath);
|
|
44097
|
+
unlinkSync9(wavPath);
|
|
43820
44098
|
return data;
|
|
43821
44099
|
} catch {
|
|
43822
44100
|
return null;
|
|
@@ -43838,7 +44116,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43838
44116
|
}
|
|
43839
44117
|
const venvDir = luxttsVenvDir();
|
|
43840
44118
|
const venvPy = luxttsVenvPy();
|
|
43841
|
-
if (
|
|
44119
|
+
if (existsSync40(venvPy)) {
|
|
43842
44120
|
try {
|
|
43843
44121
|
await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
|
|
43844
44122
|
let hasCudaSys = false;
|
|
@@ -43852,7 +44130,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43852
44130
|
if (torchCheck === "cpu") {
|
|
43853
44131
|
renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
|
|
43854
44132
|
try {
|
|
43855
|
-
const detectScript =
|
|
44133
|
+
const detectScript = join56(voiceDir(), "detect-torch.py");
|
|
43856
44134
|
writeDetectTorchScript(detectScript);
|
|
43857
44135
|
let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
|
|
43858
44136
|
try {
|
|
@@ -43877,7 +44155,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43877
44155
|
}
|
|
43878
44156
|
}
|
|
43879
44157
|
renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
|
|
43880
|
-
if (!
|
|
44158
|
+
if (!existsSync40(venvDir)) {
|
|
43881
44159
|
renderInfo(" Creating Python virtual environment...");
|
|
43882
44160
|
try {
|
|
43883
44161
|
await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
|
|
@@ -43886,7 +44164,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43886
44164
|
}
|
|
43887
44165
|
}
|
|
43888
44166
|
{
|
|
43889
|
-
const detectScript =
|
|
44167
|
+
const detectScript = join56(voiceDir(), "detect-torch.py");
|
|
43890
44168
|
writeDetectTorchScript(detectScript);
|
|
43891
44169
|
let pipArgsStr = "torch torchaudio";
|
|
43892
44170
|
let torchDesc = "unknown platform";
|
|
@@ -43923,10 +44201,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43923
44201
|
}
|
|
43924
44202
|
}
|
|
43925
44203
|
const repoDir = luxttsRepoDir();
|
|
43926
|
-
if (!
|
|
44204
|
+
if (!existsSync40(join56(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
43927
44205
|
renderInfo(" Cloning LuxTTS repository...");
|
|
43928
44206
|
try {
|
|
43929
|
-
if (
|
|
44207
|
+
if (existsSync40(repoDir)) {
|
|
43930
44208
|
const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
|
|
43931
44209
|
await this.asyncShell(rmCmd, 3e4);
|
|
43932
44210
|
}
|
|
@@ -43965,7 +44243,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
43965
44243
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
43966
44244
|
}
|
|
43967
44245
|
}
|
|
43968
|
-
const isJetson = isArm && (
|
|
44246
|
+
const isJetson = isArm && (existsSync40("/etc/nv_tegra_release") || existsSync40("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
43969
44247
|
const installSteps = isArm ? [
|
|
43970
44248
|
// ARM: install individually so we get clear error messages per package.
|
|
43971
44249
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
@@ -44033,14 +44311,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
44033
44311
|
}
|
|
44034
44312
|
/** Auto-detect an existing clone reference in the refs directory */
|
|
44035
44313
|
autoDetectCloneRef() {
|
|
44036
|
-
if (this.luxttsCloneRef &&
|
|
44314
|
+
if (this.luxttsCloneRef && existsSync40(this.luxttsCloneRef))
|
|
44037
44315
|
return;
|
|
44038
44316
|
const refsDir = luxttsCloneRefsDir();
|
|
44039
|
-
if (!
|
|
44317
|
+
if (!existsSync40(refsDir))
|
|
44040
44318
|
return;
|
|
44041
44319
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
44042
|
-
const p =
|
|
44043
|
-
if (
|
|
44320
|
+
const p = join56(refsDir, name);
|
|
44321
|
+
if (existsSync40(p)) {
|
|
44044
44322
|
this.luxttsCloneRef = p;
|
|
44045
44323
|
return;
|
|
44046
44324
|
}
|
|
@@ -44140,15 +44418,15 @@ if __name__ == '__main__':
|
|
|
44140
44418
|
main()
|
|
44141
44419
|
`;
|
|
44142
44420
|
const scriptPath2 = luxttsInferScript();
|
|
44143
|
-
|
|
44144
|
-
|
|
44421
|
+
mkdirSync16(voiceDir(), { recursive: true });
|
|
44422
|
+
writeFileSync17(scriptPath2, script);
|
|
44145
44423
|
}
|
|
44146
44424
|
/** Ensure the LuxTTS daemon is running, spawn if needed */
|
|
44147
44425
|
async ensureLuxttsDaemon() {
|
|
44148
44426
|
if (this._luxttsDaemon && !this._luxttsDaemon.killed)
|
|
44149
44427
|
return true;
|
|
44150
44428
|
const venvPy = luxttsVenvPy();
|
|
44151
|
-
if (!
|
|
44429
|
+
if (!existsSync40(venvPy))
|
|
44152
44430
|
return false;
|
|
44153
44431
|
return new Promise((resolve34) => {
|
|
44154
44432
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
@@ -44232,7 +44510,7 @@ if __name__ == '__main__':
|
|
|
44232
44510
|
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
44233
44511
|
*/
|
|
44234
44512
|
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
44235
|
-
if (!this.luxttsCloneRef || !
|
|
44513
|
+
if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
|
|
44236
44514
|
return null;
|
|
44237
44515
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44238
44516
|
if (!cleaned)
|
|
@@ -44240,7 +44518,7 @@ if __name__ == '__main__':
|
|
|
44240
44518
|
const ready = await this.ensureLuxttsDaemon();
|
|
44241
44519
|
if (!ready)
|
|
44242
44520
|
return null;
|
|
44243
|
-
const wavPath =
|
|
44521
|
+
const wavPath = join56(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
44244
44522
|
try {
|
|
44245
44523
|
await this.luxttsRequest({
|
|
44246
44524
|
action: "synthesize",
|
|
@@ -44252,17 +44530,17 @@ if __name__ == '__main__':
|
|
|
44252
44530
|
} catch {
|
|
44253
44531
|
return null;
|
|
44254
44532
|
}
|
|
44255
|
-
return
|
|
44533
|
+
return existsSync40(wavPath) ? wavPath : null;
|
|
44256
44534
|
}
|
|
44257
44535
|
/**
|
|
44258
44536
|
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
44259
44537
|
* Cleans up the WAV file after playback.
|
|
44260
44538
|
*/
|
|
44261
44539
|
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
44262
|
-
if (!
|
|
44540
|
+
if (!existsSync40(wavPath))
|
|
44263
44541
|
return;
|
|
44264
44542
|
try {
|
|
44265
|
-
const wavData =
|
|
44543
|
+
const wavData = readFileSync29(wavPath);
|
|
44266
44544
|
if (wavData.length > 44) {
|
|
44267
44545
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44268
44546
|
const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
@@ -44277,13 +44555,13 @@ if __name__ == '__main__':
|
|
|
44277
44555
|
}
|
|
44278
44556
|
const header = wavData.subarray(0, 44);
|
|
44279
44557
|
const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
|
|
44280
|
-
|
|
44558
|
+
writeFileSync17(wavPath, scaled);
|
|
44281
44559
|
}
|
|
44282
44560
|
} catch {
|
|
44283
44561
|
}
|
|
44284
44562
|
if (pitchFactor !== 1) {
|
|
44285
44563
|
try {
|
|
44286
|
-
const wavData =
|
|
44564
|
+
const wavData = readFileSync29(wavPath);
|
|
44287
44565
|
if (wavData.length > 44) {
|
|
44288
44566
|
const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
|
|
44289
44567
|
const float32 = new Float32Array(int16.length);
|
|
@@ -44298,7 +44576,7 @@ if __name__ == '__main__':
|
|
|
44298
44576
|
}
|
|
44299
44577
|
if (this.onPCMOutput) {
|
|
44300
44578
|
try {
|
|
44301
|
-
const wavData =
|
|
44579
|
+
const wavData = readFileSync29(wavPath);
|
|
44302
44580
|
if (wavData.length > 44) {
|
|
44303
44581
|
const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
|
|
44304
44582
|
const sampleRate = wavData.readUInt32LE(24);
|
|
@@ -44309,7 +44587,7 @@ if __name__ == '__main__':
|
|
|
44309
44587
|
}
|
|
44310
44588
|
if (stereoDelayMs > 0) {
|
|
44311
44589
|
try {
|
|
44312
|
-
const wavData =
|
|
44590
|
+
const wavData = readFileSync29(wavPath);
|
|
44313
44591
|
if (wavData.length > 44) {
|
|
44314
44592
|
const sampleRate = wavData.readUInt32LE(24);
|
|
44315
44593
|
const numChannels = wavData.readUInt16LE(22);
|
|
@@ -44329,7 +44607,7 @@ if __name__ == '__main__':
|
|
|
44329
44607
|
await this.playWav(wavPath);
|
|
44330
44608
|
await this.sleep(150);
|
|
44331
44609
|
try {
|
|
44332
|
-
|
|
44610
|
+
unlinkSync9(wavPath);
|
|
44333
44611
|
} catch {
|
|
44334
44612
|
}
|
|
44335
44613
|
}
|
|
@@ -44345,7 +44623,7 @@ if __name__ == '__main__':
|
|
|
44345
44623
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
44346
44624
|
*/
|
|
44347
44625
|
async synthesizeLuxttsToBuffer(text) {
|
|
44348
|
-
if (!this.luxttsCloneRef || !
|
|
44626
|
+
if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
|
|
44349
44627
|
return null;
|
|
44350
44628
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
44351
44629
|
if (!cleaned)
|
|
@@ -44353,7 +44631,7 @@ if __name__ == '__main__':
|
|
|
44353
44631
|
const ready = await this.ensureLuxttsDaemon();
|
|
44354
44632
|
if (!ready)
|
|
44355
44633
|
return null;
|
|
44356
|
-
const wavPath =
|
|
44634
|
+
const wavPath = join56(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
44357
44635
|
try {
|
|
44358
44636
|
await this.luxttsRequest({
|
|
44359
44637
|
action: "synthesize",
|
|
@@ -44365,11 +44643,11 @@ if __name__ == '__main__':
|
|
|
44365
44643
|
} catch {
|
|
44366
44644
|
return null;
|
|
44367
44645
|
}
|
|
44368
|
-
if (!
|
|
44646
|
+
if (!existsSync40(wavPath))
|
|
44369
44647
|
return null;
|
|
44370
44648
|
try {
|
|
44371
|
-
const data =
|
|
44372
|
-
|
|
44649
|
+
const data = readFileSync29(wavPath);
|
|
44650
|
+
unlinkSync9(wavPath);
|
|
44373
44651
|
return data;
|
|
44374
44652
|
} catch {
|
|
44375
44653
|
return null;
|
|
@@ -44382,40 +44660,40 @@ if __name__ == '__main__':
|
|
|
44382
44660
|
if (this.ort)
|
|
44383
44661
|
return;
|
|
44384
44662
|
const arch2 = process.arch;
|
|
44385
|
-
|
|
44386
|
-
const pkgPath =
|
|
44663
|
+
mkdirSync16(voiceDir(), { recursive: true });
|
|
44664
|
+
const pkgPath = join56(voiceDir(), "package.json");
|
|
44387
44665
|
const expectedDeps = {
|
|
44388
44666
|
"onnxruntime-node": "^1.21.0",
|
|
44389
44667
|
"phonemizer": "^1.2.1"
|
|
44390
44668
|
};
|
|
44391
|
-
if (
|
|
44669
|
+
if (existsSync40(pkgPath)) {
|
|
44392
44670
|
try {
|
|
44393
|
-
const existing = JSON.parse(
|
|
44671
|
+
const existing = JSON.parse(readFileSync29(pkgPath, "utf8"));
|
|
44394
44672
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
44395
44673
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
44396
|
-
|
|
44674
|
+
writeFileSync17(pkgPath, JSON.stringify(existing, null, 2));
|
|
44397
44675
|
}
|
|
44398
44676
|
} catch {
|
|
44399
44677
|
}
|
|
44400
44678
|
}
|
|
44401
|
-
if (!
|
|
44402
|
-
|
|
44679
|
+
if (!existsSync40(pkgPath)) {
|
|
44680
|
+
writeFileSync17(pkgPath, JSON.stringify({
|
|
44403
44681
|
name: "open-agents-voice",
|
|
44404
44682
|
private: true,
|
|
44405
44683
|
dependencies: expectedDeps
|
|
44406
44684
|
}, null, 2));
|
|
44407
44685
|
}
|
|
44408
|
-
const voiceRequire = createRequire(
|
|
44686
|
+
const voiceRequire = createRequire(join56(voiceDir(), "index.js"));
|
|
44409
44687
|
const probeOnnx = async () => {
|
|
44410
44688
|
try {
|
|
44411
|
-
const output = await this.asyncShell(`NODE_PATH="${
|
|
44689
|
+
const output = await this.asyncShell(`NODE_PATH="${join56(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
|
|
44412
44690
|
return output.trim() === "OK";
|
|
44413
44691
|
} catch {
|
|
44414
44692
|
return false;
|
|
44415
44693
|
}
|
|
44416
44694
|
};
|
|
44417
|
-
const onnxNodeModules =
|
|
44418
|
-
const onnxInstalled =
|
|
44695
|
+
const onnxNodeModules = join56(voiceDir(), "node_modules", "onnxruntime-node");
|
|
44696
|
+
const onnxInstalled = existsSync40(onnxNodeModules);
|
|
44419
44697
|
if (onnxInstalled && !await probeOnnx()) {
|
|
44420
44698
|
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.`);
|
|
44421
44699
|
}
|
|
@@ -44465,18 +44743,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44465
44743
|
const dir = modelDir(id);
|
|
44466
44744
|
const onnxPath = modelOnnxPath(id);
|
|
44467
44745
|
const configPath = modelConfigPath(id);
|
|
44468
|
-
if (
|
|
44746
|
+
if (existsSync40(onnxPath) && existsSync40(configPath))
|
|
44469
44747
|
return;
|
|
44470
|
-
|
|
44471
|
-
if (!
|
|
44748
|
+
mkdirSync16(dir, { recursive: true });
|
|
44749
|
+
if (!existsSync40(configPath)) {
|
|
44472
44750
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
44473
44751
|
const configResp = await fetch(model.configUrl);
|
|
44474
44752
|
if (!configResp.ok)
|
|
44475
44753
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
44476
44754
|
const configText = await configResp.text();
|
|
44477
|
-
|
|
44755
|
+
writeFileSync17(configPath, configText);
|
|
44478
44756
|
}
|
|
44479
|
-
if (!
|
|
44757
|
+
if (!existsSync40(onnxPath)) {
|
|
44480
44758
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
44481
44759
|
const onnxResp = await fetch(model.onnxUrl);
|
|
44482
44760
|
if (!onnxResp.ok)
|
|
@@ -44501,7 +44779,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44501
44779
|
}
|
|
44502
44780
|
}
|
|
44503
44781
|
const fullBuffer = Buffer.concat(chunks);
|
|
44504
|
-
|
|
44782
|
+
writeFileSync17(onnxPath, fullBuffer);
|
|
44505
44783
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
44506
44784
|
}
|
|
44507
44785
|
}
|
|
@@ -44513,10 +44791,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44513
44791
|
throw new Error("ONNX runtime not loaded");
|
|
44514
44792
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
44515
44793
|
const configPath = modelConfigPath(this.modelId);
|
|
44516
|
-
if (!
|
|
44794
|
+
if (!existsSync40(onnxPath) || !existsSync40(configPath)) {
|
|
44517
44795
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
44518
44796
|
}
|
|
44519
|
-
this.config = JSON.parse(
|
|
44797
|
+
this.config = JSON.parse(readFileSync29(configPath, "utf8"));
|
|
44520
44798
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
44521
44799
|
executionProviders: ["cpu"],
|
|
44522
44800
|
graphOptimizationLevel: "all"
|
|
@@ -44543,8 +44821,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
44543
44821
|
// packages/cli/dist/tui/commands.js
|
|
44544
44822
|
import * as nodeOs from "node:os";
|
|
44545
44823
|
import { execSync as nodeExecSync } from "node:child_process";
|
|
44546
|
-
import { existsSync as
|
|
44547
|
-
import { join as
|
|
44824
|
+
import { existsSync as existsSync41, readFileSync as readFileSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
|
|
44825
|
+
import { join as join57 } from "node:path";
|
|
44548
44826
|
function safeLog(text) {
|
|
44549
44827
|
if (isNeovimActive()) {
|
|
44550
44828
|
writeToNeovimOutput(text + "\n");
|
|
@@ -45153,22 +45431,22 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45153
45431
|
let content = "";
|
|
45154
45432
|
let metadata = {};
|
|
45155
45433
|
if (shareType === "tool") {
|
|
45156
|
-
const toolDir =
|
|
45157
|
-
const toolFile =
|
|
45158
|
-
if (!
|
|
45434
|
+
const toolDir = join57(ctx.repoRoot, ".oa", "tools");
|
|
45435
|
+
const toolFile = join57(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
|
|
45436
|
+
if (!existsSync41(toolFile)) {
|
|
45159
45437
|
renderWarning(`Tool not found: ${toolFile}`);
|
|
45160
45438
|
return "handled";
|
|
45161
45439
|
}
|
|
45162
|
-
content =
|
|
45440
|
+
content = readFileSync30(toolFile, "utf8");
|
|
45163
45441
|
metadata = { type: "tool", name: shareName };
|
|
45164
45442
|
} else if (shareType === "skill") {
|
|
45165
|
-
const skillDir =
|
|
45166
|
-
const skillFile =
|
|
45167
|
-
if (!
|
|
45443
|
+
const skillDir = join57(ctx.repoRoot, ".oa", "skills", shareName);
|
|
45444
|
+
const skillFile = join57(skillDir, "SKILL.md");
|
|
45445
|
+
if (!existsSync41(skillFile)) {
|
|
45168
45446
|
renderWarning(`Skill not found: ${skillFile}`);
|
|
45169
45447
|
return "handled";
|
|
45170
45448
|
}
|
|
45171
|
-
content =
|
|
45449
|
+
content = readFileSync30(skillFile, "utf8");
|
|
45172
45450
|
metadata = { type: "skill", name: shareName };
|
|
45173
45451
|
} else {
|
|
45174
45452
|
renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
|
|
@@ -45207,9 +45485,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45207
45485
|
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
45208
45486
|
const nexus = new NexusTool2(ctx.repoRoot);
|
|
45209
45487
|
await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
|
|
45210
|
-
const regFile =
|
|
45211
|
-
if (
|
|
45212
|
-
const reg = JSON.parse(
|
|
45488
|
+
const regFile = join57(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
|
|
45489
|
+
if (existsSync41(regFile)) {
|
|
45490
|
+
const reg = JSON.parse(readFileSync30(regFile, "utf8"));
|
|
45213
45491
|
const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
|
|
45214
45492
|
if (pinned) {
|
|
45215
45493
|
renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
|
|
@@ -45262,33 +45540,33 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45262
45540
|
lines.push(`
|
|
45263
45541
|
${c2.bold("IPFS / Helia Status")}
|
|
45264
45542
|
`);
|
|
45265
|
-
const ipfsDir =
|
|
45266
|
-
const ipfsLocalDir =
|
|
45543
|
+
const ipfsDir = join57(ctx.repoRoot, ".oa", "ipfs");
|
|
45544
|
+
const ipfsLocalDir = join57(ipfsDir, "local");
|
|
45267
45545
|
let ipfsFiles = 0;
|
|
45268
45546
|
let ipfsBytes = 0;
|
|
45269
45547
|
let heliaBlocks = 0;
|
|
45270
45548
|
let heliaBytes = 0;
|
|
45271
45549
|
try {
|
|
45272
|
-
if (
|
|
45273
|
-
const files =
|
|
45550
|
+
if (existsSync41(ipfsLocalDir)) {
|
|
45551
|
+
const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
|
|
45274
45552
|
ipfsFiles = files.length;
|
|
45275
45553
|
for (const f of files) {
|
|
45276
45554
|
try {
|
|
45277
|
-
ipfsBytes += statSync14(
|
|
45555
|
+
ipfsBytes += statSync14(join57(ipfsLocalDir, f)).size;
|
|
45278
45556
|
} catch {
|
|
45279
45557
|
}
|
|
45280
45558
|
}
|
|
45281
45559
|
}
|
|
45282
|
-
const heliaBlockDir =
|
|
45283
|
-
if (
|
|
45560
|
+
const heliaBlockDir = join57(ipfsDir, "blocks");
|
|
45561
|
+
if (existsSync41(heliaBlockDir)) {
|
|
45284
45562
|
const walkDir = (dir) => {
|
|
45285
|
-
for (const entry of
|
|
45563
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45286
45564
|
if (entry.isDirectory())
|
|
45287
|
-
walkDir(
|
|
45565
|
+
walkDir(join57(dir, entry.name));
|
|
45288
45566
|
else {
|
|
45289
45567
|
heliaBlocks++;
|
|
45290
45568
|
try {
|
|
45291
|
-
heliaBytes += statSync14(
|
|
45569
|
+
heliaBytes += statSync14(join57(dir, entry.name)).size;
|
|
45292
45570
|
} catch {
|
|
45293
45571
|
}
|
|
45294
45572
|
}
|
|
@@ -45304,9 +45582,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45304
45582
|
lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
|
|
45305
45583
|
lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
|
|
45306
45584
|
try {
|
|
45307
|
-
const statusFile =
|
|
45308
|
-
if (
|
|
45309
|
-
const status = JSON.parse(
|
|
45585
|
+
const statusFile = join57(ctx.repoRoot, ".oa", "nexus", "status.json");
|
|
45586
|
+
if (existsSync41(statusFile)) {
|
|
45587
|
+
const status = JSON.parse(readFileSync30(statusFile, "utf8"));
|
|
45310
45588
|
if (status.peerId) {
|
|
45311
45589
|
lines.push(`
|
|
45312
45590
|
${c2.bold("Peer Info")}`);
|
|
@@ -45325,11 +45603,11 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45325
45603
|
${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
45326
45604
|
lines.push(`
|
|
45327
45605
|
${c2.bold("Identity Kernel")}`);
|
|
45328
|
-
const idDir =
|
|
45606
|
+
const idDir = join57(ctx.repoRoot, ".oa", "identity");
|
|
45329
45607
|
try {
|
|
45330
|
-
const stateFile =
|
|
45331
|
-
if (
|
|
45332
|
-
const state = JSON.parse(
|
|
45608
|
+
const stateFile = join57(idDir, "self-state.json");
|
|
45609
|
+
if (existsSync41(stateFile)) {
|
|
45610
|
+
const state = JSON.parse(readFileSync30(stateFile, "utf8"));
|
|
45333
45611
|
lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
|
|
45334
45612
|
if (state.narrative_summary) {
|
|
45335
45613
|
lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
|
|
@@ -45338,9 +45616,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45338
45616
|
const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
|
|
45339
45617
|
lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
|
|
45340
45618
|
}
|
|
45341
|
-
const cidFile =
|
|
45342
|
-
if (
|
|
45343
|
-
const cids = JSON.parse(
|
|
45619
|
+
const cidFile = join57(idDir, "cids.json");
|
|
45620
|
+
if (existsSync41(cidFile)) {
|
|
45621
|
+
const cids = JSON.parse(readFileSync30(cidFile, "utf8"));
|
|
45344
45622
|
const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
|
|
45345
45623
|
if (lastCid)
|
|
45346
45624
|
lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
|
|
@@ -45353,9 +45631,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45353
45631
|
lines.push(`
|
|
45354
45632
|
${c2.bold("Memory Sentiment")}`);
|
|
45355
45633
|
try {
|
|
45356
|
-
const metaFile =
|
|
45357
|
-
if (
|
|
45358
|
-
const store = JSON.parse(
|
|
45634
|
+
const metaFile = join57(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
45635
|
+
if (existsSync41(metaFile)) {
|
|
45636
|
+
const store = JSON.parse(readFileSync30(metaFile, "utf8"));
|
|
45359
45637
|
const active = store.filter((m) => m.type !== "quarantine");
|
|
45360
45638
|
const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
|
|
45361
45639
|
const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
|
|
@@ -45373,8 +45651,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45373
45651
|
} catch {
|
|
45374
45652
|
}
|
|
45375
45653
|
try {
|
|
45376
|
-
const dbPath =
|
|
45377
|
-
if (
|
|
45654
|
+
const dbPath = join57(ctx.repoRoot, ".oa", "memory", "structured.db");
|
|
45655
|
+
if (existsSync41(dbPath)) {
|
|
45378
45656
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45379
45657
|
const db = initDb2(dbPath);
|
|
45380
45658
|
const memStore = new ProceduralMemoryStore2(db);
|
|
@@ -45395,8 +45673,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45395
45673
|
lines.push(`
|
|
45396
45674
|
${c2.bold("Storage Overview")}
|
|
45397
45675
|
`);
|
|
45398
|
-
const oaDir =
|
|
45399
|
-
if (!
|
|
45676
|
+
const oaDir = join57(ctx.repoRoot, ".oa");
|
|
45677
|
+
if (!existsSync41(oaDir)) {
|
|
45400
45678
|
lines.push(` ${c2.dim("No .oa/ directory found.")}`);
|
|
45401
45679
|
safeLog(lines.join("\n") + "\n");
|
|
45402
45680
|
return "handled";
|
|
@@ -45405,8 +45683,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45405
45683
|
const categories = {};
|
|
45406
45684
|
const walkStorage = (dir, category) => {
|
|
45407
45685
|
try {
|
|
45408
|
-
for (const entry of
|
|
45409
|
-
const full =
|
|
45686
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45687
|
+
const full = join57(dir, entry.name);
|
|
45410
45688
|
if (entry.isDirectory()) {
|
|
45411
45689
|
const subCat = category || entry.name;
|
|
45412
45690
|
walkStorage(full, subCat);
|
|
@@ -45439,13 +45717,13 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45439
45717
|
const sensitiveFound = [];
|
|
45440
45718
|
const checkSensitive = (dir) => {
|
|
45441
45719
|
try {
|
|
45442
|
-
for (const entry of
|
|
45720
|
+
for (const entry of readdirSync12(dir, { withFileTypes: true })) {
|
|
45443
45721
|
const name = entry.name.toLowerCase();
|
|
45444
45722
|
if (sensitivePatterns.some((p) => name.includes(p))) {
|
|
45445
|
-
sensitiveFound.push(
|
|
45723
|
+
sensitiveFound.push(join57(dir, entry.name).replace(oaDir + "/", ""));
|
|
45446
45724
|
}
|
|
45447
45725
|
if (entry.isDirectory())
|
|
45448
|
-
checkSensitive(
|
|
45726
|
+
checkSensitive(join57(dir, entry.name));
|
|
45449
45727
|
}
|
|
45450
45728
|
} catch {
|
|
45451
45729
|
}
|
|
@@ -45473,8 +45751,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45473
45751
|
renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
|
|
45474
45752
|
return "handled";
|
|
45475
45753
|
}
|
|
45476
|
-
const resolvedPath =
|
|
45477
|
-
if (!
|
|
45754
|
+
const resolvedPath = join57(ctx.repoRoot, filePath);
|
|
45755
|
+
if (!existsSync41(resolvedPath)) {
|
|
45478
45756
|
renderWarning(`File not found: ${resolvedPath}`);
|
|
45479
45757
|
return "handled";
|
|
45480
45758
|
}
|
|
@@ -45490,9 +45768,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45490
45768
|
}
|
|
45491
45769
|
try {
|
|
45492
45770
|
const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
45493
|
-
const dbDir =
|
|
45494
|
-
|
|
45495
|
-
const db = initDb2(
|
|
45771
|
+
const dbDir = join57(ctx.repoRoot, ".oa", "memory");
|
|
45772
|
+
mkdirSync17(dbDir, { recursive: true });
|
|
45773
|
+
const db = initDb2(join57(dbDir, "structured.db"));
|
|
45496
45774
|
const memStore = new ProceduralMemoryStore2(db);
|
|
45497
45775
|
if (isAudio) {
|
|
45498
45776
|
renderInfo(`Transcribing: ${filePath}...`);
|
|
@@ -45533,7 +45811,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45533
45811
|
return "handled";
|
|
45534
45812
|
}
|
|
45535
45813
|
} else {
|
|
45536
|
-
content =
|
|
45814
|
+
content = readFileSync30(resolvedPath, "utf8");
|
|
45537
45815
|
}
|
|
45538
45816
|
if (!content.trim()) {
|
|
45539
45817
|
renderWarning("No content extracted.");
|
|
@@ -45572,9 +45850,9 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45572
45850
|
}
|
|
45573
45851
|
case "fortemi": {
|
|
45574
45852
|
const fortemiSubCmd = (arg || "").trim().toLowerCase();
|
|
45575
|
-
const fortemiDir =
|
|
45576
|
-
const altFortemiDir =
|
|
45577
|
-
const fDir =
|
|
45853
|
+
const fortemiDir = join57(ctx.repoRoot, "..", "fortemi-react");
|
|
45854
|
+
const altFortemiDir = join57(nodeOs.homedir(), "fortemi-react");
|
|
45855
|
+
const fDir = existsSync41(fortemiDir) ? fortemiDir : existsSync41(altFortemiDir) ? altFortemiDir : null;
|
|
45578
45856
|
if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
|
|
45579
45857
|
if (!fDir) {
|
|
45580
45858
|
renderWarning("fortemi-react not found adjacent or in home directory.");
|
|
@@ -45589,14 +45867,14 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45589
45867
|
// 24h
|
|
45590
45868
|
nonce: Math.random().toString(36).slice(2, 10)
|
|
45591
45869
|
};
|
|
45592
|
-
const jwtFile =
|
|
45593
|
-
|
|
45594
|
-
|
|
45870
|
+
const jwtFile = join57(ctx.repoRoot, ".oa", "fortemi-jwt.json");
|
|
45871
|
+
mkdirSync17(join57(ctx.repoRoot, ".oa"), { recursive: true });
|
|
45872
|
+
writeFileSync18(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
45595
45873
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
45596
45874
|
try {
|
|
45597
45875
|
const { spawn: spawn21 } = __require("node:child_process");
|
|
45598
45876
|
const child = spawn21("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
45599
|
-
cwd:
|
|
45877
|
+
cwd: join57(fDir, "apps", "standalone"),
|
|
45600
45878
|
stdio: "ignore",
|
|
45601
45879
|
detached: true,
|
|
45602
45880
|
env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
|
|
@@ -45605,8 +45883,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45605
45883
|
renderInfo("Fortemi-React starting on http://localhost:3000");
|
|
45606
45884
|
renderInfo(`JWT saved to ${jwtFile}`);
|
|
45607
45885
|
renderInfo("Memory operations will proxy to fortemi when available.");
|
|
45608
|
-
const bridgeFile =
|
|
45609
|
-
|
|
45886
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45887
|
+
writeFileSync18(bridgeFile, JSON.stringify({
|
|
45610
45888
|
url: "http://localhost:3000",
|
|
45611
45889
|
pid: child.pid,
|
|
45612
45890
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -45618,12 +45896,12 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45618
45896
|
return "handled";
|
|
45619
45897
|
}
|
|
45620
45898
|
if (fortemiSubCmd === "status") {
|
|
45621
|
-
const bridgeFile =
|
|
45622
|
-
if (!
|
|
45899
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45900
|
+
if (!existsSync41(bridgeFile)) {
|
|
45623
45901
|
renderInfo("Fortemi bridge: not connected. Run /fortemi start");
|
|
45624
45902
|
return "handled";
|
|
45625
45903
|
}
|
|
45626
|
-
const bridge = JSON.parse(
|
|
45904
|
+
const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
|
|
45627
45905
|
let alive = false;
|
|
45628
45906
|
try {
|
|
45629
45907
|
process.kill(bridge.pid, 0);
|
|
@@ -45643,15 +45921,15 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45643
45921
|
lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
|
|
45644
45922
|
lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
|
|
45645
45923
|
lines.push(` Started: ${bridge.startedAt}`);
|
|
45646
|
-
lines.push(` JWT: ${
|
|
45924
|
+
lines.push(` JWT: ${existsSync41(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
|
|
45647
45925
|
lines.push("");
|
|
45648
45926
|
safeLog(lines.join("\n"));
|
|
45649
45927
|
return "handled";
|
|
45650
45928
|
}
|
|
45651
45929
|
if (fortemiSubCmd === "stop") {
|
|
45652
|
-
const bridgeFile =
|
|
45653
|
-
if (
|
|
45654
|
-
const bridge = JSON.parse(
|
|
45930
|
+
const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
|
|
45931
|
+
if (existsSync41(bridgeFile)) {
|
|
45932
|
+
const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
|
|
45655
45933
|
try {
|
|
45656
45934
|
process.kill(bridge.pid, "SIGTERM");
|
|
45657
45935
|
} catch {
|
|
@@ -47030,13 +47308,13 @@ async function showCohereDashboard(ctx) {
|
|
|
47030
47308
|
} else if (idResult.key === "view") {
|
|
47031
47309
|
await ik.execute({ operation: "hydrate" });
|
|
47032
47310
|
} else if (idResult.key === "history") {
|
|
47033
|
-
const snapDir =
|
|
47034
|
-
if (
|
|
47035
|
-
const snaps =
|
|
47311
|
+
const snapDir = join57(ctx.repoRoot, ".oa", "identity", "snapshots");
|
|
47312
|
+
if (existsSync41(snapDir)) {
|
|
47313
|
+
const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
47036
47314
|
const snapItems = snaps.slice(0, 20).map((f) => ({
|
|
47037
47315
|
key: f,
|
|
47038
47316
|
label: f.replace(".json", ""),
|
|
47039
|
-
detail: `${formatFileSize(statSync14(
|
|
47317
|
+
detail: `${formatFileSize(statSync14(join57(snapDir, f)).size)}`
|
|
47040
47318
|
}));
|
|
47041
47319
|
if (snapItems.length > 0) {
|
|
47042
47320
|
await tuiSelect({
|
|
@@ -47351,13 +47629,13 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
47351
47629
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
47352
47630
|
continue;
|
|
47353
47631
|
}
|
|
47354
|
-
const { basename:
|
|
47355
|
-
const { copyFileSync: copyFileSync2, mkdirSync:
|
|
47632
|
+
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
47633
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync25, existsSync: exists } = await import("node:fs");
|
|
47356
47634
|
const { homedir: homedir18 } = await import("node:os");
|
|
47357
|
-
const modelName =
|
|
47635
|
+
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
47358
47636
|
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
47359
47637
|
if (!exists(destDir))
|
|
47360
|
-
|
|
47638
|
+
mkdirSync25(destDir, { recursive: true });
|
|
47361
47639
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
47362
47640
|
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
47363
47641
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -47502,7 +47780,7 @@ async function handleVoiceList(ctx, focusFilename) {
|
|
|
47502
47780
|
const src = srcPath.trim();
|
|
47503
47781
|
try {
|
|
47504
47782
|
const { existsSync: fe, copyFileSync: cpf, mkdirSync: mkd } = __require("node:fs");
|
|
47505
|
-
const { basename:
|
|
47783
|
+
const { basename: basename18, join: pjoin } = __require("node:path");
|
|
47506
47784
|
if (!fe(src)) {
|
|
47507
47785
|
renderError(`File not found: ${src}`);
|
|
47508
47786
|
helpers.render();
|
|
@@ -47510,7 +47788,7 @@ async function handleVoiceList(ctx, focusFilename) {
|
|
|
47510
47788
|
}
|
|
47511
47789
|
const refsDir = pjoin(__require("node:os").homedir(), ".open-agents", "voice", "clone-refs");
|
|
47512
47790
|
mkd(refsDir, { recursive: true });
|
|
47513
|
-
const destName =
|
|
47791
|
+
const destName = basename18(src);
|
|
47514
47792
|
const dest = pjoin(refsDir, destName);
|
|
47515
47793
|
cpf(src, dest);
|
|
47516
47794
|
renderInfo(`Imported "${destName}" \u2192 ${dest}`);
|
|
@@ -47849,11 +48127,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47849
48127
|
const models = await fetchModels(peerUrl, authKey);
|
|
47850
48128
|
if (models.length > 0) {
|
|
47851
48129
|
try {
|
|
47852
|
-
const { writeFileSync:
|
|
47853
|
-
const { join:
|
|
47854
|
-
const cachePath =
|
|
47855
|
-
|
|
47856
|
-
|
|
48130
|
+
const { writeFileSync: writeFileSync24, mkdirSync: mkdirSync25 } = await import("node:fs");
|
|
48131
|
+
const { join: join71, dirname: dirname22 } = await import("node:path");
|
|
48132
|
+
const cachePath = join71(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
48133
|
+
mkdirSync25(dirname22(cachePath), { recursive: true });
|
|
48134
|
+
writeFileSync24(cachePath, JSON.stringify({
|
|
47857
48135
|
peerId,
|
|
47858
48136
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47859
48137
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -47902,7 +48180,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
47902
48180
|
}
|
|
47903
48181
|
}
|
|
47904
48182
|
async function handleParallel(arg, ctx) {
|
|
47905
|
-
const { execSync:
|
|
48183
|
+
const { execSync: execSync34 } = await import("node:child_process");
|
|
47906
48184
|
const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
|
|
47907
48185
|
const isRemote = ctx.config.backendType === "nexus";
|
|
47908
48186
|
if (isRemote) {
|
|
@@ -47926,7 +48204,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47926
48204
|
}
|
|
47927
48205
|
let systemdVal = "";
|
|
47928
48206
|
try {
|
|
47929
|
-
const out =
|
|
48207
|
+
const out = execSync34("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
|
|
47930
48208
|
const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
|
|
47931
48209
|
if (match)
|
|
47932
48210
|
systemdVal = match[1];
|
|
@@ -47955,7 +48233,7 @@ async function handleParallel(arg, ctx) {
|
|
|
47955
48233
|
}
|
|
47956
48234
|
const isSystemd = (() => {
|
|
47957
48235
|
try {
|
|
47958
|
-
const out =
|
|
48236
|
+
const out = execSync34("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
|
|
47959
48237
|
return out === "active" || out === "inactive";
|
|
47960
48238
|
} catch {
|
|
47961
48239
|
return false;
|
|
@@ -47969,10 +48247,10 @@ async function handleParallel(arg, ctx) {
|
|
|
47969
48247
|
const overrideContent = `[Service]
|
|
47970
48248
|
Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
47971
48249
|
`;
|
|
47972
|
-
|
|
47973
|
-
|
|
47974
|
-
|
|
47975
|
-
|
|
48250
|
+
execSync34(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
|
|
48251
|
+
execSync34(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
|
|
48252
|
+
execSync34("sudo systemctl daemon-reload", { stdio: "pipe" });
|
|
48253
|
+
execSync34("sudo systemctl restart ollama.service", { stdio: "pipe" });
|
|
47976
48254
|
let ready = false;
|
|
47977
48255
|
for (let i = 0; i < 30 && !ready; i++) {
|
|
47978
48256
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -47999,7 +48277,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
47999
48277
|
renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
|
|
48000
48278
|
try {
|
|
48001
48279
|
try {
|
|
48002
|
-
|
|
48280
|
+
execSync34("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
|
|
48003
48281
|
} catch {
|
|
48004
48282
|
}
|
|
48005
48283
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
@@ -48052,17 +48330,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48052
48330
|
try {
|
|
48053
48331
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
48054
48332
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
48055
|
-
const { dirname: dirname22, join:
|
|
48056
|
-
const { existsSync:
|
|
48333
|
+
const { dirname: dirname22, join: join71 } = await import("node:path");
|
|
48334
|
+
const { existsSync: existsSync51 } = await import("node:fs");
|
|
48057
48335
|
const req = createRequire4(import.meta.url);
|
|
48058
48336
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
48059
48337
|
const candidates = [
|
|
48060
|
-
|
|
48061
|
-
|
|
48062
|
-
|
|
48338
|
+
join71(thisDir, "..", "package.json"),
|
|
48339
|
+
join71(thisDir, "..", "..", "package.json"),
|
|
48340
|
+
join71(thisDir, "..", "..", "..", "package.json")
|
|
48063
48341
|
];
|
|
48064
48342
|
for (const pkgPath of candidates) {
|
|
48065
|
-
if (
|
|
48343
|
+
if (existsSync51(pkgPath)) {
|
|
48066
48344
|
const pkg = req(pkgPath);
|
|
48067
48345
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
48068
48346
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -48802,18 +49080,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
48802
49080
|
const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
|
|
48803
49081
|
let copied = false;
|
|
48804
49082
|
try {
|
|
48805
|
-
const { execSync:
|
|
49083
|
+
const { execSync: execSync34 } = __require("node:child_process");
|
|
48806
49084
|
const platform6 = process.platform;
|
|
48807
49085
|
if (platform6 === "darwin") {
|
|
48808
|
-
|
|
49086
|
+
execSync34("pbcopy", { input: cmd, timeout: 3e3 });
|
|
48809
49087
|
copied = true;
|
|
48810
49088
|
} else if (platform6 === "win32") {
|
|
48811
|
-
|
|
49089
|
+
execSync34("clip", { input: cmd, timeout: 3e3 });
|
|
48812
49090
|
copied = true;
|
|
48813
49091
|
} else {
|
|
48814
49092
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
48815
49093
|
try {
|
|
48816
|
-
|
|
49094
|
+
execSync34(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
|
|
48817
49095
|
copied = true;
|
|
48818
49096
|
break;
|
|
48819
49097
|
} catch {
|
|
@@ -48900,9 +49178,9 @@ var init_commands = __esm({
|
|
|
48900
49178
|
});
|
|
48901
49179
|
|
|
48902
49180
|
// packages/cli/dist/tui/project-context.js
|
|
48903
|
-
import { existsSync as
|
|
48904
|
-
import { join as
|
|
48905
|
-
import { execSync as
|
|
49181
|
+
import { existsSync as existsSync42, readFileSync as readFileSync31, readdirSync as readdirSync13 } from "node:fs";
|
|
49182
|
+
import { join as join58, basename as basename12 } from "node:path";
|
|
49183
|
+
import { execSync as execSync30 } from "node:child_process";
|
|
48906
49184
|
import { homedir as homedir15, platform as platform4, release } from "node:os";
|
|
48907
49185
|
function getModelTier(modelName) {
|
|
48908
49186
|
const m = modelName.toLowerCase();
|
|
@@ -48936,10 +49214,10 @@ function loadProjectMap(repoRoot) {
|
|
|
48936
49214
|
if (!hasOaDirectory(repoRoot)) {
|
|
48937
49215
|
initOaDirectory(repoRoot);
|
|
48938
49216
|
}
|
|
48939
|
-
const mapPath2 =
|
|
48940
|
-
if (
|
|
49217
|
+
const mapPath2 = join58(repoRoot, OA_DIR, "context", "project-map.md");
|
|
49218
|
+
if (existsSync42(mapPath2)) {
|
|
48941
49219
|
try {
|
|
48942
|
-
const content =
|
|
49220
|
+
const content = readFileSync31(mapPath2, "utf-8");
|
|
48943
49221
|
return content;
|
|
48944
49222
|
} catch {
|
|
48945
49223
|
}
|
|
@@ -48948,19 +49226,19 @@ function loadProjectMap(repoRoot) {
|
|
|
48948
49226
|
}
|
|
48949
49227
|
function getGitInfo(repoRoot) {
|
|
48950
49228
|
try {
|
|
48951
|
-
|
|
49229
|
+
execSync30("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
48952
49230
|
} catch {
|
|
48953
49231
|
return "";
|
|
48954
49232
|
}
|
|
48955
49233
|
const lines = [];
|
|
48956
49234
|
try {
|
|
48957
|
-
const branch =
|
|
49235
|
+
const branch = execSync30("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48958
49236
|
if (branch)
|
|
48959
49237
|
lines.push(`Branch: ${branch}`);
|
|
48960
49238
|
} catch {
|
|
48961
49239
|
}
|
|
48962
49240
|
try {
|
|
48963
|
-
const status =
|
|
49241
|
+
const status = execSync30("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48964
49242
|
if (status) {
|
|
48965
49243
|
const changed = status.split("\n").length;
|
|
48966
49244
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -48970,7 +49248,7 @@ function getGitInfo(repoRoot) {
|
|
|
48970
49248
|
} catch {
|
|
48971
49249
|
}
|
|
48972
49250
|
try {
|
|
48973
|
-
const log =
|
|
49251
|
+
const log = execSync30("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
48974
49252
|
if (log)
|
|
48975
49253
|
lines.push(`Recent commits:
|
|
48976
49254
|
${log}`);
|
|
@@ -48980,33 +49258,33 @@ ${log}`);
|
|
|
48980
49258
|
}
|
|
48981
49259
|
function loadMemoryContext(repoRoot) {
|
|
48982
49260
|
const sections = [];
|
|
48983
|
-
const oaMemDir =
|
|
49261
|
+
const oaMemDir = join58(repoRoot, OA_DIR, "memory");
|
|
48984
49262
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
48985
49263
|
if (oaEntries)
|
|
48986
49264
|
sections.push(oaEntries);
|
|
48987
|
-
const legacyMemDir =
|
|
48988
|
-
if (legacyMemDir !== oaMemDir &&
|
|
49265
|
+
const legacyMemDir = join58(repoRoot, ".open-agents", "memory");
|
|
49266
|
+
if (legacyMemDir !== oaMemDir && existsSync42(legacyMemDir)) {
|
|
48989
49267
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
48990
49268
|
if (legacyEntries)
|
|
48991
49269
|
sections.push(legacyEntries);
|
|
48992
49270
|
}
|
|
48993
|
-
const globalMemDir =
|
|
49271
|
+
const globalMemDir = join58(homedir15(), ".open-agents", "memory");
|
|
48994
49272
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
48995
49273
|
if (globalEntries)
|
|
48996
49274
|
sections.push(globalEntries);
|
|
48997
49275
|
return sections.join("\n\n");
|
|
48998
49276
|
}
|
|
48999
49277
|
function loadMemoryDir(memDir, scope) {
|
|
49000
|
-
if (!
|
|
49278
|
+
if (!existsSync42(memDir))
|
|
49001
49279
|
return "";
|
|
49002
49280
|
const lines = [];
|
|
49003
49281
|
try {
|
|
49004
|
-
const files =
|
|
49282
|
+
const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
|
|
49005
49283
|
for (const file of files.slice(0, 10)) {
|
|
49006
49284
|
try {
|
|
49007
|
-
const raw =
|
|
49285
|
+
const raw = readFileSync31(join58(memDir, file), "utf-8");
|
|
49008
49286
|
const entries = JSON.parse(raw);
|
|
49009
|
-
const topic =
|
|
49287
|
+
const topic = basename12(file, ".json");
|
|
49010
49288
|
const keys = Object.keys(entries);
|
|
49011
49289
|
if (keys.length === 0)
|
|
49012
49290
|
continue;
|
|
@@ -50523,22 +50801,22 @@ var init_banner = __esm({
|
|
|
50523
50801
|
});
|
|
50524
50802
|
|
|
50525
50803
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
50526
|
-
import { existsSync as
|
|
50527
|
-
import { join as
|
|
50804
|
+
import { existsSync as existsSync43, readFileSync as readFileSync32, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync14 } from "node:fs";
|
|
50805
|
+
import { join as join59, basename as basename13 } from "node:path";
|
|
50528
50806
|
function loadToolProfile(repoRoot) {
|
|
50529
|
-
const filePath =
|
|
50807
|
+
const filePath = join59(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
50530
50808
|
try {
|
|
50531
|
-
if (!
|
|
50809
|
+
if (!existsSync43(filePath))
|
|
50532
50810
|
return null;
|
|
50533
|
-
return JSON.parse(
|
|
50811
|
+
return JSON.parse(readFileSync32(filePath, "utf-8"));
|
|
50534
50812
|
} catch {
|
|
50535
50813
|
return null;
|
|
50536
50814
|
}
|
|
50537
50815
|
}
|
|
50538
50816
|
function saveToolProfile(repoRoot, profile) {
|
|
50539
|
-
const contextDir =
|
|
50540
|
-
|
|
50541
|
-
|
|
50817
|
+
const contextDir = join59(repoRoot, OA_DIR, "context");
|
|
50818
|
+
mkdirSync18(contextDir, { recursive: true });
|
|
50819
|
+
writeFileSync19(join59(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
50542
50820
|
}
|
|
50543
50821
|
function categorizeToolCall(toolName) {
|
|
50544
50822
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -50596,25 +50874,25 @@ function weightedColor(profile) {
|
|
|
50596
50874
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
50597
50875
|
}
|
|
50598
50876
|
function loadCachedDescriptors(repoRoot) {
|
|
50599
|
-
const filePath =
|
|
50877
|
+
const filePath = join59(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
50600
50878
|
try {
|
|
50601
|
-
if (!
|
|
50879
|
+
if (!existsSync43(filePath))
|
|
50602
50880
|
return null;
|
|
50603
|
-
const cached = JSON.parse(
|
|
50881
|
+
const cached = JSON.parse(readFileSync32(filePath, "utf-8"));
|
|
50604
50882
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
50605
50883
|
} catch {
|
|
50606
50884
|
return null;
|
|
50607
50885
|
}
|
|
50608
50886
|
}
|
|
50609
50887
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
50610
|
-
const contextDir =
|
|
50611
|
-
|
|
50888
|
+
const contextDir = join59(repoRoot, OA_DIR, "context");
|
|
50889
|
+
mkdirSync18(contextDir, { recursive: true });
|
|
50612
50890
|
const cached = {
|
|
50613
50891
|
phrases,
|
|
50614
50892
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50615
50893
|
sourceHash
|
|
50616
50894
|
};
|
|
50617
|
-
|
|
50895
|
+
writeFileSync19(join59(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
50618
50896
|
}
|
|
50619
50897
|
function generateDescriptors(repoRoot) {
|
|
50620
50898
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -50625,7 +50903,7 @@ function generateDescriptors(repoRoot) {
|
|
|
50625
50903
|
extractFromSessions(repoRoot, tags);
|
|
50626
50904
|
extractFromMemory(repoRoot, tags);
|
|
50627
50905
|
extractFromToolProfile(profile, tags);
|
|
50628
|
-
const repoName2 =
|
|
50906
|
+
const repoName2 = basename13(repoRoot);
|
|
50629
50907
|
if (repoName2 && !tags.includes(repoName2)) {
|
|
50630
50908
|
tags.push(repoName2);
|
|
50631
50909
|
}
|
|
@@ -50662,11 +50940,11 @@ function generateDescriptors(repoRoot) {
|
|
|
50662
50940
|
return phrases;
|
|
50663
50941
|
}
|
|
50664
50942
|
function extractFromPackageJson(repoRoot, tags) {
|
|
50665
|
-
const pkgPath =
|
|
50943
|
+
const pkgPath = join59(repoRoot, "package.json");
|
|
50666
50944
|
try {
|
|
50667
|
-
if (!
|
|
50945
|
+
if (!existsSync43(pkgPath))
|
|
50668
50946
|
return;
|
|
50669
|
-
const pkg = JSON.parse(
|
|
50947
|
+
const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
|
|
50670
50948
|
if (pkg.name && typeof pkg.name === "string") {
|
|
50671
50949
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
50672
50950
|
for (const p of parts)
|
|
@@ -50710,7 +50988,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
50710
50988
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
50711
50989
|
];
|
|
50712
50990
|
for (const check of manifestChecks) {
|
|
50713
|
-
if (
|
|
50991
|
+
if (existsSync43(join59(repoRoot, check.file))) {
|
|
50714
50992
|
tags.push(check.tag);
|
|
50715
50993
|
}
|
|
50716
50994
|
}
|
|
@@ -50732,16 +51010,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
50732
51010
|
}
|
|
50733
51011
|
}
|
|
50734
51012
|
function extractFromMemory(repoRoot, tags) {
|
|
50735
|
-
const memoryDir =
|
|
51013
|
+
const memoryDir = join59(repoRoot, OA_DIR, "memory");
|
|
50736
51014
|
try {
|
|
50737
|
-
if (!
|
|
51015
|
+
if (!existsSync43(memoryDir))
|
|
50738
51016
|
return;
|
|
50739
|
-
const files =
|
|
51017
|
+
const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
|
|
50740
51018
|
for (const file of files) {
|
|
50741
51019
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
50742
51020
|
tags.push(topic);
|
|
50743
51021
|
try {
|
|
50744
|
-
const data = JSON.parse(
|
|
51022
|
+
const data = JSON.parse(readFileSync32(join59(memoryDir, file), "utf-8"));
|
|
50745
51023
|
if (data && typeof data === "object") {
|
|
50746
51024
|
const keys = Object.keys(data).slice(0, 3);
|
|
50747
51025
|
for (const key of keys) {
|
|
@@ -51182,7 +51460,7 @@ var init_stream_renderer = __esm({
|
|
|
51182
51460
|
if (this.lineBuffer.length > 0) {
|
|
51183
51461
|
this.flushPartial(kind);
|
|
51184
51462
|
}
|
|
51185
|
-
},
|
|
51463
|
+
}, 150);
|
|
51186
51464
|
}
|
|
51187
51465
|
cancelFlush() {
|
|
51188
51466
|
if (this.flushTimer) {
|
|
@@ -51374,13 +51652,13 @@ var init_stream_renderer = __esm({
|
|
|
51374
51652
|
});
|
|
51375
51653
|
|
|
51376
51654
|
// packages/cli/dist/tui/edit-history.js
|
|
51377
|
-
import { appendFileSync as appendFileSync3, mkdirSync as
|
|
51378
|
-
import { join as
|
|
51655
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync19 } from "node:fs";
|
|
51656
|
+
import { join as join60 } from "node:path";
|
|
51379
51657
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
51380
|
-
const historyDir =
|
|
51381
|
-
const logPath2 =
|
|
51658
|
+
const historyDir = join60(repoRoot, ".oa", "history");
|
|
51659
|
+
const logPath2 = join60(historyDir, "edits.jsonl");
|
|
51382
51660
|
try {
|
|
51383
|
-
|
|
51661
|
+
mkdirSync19(historyDir, { recursive: true });
|
|
51384
51662
|
} catch {
|
|
51385
51663
|
}
|
|
51386
51664
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -51489,17 +51767,17 @@ var init_edit_history = __esm({
|
|
|
51489
51767
|
});
|
|
51490
51768
|
|
|
51491
51769
|
// packages/cli/dist/tui/promptLoader.js
|
|
51492
|
-
import { readFileSync as
|
|
51493
|
-
import { join as
|
|
51770
|
+
import { readFileSync as readFileSync33, existsSync as existsSync44 } from "node:fs";
|
|
51771
|
+
import { join as join61, dirname as dirname19 } from "node:path";
|
|
51494
51772
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
51495
51773
|
function loadPrompt3(promptPath, vars) {
|
|
51496
51774
|
let content = cache3.get(promptPath);
|
|
51497
51775
|
if (content === void 0) {
|
|
51498
|
-
const fullPath =
|
|
51499
|
-
if (!
|
|
51776
|
+
const fullPath = join61(PROMPTS_DIR3, promptPath);
|
|
51777
|
+
if (!existsSync44(fullPath)) {
|
|
51500
51778
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
51501
51779
|
}
|
|
51502
|
-
content =
|
|
51780
|
+
content = readFileSync33(fullPath, "utf-8");
|
|
51503
51781
|
cache3.set(promptPath, content);
|
|
51504
51782
|
}
|
|
51505
51783
|
if (!vars)
|
|
@@ -51512,23 +51790,23 @@ var init_promptLoader3 = __esm({
|
|
|
51512
51790
|
"use strict";
|
|
51513
51791
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
51514
51792
|
__dirname6 = dirname19(__filename3);
|
|
51515
|
-
devPath2 =
|
|
51516
|
-
publishedPath2 =
|
|
51517
|
-
PROMPTS_DIR3 =
|
|
51793
|
+
devPath2 = join61(__dirname6, "..", "..", "prompts");
|
|
51794
|
+
publishedPath2 = join61(__dirname6, "..", "prompts");
|
|
51795
|
+
PROMPTS_DIR3 = existsSync44(devPath2) ? devPath2 : publishedPath2;
|
|
51518
51796
|
cache3 = /* @__PURE__ */ new Map();
|
|
51519
51797
|
}
|
|
51520
51798
|
});
|
|
51521
51799
|
|
|
51522
51800
|
// packages/cli/dist/tui/dream-engine.js
|
|
51523
|
-
import { mkdirSync as
|
|
51524
|
-
import { join as
|
|
51525
|
-
import { execSync as
|
|
51801
|
+
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync20, readFileSync as readFileSync34, existsSync as existsSync45, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
|
|
51802
|
+
import { join as join62, basename as basename14 } from "node:path";
|
|
51803
|
+
import { execSync as execSync31 } from "node:child_process";
|
|
51526
51804
|
function loadAutoresearchMemory(repoRoot) {
|
|
51527
|
-
const memoryPath =
|
|
51528
|
-
if (!
|
|
51805
|
+
const memoryPath = join62(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
51806
|
+
if (!existsSync45(memoryPath))
|
|
51529
51807
|
return "";
|
|
51530
51808
|
try {
|
|
51531
|
-
const raw =
|
|
51809
|
+
const raw = readFileSync34(memoryPath, "utf-8");
|
|
51532
51810
|
const data = JSON.parse(raw);
|
|
51533
51811
|
const sections = [];
|
|
51534
51812
|
for (const key of AUTORESEARCH_MEMORY_KEYS) {
|
|
@@ -51718,14 +51996,14 @@ var init_dream_engine = __esm({
|
|
|
51718
51996
|
const content = String(args["content"] ?? "");
|
|
51719
51997
|
if (!rawPath)
|
|
51720
51998
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
51721
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
51999
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
|
|
51722
52000
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
51723
52001
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
51724
52002
|
}
|
|
51725
52003
|
try {
|
|
51726
|
-
const dir =
|
|
51727
|
-
|
|
51728
|
-
|
|
52004
|
+
const dir = join62(targetPath, "..");
|
|
52005
|
+
mkdirSync20(dir, { recursive: true });
|
|
52006
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51729
52007
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
51730
52008
|
} catch (err) {
|
|
51731
52009
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51753,20 +52031,20 @@ var init_dream_engine = __esm({
|
|
|
51753
52031
|
const rawPath = String(args["path"] ?? "");
|
|
51754
52032
|
const oldStr = String(args["old_string"] ?? "");
|
|
51755
52033
|
const newStr = String(args["new_string"] ?? "");
|
|
51756
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
52034
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
|
|
51757
52035
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
51758
52036
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
51759
52037
|
}
|
|
51760
52038
|
try {
|
|
51761
|
-
if (!
|
|
52039
|
+
if (!existsSync45(targetPath)) {
|
|
51762
52040
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
51763
52041
|
}
|
|
51764
|
-
let content =
|
|
52042
|
+
let content = readFileSync34(targetPath, "utf-8");
|
|
51765
52043
|
if (!content.includes(oldStr)) {
|
|
51766
52044
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
51767
52045
|
}
|
|
51768
52046
|
content = content.replace(oldStr, newStr);
|
|
51769
|
-
|
|
52047
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51770
52048
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
51771
52049
|
} catch (err) {
|
|
51772
52050
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51807,14 +52085,14 @@ var init_dream_engine = __esm({
|
|
|
51807
52085
|
const content = String(args["content"] ?? "");
|
|
51808
52086
|
if (!rawPath)
|
|
51809
52087
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
51810
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52088
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
|
|
51811
52089
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
51812
52090
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
51813
52091
|
}
|
|
51814
52092
|
try {
|
|
51815
|
-
const dir =
|
|
51816
|
-
|
|
51817
|
-
|
|
52093
|
+
const dir = join62(targetPath, "..");
|
|
52094
|
+
mkdirSync20(dir, { recursive: true });
|
|
52095
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51818
52096
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
51819
52097
|
} catch (err) {
|
|
51820
52098
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51842,20 +52120,20 @@ var init_dream_engine = __esm({
|
|
|
51842
52120
|
const rawPath = String(args["path"] ?? "");
|
|
51843
52121
|
const oldStr = String(args["old_string"] ?? "");
|
|
51844
52122
|
const newStr = String(args["new_string"] ?? "");
|
|
51845
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
52123
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
|
|
51846
52124
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
51847
52125
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
51848
52126
|
}
|
|
51849
52127
|
try {
|
|
51850
|
-
if (!
|
|
52128
|
+
if (!existsSync45(targetPath)) {
|
|
51851
52129
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
51852
52130
|
}
|
|
51853
|
-
let content =
|
|
52131
|
+
let content = readFileSync34(targetPath, "utf-8");
|
|
51854
52132
|
if (!content.includes(oldStr)) {
|
|
51855
52133
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
51856
52134
|
}
|
|
51857
52135
|
content = content.replace(oldStr, newStr);
|
|
51858
|
-
|
|
52136
|
+
writeFileSync20(targetPath, content, "utf-8");
|
|
51859
52137
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
51860
52138
|
} catch (err) {
|
|
51861
52139
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -51886,7 +52164,7 @@ var init_dream_engine = __esm({
|
|
|
51886
52164
|
}
|
|
51887
52165
|
}
|
|
51888
52166
|
try {
|
|
51889
|
-
const output =
|
|
52167
|
+
const output = execSync31(cmd, {
|
|
51890
52168
|
cwd: this.repoRoot,
|
|
51891
52169
|
timeout: 3e4,
|
|
51892
52170
|
encoding: "utf-8",
|
|
@@ -51909,7 +52187,7 @@ var init_dream_engine = __esm({
|
|
|
51909
52187
|
constructor(config, repoRoot) {
|
|
51910
52188
|
this.config = config;
|
|
51911
52189
|
this.repoRoot = repoRoot;
|
|
51912
|
-
this.dreamsDir =
|
|
52190
|
+
this.dreamsDir = join62(repoRoot, ".oa", "dreams");
|
|
51913
52191
|
this.state = {
|
|
51914
52192
|
mode: "default",
|
|
51915
52193
|
active: false,
|
|
@@ -51940,7 +52218,7 @@ var init_dream_engine = __esm({
|
|
|
51940
52218
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51941
52219
|
results: []
|
|
51942
52220
|
};
|
|
51943
|
-
|
|
52221
|
+
mkdirSync20(this.dreamsDir, { recursive: true });
|
|
51944
52222
|
this.saveDreamState();
|
|
51945
52223
|
try {
|
|
51946
52224
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -51993,8 +52271,8 @@ ${result.summary}`;
|
|
|
51993
52271
|
if (mode !== "default" || cycle === totalCycles) {
|
|
51994
52272
|
renderDreamContraction(cycle);
|
|
51995
52273
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
51996
|
-
const summaryPath =
|
|
51997
|
-
|
|
52274
|
+
const summaryPath = join62(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
52275
|
+
writeFileSync20(summaryPath, cycleSummary, "utf-8");
|
|
51998
52276
|
}
|
|
51999
52277
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
52000
52278
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -52206,7 +52484,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
52206
52484
|
}
|
|
52207
52485
|
/** Build role-specific tool sets for swarm agents */
|
|
52208
52486
|
buildSwarmTools(role, _workspace) {
|
|
52209
|
-
const autoresearchDir =
|
|
52487
|
+
const autoresearchDir = join62(this.repoRoot, ".oa", "autoresearch");
|
|
52210
52488
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
52211
52489
|
switch (role) {
|
|
52212
52490
|
case "researcher": {
|
|
@@ -52570,7 +52848,7 @@ INSTRUCTIONS:
|
|
|
52570
52848
|
2. Summarize the key learnings and next steps
|
|
52571
52849
|
|
|
52572
52850
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
52573
|
-
const reportPath =
|
|
52851
|
+
const reportPath = join62(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
52574
52852
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
52575
52853
|
|
|
52576
52854
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -52592,8 +52870,8 @@ ${summaryResult}
|
|
|
52592
52870
|
*Generated by open-agents autoresearch swarm*
|
|
52593
52871
|
`;
|
|
52594
52872
|
try {
|
|
52595
|
-
|
|
52596
|
-
|
|
52873
|
+
mkdirSync20(this.dreamsDir, { recursive: true });
|
|
52874
|
+
writeFileSync20(reportPath, report, "utf-8");
|
|
52597
52875
|
} catch {
|
|
52598
52876
|
}
|
|
52599
52877
|
renderSwarmComplete(workspace);
|
|
@@ -52659,29 +52937,29 @@ ${summaryResult}
|
|
|
52659
52937
|
}
|
|
52660
52938
|
/** Save workspace backup for lucid mode */
|
|
52661
52939
|
saveVersionCheckpoint(cycle) {
|
|
52662
|
-
const checkpointDir =
|
|
52940
|
+
const checkpointDir = join62(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
52663
52941
|
try {
|
|
52664
|
-
|
|
52942
|
+
mkdirSync20(checkpointDir, { recursive: true });
|
|
52665
52943
|
try {
|
|
52666
|
-
const gitStatus =
|
|
52944
|
+
const gitStatus = execSync31("git status --porcelain", {
|
|
52667
52945
|
cwd: this.repoRoot,
|
|
52668
52946
|
encoding: "utf-8",
|
|
52669
52947
|
timeout: 1e4
|
|
52670
52948
|
});
|
|
52671
|
-
const gitDiff =
|
|
52949
|
+
const gitDiff = execSync31("git diff", {
|
|
52672
52950
|
cwd: this.repoRoot,
|
|
52673
52951
|
encoding: "utf-8",
|
|
52674
52952
|
timeout: 1e4
|
|
52675
52953
|
});
|
|
52676
|
-
const gitHash =
|
|
52954
|
+
const gitHash = execSync31("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
52677
52955
|
cwd: this.repoRoot,
|
|
52678
52956
|
encoding: "utf-8",
|
|
52679
52957
|
timeout: 5e3
|
|
52680
52958
|
}).trim();
|
|
52681
|
-
|
|
52682
|
-
|
|
52683
|
-
|
|
52684
|
-
|
|
52959
|
+
writeFileSync20(join62(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
52960
|
+
writeFileSync20(join62(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
52961
|
+
writeFileSync20(join62(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
52962
|
+
writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
52685
52963
|
cycle,
|
|
52686
52964
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52687
52965
|
gitHash,
|
|
@@ -52689,7 +52967,7 @@ ${summaryResult}
|
|
|
52689
52967
|
}, null, 2), "utf-8");
|
|
52690
52968
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
52691
52969
|
} catch {
|
|
52692
|
-
|
|
52970
|
+
writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
52693
52971
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
52694
52972
|
}
|
|
52695
52973
|
} catch (err) {
|
|
@@ -52726,7 +53004,7 @@ Each proposal includes implementation entrypoints and estimated effort.
|
|
|
52726
53004
|
/** Update the master proposal index */
|
|
52727
53005
|
updateProposalIndex() {
|
|
52728
53006
|
try {
|
|
52729
|
-
const files =
|
|
53007
|
+
const files = readdirSync15(this.dreamsDir).filter((f) => f.endsWith(".md") && f !== "PROPOSAL-INDEX.md" && f !== "dream-state.json").sort();
|
|
52730
53008
|
const index = `# Dream Proposals Index
|
|
52731
53009
|
|
|
52732
53010
|
**Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -52747,14 +53025,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
52747
53025
|
---
|
|
52748
53026
|
*Auto-generated by open-agents dream engine*
|
|
52749
53027
|
`;
|
|
52750
|
-
|
|
53028
|
+
writeFileSync20(join62(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
52751
53029
|
} catch {
|
|
52752
53030
|
}
|
|
52753
53031
|
}
|
|
52754
53032
|
/** Save dream state for resume/inspection */
|
|
52755
53033
|
saveDreamState() {
|
|
52756
53034
|
try {
|
|
52757
|
-
|
|
53035
|
+
writeFileSync20(join62(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
52758
53036
|
} catch {
|
|
52759
53037
|
}
|
|
52760
53038
|
}
|
|
@@ -53128,8 +53406,8 @@ var init_bless_engine = __esm({
|
|
|
53128
53406
|
});
|
|
53129
53407
|
|
|
53130
53408
|
// packages/cli/dist/tui/dmn-engine.js
|
|
53131
|
-
import { existsSync as
|
|
53132
|
-
import { join as
|
|
53409
|
+
import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync21, mkdirSync as mkdirSync21, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
|
|
53410
|
+
import { join as join63, basename as basename15 } from "node:path";
|
|
53133
53411
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
53134
53412
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
53135
53413
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -53249,9 +53527,9 @@ var init_dmn_engine = __esm({
|
|
|
53249
53527
|
constructor(config, repoRoot) {
|
|
53250
53528
|
this.config = config;
|
|
53251
53529
|
this.repoRoot = repoRoot;
|
|
53252
|
-
this.stateDir =
|
|
53253
|
-
this.historyDir =
|
|
53254
|
-
|
|
53530
|
+
this.stateDir = join63(repoRoot, ".oa", "dmn");
|
|
53531
|
+
this.historyDir = join63(repoRoot, ".oa", "dmn", "cycles");
|
|
53532
|
+
mkdirSync21(this.historyDir, { recursive: true });
|
|
53255
53533
|
this.loadState();
|
|
53256
53534
|
}
|
|
53257
53535
|
get stats() {
|
|
@@ -53840,16 +54118,16 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53840
54118
|
async gatherMemoryTopics() {
|
|
53841
54119
|
const topics = [];
|
|
53842
54120
|
const dirs = [
|
|
53843
|
-
|
|
53844
|
-
|
|
54121
|
+
join63(this.repoRoot, ".oa", "memory"),
|
|
54122
|
+
join63(this.repoRoot, ".open-agents", "memory")
|
|
53845
54123
|
];
|
|
53846
54124
|
for (const dir of dirs) {
|
|
53847
|
-
if (!
|
|
54125
|
+
if (!existsSync46(dir))
|
|
53848
54126
|
continue;
|
|
53849
54127
|
try {
|
|
53850
|
-
const files =
|
|
54128
|
+
const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
|
|
53851
54129
|
for (const f of files) {
|
|
53852
|
-
const topic =
|
|
54130
|
+
const topic = basename15(f, ".json");
|
|
53853
54131
|
if (!topics.includes(topic))
|
|
53854
54132
|
topics.push(topic);
|
|
53855
54133
|
}
|
|
@@ -53860,29 +54138,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53860
54138
|
}
|
|
53861
54139
|
// ── State persistence ─────────────────────────────────────────────────
|
|
53862
54140
|
loadState() {
|
|
53863
|
-
const path =
|
|
53864
|
-
if (
|
|
54141
|
+
const path = join63(this.stateDir, "state.json");
|
|
54142
|
+
if (existsSync46(path)) {
|
|
53865
54143
|
try {
|
|
53866
|
-
this.state = JSON.parse(
|
|
54144
|
+
this.state = JSON.parse(readFileSync35(path, "utf-8"));
|
|
53867
54145
|
} catch {
|
|
53868
54146
|
}
|
|
53869
54147
|
}
|
|
53870
54148
|
}
|
|
53871
54149
|
saveState() {
|
|
53872
54150
|
try {
|
|
53873
|
-
|
|
54151
|
+
writeFileSync21(join63(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
53874
54152
|
} catch {
|
|
53875
54153
|
}
|
|
53876
54154
|
}
|
|
53877
54155
|
saveCycleResult(result) {
|
|
53878
54156
|
try {
|
|
53879
54157
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
53880
|
-
|
|
53881
|
-
const files =
|
|
54158
|
+
writeFileSync21(join63(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
54159
|
+
const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
53882
54160
|
if (files.length > 50) {
|
|
53883
54161
|
for (const old of files.slice(0, files.length - 50)) {
|
|
53884
54162
|
try {
|
|
53885
|
-
|
|
54163
|
+
unlinkSync10(join63(this.historyDir, old));
|
|
53886
54164
|
} catch {
|
|
53887
54165
|
}
|
|
53888
54166
|
}
|
|
@@ -53895,8 +54173,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
53895
54173
|
});
|
|
53896
54174
|
|
|
53897
54175
|
// packages/cli/dist/tui/snr-engine.js
|
|
53898
|
-
import { existsSync as
|
|
53899
|
-
import { join as
|
|
54176
|
+
import { existsSync as existsSync47, readdirSync as readdirSync17, readFileSync as readFileSync36 } from "node:fs";
|
|
54177
|
+
import { join as join64, basename as basename16 } from "node:path";
|
|
53900
54178
|
function computeDPrime(signalScores, noiseScores) {
|
|
53901
54179
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
53902
54180
|
return 0;
|
|
@@ -54136,20 +54414,20 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
54136
54414
|
loadMemoryEntries(topics) {
|
|
54137
54415
|
const entries = [];
|
|
54138
54416
|
const dirs = [
|
|
54139
|
-
|
|
54140
|
-
|
|
54417
|
+
join64(this.repoRoot, ".oa", "memory"),
|
|
54418
|
+
join64(this.repoRoot, ".open-agents", "memory")
|
|
54141
54419
|
];
|
|
54142
54420
|
for (const dir of dirs) {
|
|
54143
|
-
if (!
|
|
54421
|
+
if (!existsSync47(dir))
|
|
54144
54422
|
continue;
|
|
54145
54423
|
try {
|
|
54146
|
-
const files =
|
|
54424
|
+
const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
|
|
54147
54425
|
for (const f of files) {
|
|
54148
|
-
const topic =
|
|
54426
|
+
const topic = basename16(f, ".json");
|
|
54149
54427
|
if (topics.length > 0 && !topics.includes(topic))
|
|
54150
54428
|
continue;
|
|
54151
54429
|
try {
|
|
54152
|
-
const data = JSON.parse(
|
|
54430
|
+
const data = JSON.parse(readFileSync36(join64(dir, f), "utf-8"));
|
|
54153
54431
|
for (const [key, val] of Object.entries(data)) {
|
|
54154
54432
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
54155
54433
|
entries.push({ topic, key, value });
|
|
@@ -54716,8 +54994,8 @@ var init_tool_policy = __esm({
|
|
|
54716
54994
|
});
|
|
54717
54995
|
|
|
54718
54996
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
54719
|
-
import { mkdirSync as
|
|
54720
|
-
import { join as
|
|
54997
|
+
import { mkdirSync as mkdirSync22, existsSync as existsSync48, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
|
|
54998
|
+
import { join as join65, resolve as resolve30 } from "node:path";
|
|
54721
54999
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
54722
55000
|
function convertMarkdownToTelegramHTML(md) {
|
|
54723
55001
|
let html = md;
|
|
@@ -55045,7 +55323,7 @@ with summary "no_reply" to silently skip without responding.
|
|
|
55045
55323
|
this.polling = true;
|
|
55046
55324
|
this.abortController = new AbortController();
|
|
55047
55325
|
try {
|
|
55048
|
-
|
|
55326
|
+
mkdirSync22(this.mediaCacheDir, { recursive: true });
|
|
55049
55327
|
} catch {
|
|
55050
55328
|
}
|
|
55051
55329
|
this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
|
|
@@ -55482,7 +55760,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
55482
55760
|
return null;
|
|
55483
55761
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
55484
55762
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
55485
|
-
const localPath =
|
|
55763
|
+
const localPath = join65(this.mediaCacheDir, fileName);
|
|
55486
55764
|
await writeFileAsync(localPath, buffer);
|
|
55487
55765
|
return localPath;
|
|
55488
55766
|
} catch {
|
|
@@ -55570,7 +55848,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
55570
55848
|
for (const [key, entry] of this.mediaCache) {
|
|
55571
55849
|
if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
|
|
55572
55850
|
try {
|
|
55573
|
-
|
|
55851
|
+
unlinkSync11(entry.localPath);
|
|
55574
55852
|
} catch {
|
|
55575
55853
|
}
|
|
55576
55854
|
this.mediaCache.delete(key);
|
|
@@ -56498,7 +56776,7 @@ __export(text_selection_exports, {
|
|
|
56498
56776
|
stripAnsi: () => stripAnsi3,
|
|
56499
56777
|
visibleLength: () => visibleLength
|
|
56500
56778
|
});
|
|
56501
|
-
import { execSync as
|
|
56779
|
+
import { execSync as execSync32 } from "node:child_process";
|
|
56502
56780
|
function stripAnsi3(s) {
|
|
56503
56781
|
return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
|
|
56504
56782
|
}
|
|
@@ -56509,16 +56787,16 @@ function copyText(text) {
|
|
|
56509
56787
|
try {
|
|
56510
56788
|
const platform6 = process.platform;
|
|
56511
56789
|
if (platform6 === "darwin") {
|
|
56512
|
-
|
|
56790
|
+
execSync32("pbcopy", { input: text, timeout: 3e3 });
|
|
56513
56791
|
return true;
|
|
56514
56792
|
}
|
|
56515
56793
|
if (platform6 === "win32") {
|
|
56516
|
-
|
|
56794
|
+
execSync32("clip", { input: text, timeout: 3e3 });
|
|
56517
56795
|
return true;
|
|
56518
56796
|
}
|
|
56519
56797
|
for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
|
|
56520
56798
|
try {
|
|
56521
|
-
|
|
56799
|
+
execSync32(tool, { input: text, timeout: 3e3 });
|
|
56522
56800
|
return true;
|
|
56523
56801
|
} catch {
|
|
56524
56802
|
continue;
|
|
@@ -56527,10 +56805,10 @@ function copyText(text) {
|
|
|
56527
56805
|
if (!_clipboardAutoInstallAttempted) {
|
|
56528
56806
|
_clipboardAutoInstallAttempted = true;
|
|
56529
56807
|
try {
|
|
56530
|
-
|
|
56808
|
+
execSync32("which apt-get", { timeout: 2e3, stdio: "pipe" });
|
|
56531
56809
|
try {
|
|
56532
|
-
|
|
56533
|
-
|
|
56810
|
+
execSync32("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
|
|
56811
|
+
execSync32("xclip -selection clipboard", { input: text, timeout: 3e3 });
|
|
56534
56812
|
return true;
|
|
56535
56813
|
} catch {
|
|
56536
56814
|
}
|
|
@@ -56838,7 +57116,7 @@ var init_text_selection = __esm({
|
|
|
56838
57116
|
});
|
|
56839
57117
|
|
|
56840
57118
|
// packages/cli/dist/tui/status-bar.js
|
|
56841
|
-
import { readFileSync as
|
|
57119
|
+
import { readFileSync as readFileSync37 } from "node:fs";
|
|
56842
57120
|
function setTerminalTitle(task, version) {
|
|
56843
57121
|
if (!process.stdout.isTTY)
|
|
56844
57122
|
return;
|
|
@@ -57520,7 +57798,7 @@ var init_status_bar = __esm({
|
|
|
57520
57798
|
if (nexusDir) {
|
|
57521
57799
|
try {
|
|
57522
57800
|
const metricsPath = nexusDir + "/remote-metrics.json";
|
|
57523
|
-
const raw =
|
|
57801
|
+
const raw = readFileSync37(metricsPath, "utf8");
|
|
57524
57802
|
const cached = JSON.parse(raw);
|
|
57525
57803
|
if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
|
|
57526
57804
|
const m = cached.data;
|
|
@@ -59119,12 +59397,12 @@ var init_mouse_filter = __esm({
|
|
|
59119
59397
|
import * as readline2 from "node:readline";
|
|
59120
59398
|
import { Writable } from "node:stream";
|
|
59121
59399
|
import { cwd } from "node:process";
|
|
59122
|
-
import { resolve as resolve31, join as
|
|
59400
|
+
import { resolve as resolve31, join as join66, dirname as dirname20, extname as extname11 } from "node:path";
|
|
59123
59401
|
import { createRequire as createRequire2 } from "node:module";
|
|
59124
59402
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
59125
|
-
import { readFileSync as
|
|
59126
|
-
import { existsSync as
|
|
59127
|
-
import { execSync as
|
|
59403
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync22, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync19, mkdirSync as mkdirSync23 } from "node:fs";
|
|
59404
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
59405
|
+
import { execSync as execSync33 } from "node:child_process";
|
|
59128
59406
|
import { homedir as homedir16 } from "node:os";
|
|
59129
59407
|
function formatTimeAgo(date) {
|
|
59130
59408
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
@@ -59144,12 +59422,12 @@ function getVersion3() {
|
|
|
59144
59422
|
const require2 = createRequire2(import.meta.url);
|
|
59145
59423
|
const thisDir = dirname20(fileURLToPath12(import.meta.url));
|
|
59146
59424
|
const candidates = [
|
|
59147
|
-
|
|
59148
|
-
|
|
59149
|
-
|
|
59425
|
+
join66(thisDir, "..", "package.json"),
|
|
59426
|
+
join66(thisDir, "..", "..", "package.json"),
|
|
59427
|
+
join66(thisDir, "..", "..", "..", "package.json")
|
|
59150
59428
|
];
|
|
59151
59429
|
for (const pkgPath of candidates) {
|
|
59152
|
-
if (
|
|
59430
|
+
if (existsSync49(pkgPath)) {
|
|
59153
59431
|
const pkg = require2(pkgPath);
|
|
59154
59432
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
59155
59433
|
return pkg.version ?? "0.0.0";
|
|
@@ -59282,6 +59560,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
59282
59560
|
new SemanticMapTool(repoRoot),
|
|
59283
59561
|
new RepoMapTool(repoRoot),
|
|
59284
59562
|
new ProcessHealthTool(),
|
|
59563
|
+
new VideoUnderstandTool(repoRoot),
|
|
59285
59564
|
// Full OA sub-process — callbacks wired after runner + statusBar created
|
|
59286
59565
|
(() => {
|
|
59287
59566
|
_fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
|
|
@@ -59383,15 +59662,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
59383
59662
|
function gatherMemorySnippets(root) {
|
|
59384
59663
|
const snippets = [];
|
|
59385
59664
|
const dirs = [
|
|
59386
|
-
|
|
59387
|
-
|
|
59665
|
+
join66(root, ".oa", "memory"),
|
|
59666
|
+
join66(root, ".open-agents", "memory")
|
|
59388
59667
|
];
|
|
59389
59668
|
for (const dir of dirs) {
|
|
59390
|
-
if (!
|
|
59669
|
+
if (!existsSync49(dir))
|
|
59391
59670
|
continue;
|
|
59392
59671
|
try {
|
|
59393
|
-
for (const f of
|
|
59394
|
-
const data = JSON.parse(
|
|
59672
|
+
for (const f of readdirSync19(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
59673
|
+
const data = JSON.parse(readFileSync38(join66(dir, f), "utf-8"));
|
|
59395
59674
|
for (const val of Object.values(data)) {
|
|
59396
59675
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
59397
59676
|
if (v.length > 10)
|
|
@@ -59548,9 +59827,9 @@ ${metabolismMemories}
|
|
|
59548
59827
|
} catch {
|
|
59549
59828
|
}
|
|
59550
59829
|
try {
|
|
59551
|
-
const archeFile =
|
|
59552
|
-
if (
|
|
59553
|
-
const variants = JSON.parse(
|
|
59830
|
+
const archeFile = join66(repoRoot, ".oa", "arche", "variants.json");
|
|
59831
|
+
if (existsSync49(archeFile)) {
|
|
59832
|
+
const variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
59554
59833
|
if (variants.length > 0) {
|
|
59555
59834
|
let filtered = variants;
|
|
59556
59835
|
if (taskType) {
|
|
@@ -59687,9 +59966,9 @@ ${lines.join("\n")}
|
|
|
59687
59966
|
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
59688
59967
|
let identityInjection = "";
|
|
59689
59968
|
try {
|
|
59690
|
-
const ikStateFile =
|
|
59691
|
-
if (
|
|
59692
|
-
const selfState = JSON.parse(
|
|
59969
|
+
const ikStateFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
59970
|
+
if (existsSync49(ikStateFile)) {
|
|
59971
|
+
const selfState = JSON.parse(readFileSync38(ikStateFile, "utf8"));
|
|
59693
59972
|
const lines = [
|
|
59694
59973
|
`[Identity State v${selfState.version}]`,
|
|
59695
59974
|
`Self: ${selfState.narrative_summary}`,
|
|
@@ -60328,13 +60607,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60328
60607
|
});
|
|
60329
60608
|
}
|
|
60330
60609
|
try {
|
|
60331
|
-
const ikDir =
|
|
60332
|
-
const ikFile =
|
|
60610
|
+
const ikDir = join66(repoRoot, ".oa", "identity");
|
|
60611
|
+
const ikFile = join66(ikDir, "self-state.json");
|
|
60333
60612
|
let ikState;
|
|
60334
|
-
if (
|
|
60335
|
-
ikState = JSON.parse(
|
|
60613
|
+
if (existsSync49(ikFile)) {
|
|
60614
|
+
ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
60336
60615
|
} else {
|
|
60337
|
-
|
|
60616
|
+
mkdirSync23(ikDir, { recursive: true });
|
|
60338
60617
|
const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
60339
60618
|
ikState = {
|
|
60340
60619
|
self_id: `oa-${machineId}`,
|
|
@@ -60360,7 +60639,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60360
60639
|
}
|
|
60361
60640
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60362
60641
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60363
|
-
|
|
60642
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
60364
60643
|
} catch (ikErr) {
|
|
60365
60644
|
try {
|
|
60366
60645
|
console.error("[IK-OBSERVE]", ikErr);
|
|
@@ -60375,14 +60654,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
60375
60654
|
} else {
|
|
60376
60655
|
renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
|
|
60377
60656
|
try {
|
|
60378
|
-
const ikFile =
|
|
60379
|
-
if (
|
|
60380
|
-
const ikState = JSON.parse(
|
|
60657
|
+
const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
60658
|
+
if (existsSync49(ikFile)) {
|
|
60659
|
+
const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
60381
60660
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
60382
60661
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
60383
60662
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
60384
60663
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
60385
|
-
|
|
60664
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
60386
60665
|
}
|
|
60387
60666
|
} catch {
|
|
60388
60667
|
}
|
|
@@ -60725,7 +61004,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
60725
61004
|
let p2pGateway = null;
|
|
60726
61005
|
let peerMesh = null;
|
|
60727
61006
|
let inferenceRouter = null;
|
|
60728
|
-
const secretVault = new SecretVault(
|
|
61007
|
+
const secretVault = new SecretVault(join66(repoRoot, ".oa", "vault.enc"));
|
|
60729
61008
|
let adminSessionKey = null;
|
|
60730
61009
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
60731
61010
|
const streamRenderer = new StreamRenderer();
|
|
@@ -60945,13 +61224,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
60945
61224
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
60946
61225
|
return [hits, line];
|
|
60947
61226
|
}
|
|
60948
|
-
const HISTORY_DIR =
|
|
60949
|
-
const HISTORY_FILE =
|
|
61227
|
+
const HISTORY_DIR = join66(homedir16(), ".open-agents");
|
|
61228
|
+
const HISTORY_FILE = join66(HISTORY_DIR, "repl-history");
|
|
60950
61229
|
const MAX_HISTORY_LINES = 500;
|
|
60951
61230
|
let savedHistory = [];
|
|
60952
61231
|
try {
|
|
60953
|
-
if (
|
|
60954
|
-
const raw =
|
|
61232
|
+
if (existsSync49(HISTORY_FILE)) {
|
|
61233
|
+
const raw = readFileSync38(HISTORY_FILE, "utf8").trim();
|
|
60955
61234
|
if (raw)
|
|
60956
61235
|
savedHistory = raw.split("\n").reverse();
|
|
60957
61236
|
}
|
|
@@ -61031,12 +61310,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61031
61310
|
if (!line.trim())
|
|
61032
61311
|
return;
|
|
61033
61312
|
try {
|
|
61034
|
-
|
|
61313
|
+
mkdirSync23(HISTORY_DIR, { recursive: true });
|
|
61035
61314
|
appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
|
|
61036
61315
|
if (Math.random() < 0.02) {
|
|
61037
|
-
const all =
|
|
61316
|
+
const all = readFileSync38(HISTORY_FILE, "utf8").trim().split("\n");
|
|
61038
61317
|
if (all.length > MAX_HISTORY_LINES) {
|
|
61039
|
-
|
|
61318
|
+
writeFileSync22(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
|
|
61040
61319
|
}
|
|
61041
61320
|
}
|
|
61042
61321
|
} catch {
|
|
@@ -61212,7 +61491,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61212
61491
|
} catch {
|
|
61213
61492
|
}
|
|
61214
61493
|
try {
|
|
61215
|
-
const oaDir =
|
|
61494
|
+
const oaDir = join66(repoRoot, ".oa");
|
|
61216
61495
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
61217
61496
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61218
61497
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -61235,7 +61514,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
61235
61514
|
} catch {
|
|
61236
61515
|
}
|
|
61237
61516
|
try {
|
|
61238
|
-
const oaDir =
|
|
61517
|
+
const oaDir = join66(repoRoot, ".oa");
|
|
61239
61518
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
61240
61519
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
61241
61520
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -62119,7 +62398,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62119
62398
|
kind,
|
|
62120
62399
|
targetUrl,
|
|
62121
62400
|
authKey,
|
|
62122
|
-
stateDir:
|
|
62401
|
+
stateDir: join66(repoRoot, ".oa"),
|
|
62123
62402
|
passthrough: passthrough ?? false,
|
|
62124
62403
|
loadbalance: loadbalance ?? false,
|
|
62125
62404
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -62167,7 +62446,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62167
62446
|
await tunnelGateway.stop();
|
|
62168
62447
|
tunnelGateway = null;
|
|
62169
62448
|
}
|
|
62170
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
62449
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join66(repoRoot, ".oa") });
|
|
62171
62450
|
newTunnel.on("stats", (stats) => {
|
|
62172
62451
|
statusBar.setExposeStatus({
|
|
62173
62452
|
status: stats.status,
|
|
@@ -62436,15 +62715,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62436
62715
|
writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
|
|
62437
62716
|
}
|
|
62438
62717
|
try {
|
|
62439
|
-
const nexusDir =
|
|
62440
|
-
const pidFile =
|
|
62441
|
-
if (
|
|
62442
|
-
const pid = parseInt(
|
|
62718
|
+
const nexusDir = join66(repoRoot, OA_DIR, "nexus");
|
|
62719
|
+
const pidFile = join66(nexusDir, "daemon.pid");
|
|
62720
|
+
if (existsSync49(pidFile)) {
|
|
62721
|
+
const pid = parseInt(readFileSync38(pidFile, "utf8").trim(), 10);
|
|
62443
62722
|
if (pid > 0) {
|
|
62444
62723
|
try {
|
|
62445
62724
|
if (process.platform === "win32") {
|
|
62446
62725
|
try {
|
|
62447
|
-
|
|
62726
|
+
execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
62448
62727
|
} catch {
|
|
62449
62728
|
}
|
|
62450
62729
|
} else {
|
|
@@ -62461,17 +62740,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62461
62740
|
} catch {
|
|
62462
62741
|
}
|
|
62463
62742
|
try {
|
|
62464
|
-
const voiceDir2 =
|
|
62743
|
+
const voiceDir2 = join66(homedir16(), ".open-agents", "voice");
|
|
62465
62744
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
62466
62745
|
for (const pf of voicePidFiles) {
|
|
62467
|
-
const pidPath =
|
|
62468
|
-
if (
|
|
62746
|
+
const pidPath = join66(voiceDir2, pf);
|
|
62747
|
+
if (existsSync49(pidPath)) {
|
|
62469
62748
|
try {
|
|
62470
|
-
const pid = parseInt(
|
|
62749
|
+
const pid = parseInt(readFileSync38(pidPath, "utf8").trim(), 10);
|
|
62471
62750
|
if (pid > 0) {
|
|
62472
62751
|
if (process.platform === "win32") {
|
|
62473
62752
|
try {
|
|
62474
|
-
|
|
62753
|
+
execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
|
|
62475
62754
|
} catch {
|
|
62476
62755
|
}
|
|
62477
62756
|
} else {
|
|
@@ -62488,11 +62767,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62488
62767
|
} catch {
|
|
62489
62768
|
}
|
|
62490
62769
|
try {
|
|
62491
|
-
|
|
62770
|
+
execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
|
|
62492
62771
|
} catch {
|
|
62493
62772
|
}
|
|
62494
|
-
const oaPath =
|
|
62495
|
-
if (
|
|
62773
|
+
const oaPath = join66(repoRoot, OA_DIR);
|
|
62774
|
+
if (existsSync49(oaPath)) {
|
|
62496
62775
|
let deleted = false;
|
|
62497
62776
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
62498
62777
|
try {
|
|
@@ -62502,14 +62781,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
62502
62781
|
} catch (err) {
|
|
62503
62782
|
if (attempt < 2) {
|
|
62504
62783
|
try {
|
|
62505
|
-
|
|
62784
|
+
execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
|
|
62506
62785
|
} catch {
|
|
62507
62786
|
}
|
|
62508
62787
|
} else {
|
|
62509
62788
|
writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
|
|
62510
62789
|
if (process.platform === "win32") {
|
|
62511
62790
|
try {
|
|
62512
|
-
|
|
62791
|
+
execSync33(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
|
|
62513
62792
|
deleted = true;
|
|
62514
62793
|
} catch {
|
|
62515
62794
|
}
|
|
@@ -62864,8 +63143,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
62864
63143
|
}
|
|
62865
63144
|
}
|
|
62866
63145
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
62867
|
-
const isImage = isImagePath(cleanPath) &&
|
|
62868
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
63146
|
+
const isImage = isImagePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
|
|
63147
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
|
|
62869
63148
|
if (activeTask) {
|
|
62870
63149
|
if (activeTask.runner.isPaused) {
|
|
62871
63150
|
activeTask.runner.resume();
|
|
@@ -62874,7 +63153,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
62874
63153
|
if (isImage) {
|
|
62875
63154
|
try {
|
|
62876
63155
|
const imgPath = resolve31(repoRoot, cleanPath);
|
|
62877
|
-
const imgBuffer =
|
|
63156
|
+
const imgBuffer = readFileSync38(imgPath);
|
|
62878
63157
|
const base64 = imgBuffer.toString("base64");
|
|
62879
63158
|
const ext = extname11(cleanPath).toLowerCase();
|
|
62880
63159
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -63111,13 +63390,13 @@ NEW TASK: ${fullInput}`;
|
|
|
63111
63390
|
writeContent(() => renderError(errMsg));
|
|
63112
63391
|
if (failureStore) {
|
|
63113
63392
|
try {
|
|
63114
|
-
const { createHash:
|
|
63393
|
+
const { createHash: createHash6 } = await import("node:crypto");
|
|
63115
63394
|
failureStore.insert({
|
|
63116
63395
|
taskId: "",
|
|
63117
63396
|
sessionId: `${Date.now()}`,
|
|
63118
63397
|
repoRoot,
|
|
63119
63398
|
failureType: "runtime-error",
|
|
63120
|
-
fingerprint:
|
|
63399
|
+
fingerprint: createHash6("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
|
|
63121
63400
|
filePath: null,
|
|
63122
63401
|
errorMessage: errMsg.slice(0, 500),
|
|
63123
63402
|
context: null,
|
|
@@ -63373,13 +63652,13 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63373
63652
|
const handle = startTask(task, config, repoRoot);
|
|
63374
63653
|
await handle.promise;
|
|
63375
63654
|
try {
|
|
63376
|
-
const ikDir =
|
|
63377
|
-
const ikFile =
|
|
63655
|
+
const ikDir = join66(repoRoot, ".oa", "identity");
|
|
63656
|
+
const ikFile = join66(ikDir, "self-state.json");
|
|
63378
63657
|
let ikState;
|
|
63379
|
-
if (
|
|
63380
|
-
ikState = JSON.parse(
|
|
63658
|
+
if (existsSync49(ikFile)) {
|
|
63659
|
+
ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
63381
63660
|
} else {
|
|
63382
|
-
|
|
63661
|
+
mkdirSync23(ikDir, { recursive: true });
|
|
63383
63662
|
ikState = {
|
|
63384
63663
|
self_id: `oa-${Date.now().toString(36)}`,
|
|
63385
63664
|
version: 1,
|
|
@@ -63401,7 +63680,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63401
63680
|
ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
|
|
63402
63681
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
63403
63682
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
63404
|
-
|
|
63683
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
63405
63684
|
} catch (ikErr) {
|
|
63406
63685
|
}
|
|
63407
63686
|
try {
|
|
@@ -63410,12 +63689,12 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63410
63689
|
ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
|
|
63411
63690
|
} catch {
|
|
63412
63691
|
try {
|
|
63413
|
-
const archeDir =
|
|
63414
|
-
const archeFile =
|
|
63692
|
+
const archeDir = join66(repoRoot, ".oa", "arche");
|
|
63693
|
+
const archeFile = join66(archeDir, "variants.json");
|
|
63415
63694
|
let variants = [];
|
|
63416
63695
|
try {
|
|
63417
|
-
if (
|
|
63418
|
-
variants = JSON.parse(
|
|
63696
|
+
if (existsSync49(archeFile))
|
|
63697
|
+
variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
63419
63698
|
} catch {
|
|
63420
63699
|
}
|
|
63421
63700
|
variants.push({
|
|
@@ -63430,15 +63709,15 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63430
63709
|
});
|
|
63431
63710
|
if (variants.length > 50)
|
|
63432
63711
|
variants = variants.slice(-50);
|
|
63433
|
-
|
|
63434
|
-
|
|
63712
|
+
mkdirSync23(archeDir, { recursive: true });
|
|
63713
|
+
writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
|
|
63435
63714
|
} catch {
|
|
63436
63715
|
}
|
|
63437
63716
|
}
|
|
63438
63717
|
try {
|
|
63439
|
-
const metaFile =
|
|
63440
|
-
if (
|
|
63441
|
-
const store = JSON.parse(
|
|
63718
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63719
|
+
if (existsSync49(metaFile)) {
|
|
63720
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63442
63721
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
63443
63722
|
let updated = false;
|
|
63444
63723
|
for (const item of surfaced) {
|
|
@@ -63449,7 +63728,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
63449
63728
|
updated = true;
|
|
63450
63729
|
}
|
|
63451
63730
|
if (updated) {
|
|
63452
|
-
|
|
63731
|
+
writeFileSync22(metaFile, JSON.stringify(store, null, 2));
|
|
63453
63732
|
}
|
|
63454
63733
|
}
|
|
63455
63734
|
} catch {
|
|
@@ -63502,9 +63781,9 @@ Rules:
|
|
|
63502
63781
|
try {
|
|
63503
63782
|
const { initDb: initDb2 } = __require("@open-agents/memory");
|
|
63504
63783
|
const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
|
|
63505
|
-
const dbDir =
|
|
63506
|
-
|
|
63507
|
-
const db = initDb2(
|
|
63784
|
+
const dbDir = join66(repoRoot, ".oa", "memory");
|
|
63785
|
+
mkdirSync23(dbDir, { recursive: true });
|
|
63786
|
+
const db = initDb2(join66(dbDir, "structured.db"));
|
|
63508
63787
|
const memStore = new ProceduralMemoryStore2(db);
|
|
63509
63788
|
memStore.createWithEmbedding({
|
|
63510
63789
|
content: content.slice(0, 600),
|
|
@@ -63519,12 +63798,12 @@ Rules:
|
|
|
63519
63798
|
db.close();
|
|
63520
63799
|
} catch {
|
|
63521
63800
|
}
|
|
63522
|
-
const metaDir =
|
|
63523
|
-
const storeFile =
|
|
63801
|
+
const metaDir = join66(repoRoot, ".oa", "memory", "metabolism");
|
|
63802
|
+
const storeFile = join66(metaDir, "store.json");
|
|
63524
63803
|
let store = [];
|
|
63525
63804
|
try {
|
|
63526
|
-
if (
|
|
63527
|
-
store = JSON.parse(
|
|
63805
|
+
if (existsSync49(storeFile))
|
|
63806
|
+
store = JSON.parse(readFileSync38(storeFile, "utf8"));
|
|
63528
63807
|
} catch {
|
|
63529
63808
|
}
|
|
63530
63809
|
store.push({
|
|
@@ -63540,26 +63819,26 @@ Rules:
|
|
|
63540
63819
|
});
|
|
63541
63820
|
if (store.length > 100)
|
|
63542
63821
|
store = store.slice(-100);
|
|
63543
|
-
|
|
63544
|
-
|
|
63822
|
+
mkdirSync23(metaDir, { recursive: true });
|
|
63823
|
+
writeFileSync22(storeFile, JSON.stringify(store, null, 2));
|
|
63545
63824
|
}
|
|
63546
63825
|
}
|
|
63547
63826
|
} catch {
|
|
63548
63827
|
}
|
|
63549
63828
|
try {
|
|
63550
|
-
const cohereSettingsFile =
|
|
63829
|
+
const cohereSettingsFile = join66(repoRoot, ".oa", "settings.json");
|
|
63551
63830
|
let cohereActive = false;
|
|
63552
63831
|
try {
|
|
63553
|
-
if (
|
|
63554
|
-
const settings = JSON.parse(
|
|
63832
|
+
if (existsSync49(cohereSettingsFile)) {
|
|
63833
|
+
const settings = JSON.parse(readFileSync38(cohereSettingsFile, "utf8"));
|
|
63555
63834
|
cohereActive = settings.cohere === true;
|
|
63556
63835
|
}
|
|
63557
63836
|
} catch {
|
|
63558
63837
|
}
|
|
63559
63838
|
if (cohereActive) {
|
|
63560
|
-
const metaFile =
|
|
63561
|
-
if (
|
|
63562
|
-
const store = JSON.parse(
|
|
63839
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63840
|
+
if (existsSync49(metaFile)) {
|
|
63841
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63563
63842
|
const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
|
|
63564
63843
|
if (latest && latest.scores?.confidence >= 0.6) {
|
|
63565
63844
|
try {
|
|
@@ -63584,18 +63863,18 @@ Rules:
|
|
|
63584
63863
|
}
|
|
63585
63864
|
} catch (err) {
|
|
63586
63865
|
try {
|
|
63587
|
-
const ikFile =
|
|
63588
|
-
if (
|
|
63589
|
-
const ikState = JSON.parse(
|
|
63866
|
+
const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
|
|
63867
|
+
if (existsSync49(ikFile)) {
|
|
63868
|
+
const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
|
|
63590
63869
|
ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
|
|
63591
63870
|
ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
|
|
63592
63871
|
ikState.session_count = (ikState.session_count || 0) + 1;
|
|
63593
63872
|
ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
63594
|
-
|
|
63873
|
+
writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
|
|
63595
63874
|
}
|
|
63596
|
-
const metaFile =
|
|
63597
|
-
if (
|
|
63598
|
-
const store = JSON.parse(
|
|
63875
|
+
const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
|
|
63876
|
+
if (existsSync49(metaFile)) {
|
|
63877
|
+
const store = JSON.parse(readFileSync38(metaFile, "utf8"));
|
|
63599
63878
|
const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
|
|
63600
63879
|
for (const item of surfaced) {
|
|
63601
63880
|
item.accessCount = (item.accessCount || 0) + 1;
|
|
@@ -63603,15 +63882,15 @@ Rules:
|
|
|
63603
63882
|
item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
|
|
63604
63883
|
item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
|
|
63605
63884
|
}
|
|
63606
|
-
|
|
63885
|
+
writeFileSync22(metaFile, JSON.stringify(store, null, 2));
|
|
63607
63886
|
}
|
|
63608
63887
|
try {
|
|
63609
|
-
const archeDir =
|
|
63610
|
-
const archeFile =
|
|
63888
|
+
const archeDir = join66(repoRoot, ".oa", "arche");
|
|
63889
|
+
const archeFile = join66(archeDir, "variants.json");
|
|
63611
63890
|
let variants = [];
|
|
63612
63891
|
try {
|
|
63613
|
-
if (
|
|
63614
|
-
variants = JSON.parse(
|
|
63892
|
+
if (existsSync49(archeFile))
|
|
63893
|
+
variants = JSON.parse(readFileSync38(archeFile, "utf8"));
|
|
63615
63894
|
} catch {
|
|
63616
63895
|
}
|
|
63617
63896
|
variants.push({
|
|
@@ -63626,8 +63905,8 @@ Rules:
|
|
|
63626
63905
|
});
|
|
63627
63906
|
if (variants.length > 50)
|
|
63628
63907
|
variants = variants.slice(-50);
|
|
63629
|
-
|
|
63630
|
-
|
|
63908
|
+
mkdirSync23(archeDir, { recursive: true });
|
|
63909
|
+
writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
|
|
63631
63910
|
} catch {
|
|
63632
63911
|
}
|
|
63633
63912
|
} catch {
|
|
@@ -63715,8 +63994,8 @@ var init_run = __esm({
|
|
|
63715
63994
|
import { glob } from "glob";
|
|
63716
63995
|
import ignore from "ignore";
|
|
63717
63996
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
63718
|
-
import { createHash as
|
|
63719
|
-
import { join as
|
|
63997
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
63998
|
+
import { join as join67, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
63720
63999
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
63721
64000
|
var init_codebase_indexer = __esm({
|
|
63722
64001
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -63760,7 +64039,7 @@ var init_codebase_indexer = __esm({
|
|
|
63760
64039
|
const ig = ignore.default();
|
|
63761
64040
|
if (this.config.respectGitignore) {
|
|
63762
64041
|
try {
|
|
63763
|
-
const gitignoreContent = await readFile23(
|
|
64042
|
+
const gitignoreContent = await readFile23(join67(this.config.rootDir, ".gitignore"), "utf-8");
|
|
63764
64043
|
ig.add(gitignoreContent);
|
|
63765
64044
|
} catch {
|
|
63766
64045
|
}
|
|
@@ -63775,13 +64054,13 @@ var init_codebase_indexer = __esm({
|
|
|
63775
64054
|
for (const relativePath of files) {
|
|
63776
64055
|
if (ig.ignores(relativePath))
|
|
63777
64056
|
continue;
|
|
63778
|
-
const fullPath =
|
|
64057
|
+
const fullPath = join67(this.config.rootDir, relativePath);
|
|
63779
64058
|
try {
|
|
63780
64059
|
const fileStat = await stat4(fullPath);
|
|
63781
64060
|
if (fileStat.size > this.config.maxFileSize)
|
|
63782
64061
|
continue;
|
|
63783
64062
|
const content = await readFile23(fullPath);
|
|
63784
|
-
const hash =
|
|
64063
|
+
const hash = createHash5("sha256").update(content).digest("hex");
|
|
63785
64064
|
const ext = extname12(relativePath);
|
|
63786
64065
|
indexed.push({
|
|
63787
64066
|
path: fullPath,
|
|
@@ -63798,7 +64077,7 @@ var init_codebase_indexer = __esm({
|
|
|
63798
64077
|
}
|
|
63799
64078
|
buildTree(files) {
|
|
63800
64079
|
const root = {
|
|
63801
|
-
name:
|
|
64080
|
+
name: basename17(this.config.rootDir),
|
|
63802
64081
|
path: this.config.rootDir,
|
|
63803
64082
|
type: "directory",
|
|
63804
64083
|
children: []
|
|
@@ -63821,7 +64100,7 @@ var init_codebase_indexer = __esm({
|
|
|
63821
64100
|
if (!child) {
|
|
63822
64101
|
child = {
|
|
63823
64102
|
name: part,
|
|
63824
|
-
path:
|
|
64103
|
+
path: join67(current.path, part),
|
|
63825
64104
|
type: "directory",
|
|
63826
64105
|
children: []
|
|
63827
64106
|
};
|
|
@@ -63904,13 +64183,13 @@ __export(index_repo_exports, {
|
|
|
63904
64183
|
indexRepoCommand: () => indexRepoCommand
|
|
63905
64184
|
});
|
|
63906
64185
|
import { resolve as resolve32 } from "node:path";
|
|
63907
|
-
import { existsSync as
|
|
64186
|
+
import { existsSync as existsSync50, statSync as statSync16 } from "node:fs";
|
|
63908
64187
|
import { cwd as cwd2 } from "node:process";
|
|
63909
64188
|
async function indexRepoCommand(opts, _config) {
|
|
63910
64189
|
const repoRoot = resolve32(opts.repoPath ?? cwd2());
|
|
63911
64190
|
printHeader("Index Repository");
|
|
63912
64191
|
printInfo(`Indexing: ${repoRoot}`);
|
|
63913
|
-
if (!
|
|
64192
|
+
if (!existsSync50(repoRoot)) {
|
|
63914
64193
|
printError(`Path does not exist: ${repoRoot}`);
|
|
63915
64194
|
process.exit(1);
|
|
63916
64195
|
}
|
|
@@ -64162,7 +64441,7 @@ var config_exports = {};
|
|
|
64162
64441
|
__export(config_exports, {
|
|
64163
64442
|
configCommand: () => configCommand
|
|
64164
64443
|
});
|
|
64165
|
-
import { join as
|
|
64444
|
+
import { join as join68, resolve as resolve33 } from "node:path";
|
|
64166
64445
|
import { homedir as homedir17 } from "node:os";
|
|
64167
64446
|
import { cwd as cwd3 } from "node:process";
|
|
64168
64447
|
function redactIfSensitive(key, value) {
|
|
@@ -64245,7 +64524,7 @@ function handleShow(opts, config) {
|
|
|
64245
64524
|
}
|
|
64246
64525
|
}
|
|
64247
64526
|
printSection("Config File");
|
|
64248
|
-
printInfo(`~/.open-agents/config.json (${
|
|
64527
|
+
printInfo(`~/.open-agents/config.json (${join68(homedir17(), ".open-agents", "config.json")})`);
|
|
64249
64528
|
printSection("Priority Chain");
|
|
64250
64529
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
64251
64530
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -64284,7 +64563,7 @@ function handleSet(opts, _config) {
|
|
|
64284
64563
|
const coerced = coerceForSettings(key, value);
|
|
64285
64564
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
64286
64565
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
64287
|
-
printInfo(`Saved to ${
|
|
64566
|
+
printInfo(`Saved to ${join68(repoRoot, ".oa", "settings.json")}`);
|
|
64288
64567
|
printInfo("This override applies only when running in this workspace.");
|
|
64289
64568
|
} catch (err) {
|
|
64290
64569
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -64542,8 +64821,8 @@ __export(eval_exports, {
|
|
|
64542
64821
|
evalCommand: () => evalCommand
|
|
64543
64822
|
});
|
|
64544
64823
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
64545
|
-
import { mkdirSync as
|
|
64546
|
-
import { join as
|
|
64824
|
+
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23 } from "node:fs";
|
|
64825
|
+
import { join as join69 } from "node:path";
|
|
64547
64826
|
async function evalCommand(opts, config) {
|
|
64548
64827
|
const suiteName = opts.suite ?? "basic";
|
|
64549
64828
|
const suite = SUITES[suiteName];
|
|
@@ -64668,9 +64947,9 @@ async function evalCommand(opts, config) {
|
|
|
64668
64947
|
process.exit(failed > 0 ? 1 : 0);
|
|
64669
64948
|
}
|
|
64670
64949
|
function createTempEvalRepo() {
|
|
64671
|
-
const dir =
|
|
64672
|
-
|
|
64673
|
-
|
|
64950
|
+
const dir = join69(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
64951
|
+
mkdirSync24(dir, { recursive: true });
|
|
64952
|
+
writeFileSync23(join69(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
64674
64953
|
return dir;
|
|
64675
64954
|
}
|
|
64676
64955
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -64730,7 +65009,7 @@ init_updater();
|
|
|
64730
65009
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
64731
65010
|
import { createRequire as createRequire3 } from "node:module";
|
|
64732
65011
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
64733
|
-
import { dirname as dirname21, join as
|
|
65012
|
+
import { dirname as dirname21, join as join70 } from "node:path";
|
|
64734
65013
|
|
|
64735
65014
|
// packages/cli/dist/cli.js
|
|
64736
65015
|
import { createInterface } from "node:readline";
|
|
@@ -64837,7 +65116,7 @@ init_output();
|
|
|
64837
65116
|
function getVersion4() {
|
|
64838
65117
|
try {
|
|
64839
65118
|
const require2 = createRequire3(import.meta.url);
|
|
64840
|
-
const pkgPath =
|
|
65119
|
+
const pkgPath = join70(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
64841
65120
|
const pkg = require2(pkgPath);
|
|
64842
65121
|
return pkg.version;
|
|
64843
65122
|
} catch {
|