open-agents-ai 0.105.7 → 0.106.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 +783 -449
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5639,8 +5639,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
|
|
|
5639
5639
|
const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
|
|
5640
5640
|
const filePath = join13(dir, `${name}.json`);
|
|
5641
5641
|
if (existsSync10(filePath)) {
|
|
5642
|
-
const { unlinkSync:
|
|
5643
|
-
|
|
5642
|
+
const { unlinkSync: unlinkSync11 } = __require("node:fs");
|
|
5643
|
+
unlinkSync11(filePath);
|
|
5644
5644
|
return true;
|
|
5645
5645
|
}
|
|
5646
5646
|
return false;
|
|
@@ -7511,6 +7511,315 @@ ${result.filesCreated.join("\n")}`);
|
|
|
7511
7511
|
}
|
|
7512
7512
|
});
|
|
7513
7513
|
|
|
7514
|
+
// packages/execution/dist/tools/repl.js
|
|
7515
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
7516
|
+
import { createServer } from "node:net";
|
|
7517
|
+
import { join as join18 } from "node:path";
|
|
7518
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
7519
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
7520
|
+
import { unlinkSync as unlinkSync2 } from "node:fs";
|
|
7521
|
+
var ReplTool;
|
|
7522
|
+
var init_repl = __esm({
|
|
7523
|
+
"packages/execution/dist/tools/repl.js"() {
|
|
7524
|
+
"use strict";
|
|
7525
|
+
ReplTool = class {
|
|
7526
|
+
name = "repl_exec";
|
|
7527
|
+
description = "Execute Python code in a persistent REPL environment. Variables, imports, and functions persist between calls within the same task. Use for data processing, analysis, and building up results across multiple steps. A special function llm_query(prompt, context='') is available to invoke the language model from within Python code for semantic analysis of text chunks. Write results to files or print them to see output.";
|
|
7528
|
+
parameters = {
|
|
7529
|
+
type: "object",
|
|
7530
|
+
properties: {
|
|
7531
|
+
code: {
|
|
7532
|
+
type: "string",
|
|
7533
|
+
description: "Python code to execute in the persistent REPL"
|
|
7534
|
+
},
|
|
7535
|
+
reset: {
|
|
7536
|
+
type: "boolean",
|
|
7537
|
+
description: "Reset the REPL state (kill process, clear all variables). Default: false"
|
|
7538
|
+
}
|
|
7539
|
+
},
|
|
7540
|
+
required: ["code"]
|
|
7541
|
+
};
|
|
7542
|
+
proc = null;
|
|
7543
|
+
ipcServer = null;
|
|
7544
|
+
ipcPath = null;
|
|
7545
|
+
cwd;
|
|
7546
|
+
llmQueryHandler = null;
|
|
7547
|
+
subCallCount = 0;
|
|
7548
|
+
maxSubCalls;
|
|
7549
|
+
execTimeout;
|
|
7550
|
+
constructor(cwd4, options) {
|
|
7551
|
+
this.cwd = cwd4;
|
|
7552
|
+
this.llmQueryHandler = options?.llmQueryHandler ?? null;
|
|
7553
|
+
this.maxSubCalls = options?.maxSubCalls ?? 50;
|
|
7554
|
+
this.execTimeout = options?.execTimeout ?? 6e4;
|
|
7555
|
+
}
|
|
7556
|
+
/** Set the llm_query handler (called after construction when backend is available) */
|
|
7557
|
+
setLlmQueryHandler(handler) {
|
|
7558
|
+
this.llmQueryHandler = handler;
|
|
7559
|
+
}
|
|
7560
|
+
/** Get the number of sub-calls made this session */
|
|
7561
|
+
getSubCallCount() {
|
|
7562
|
+
return this.subCallCount;
|
|
7563
|
+
}
|
|
7564
|
+
async execute(args) {
|
|
7565
|
+
const code = String(args.code ?? "");
|
|
7566
|
+
const reset = Boolean(args.reset);
|
|
7567
|
+
if (reset) {
|
|
7568
|
+
await this.dispose();
|
|
7569
|
+
return { success: true, output: "REPL state cleared.", durationMs: 0 };
|
|
7570
|
+
}
|
|
7571
|
+
if (!code.trim()) {
|
|
7572
|
+
return { success: false, output: "No code provided.", error: "Empty code", durationMs: 0 };
|
|
7573
|
+
}
|
|
7574
|
+
const start = performance.now();
|
|
7575
|
+
try {
|
|
7576
|
+
if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
|
|
7577
|
+
await this.startProcess();
|
|
7578
|
+
}
|
|
7579
|
+
const result = await this.executeCode(code);
|
|
7580
|
+
return { ...result, durationMs: performance.now() - start };
|
|
7581
|
+
} catch (err) {
|
|
7582
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7583
|
+
return { success: false, output: `REPL error: ${msg}`, error: msg, durationMs: performance.now() - start };
|
|
7584
|
+
}
|
|
7585
|
+
}
|
|
7586
|
+
// ── Process lifecycle ────────────────────────────────────────────────────
|
|
7587
|
+
async startProcess() {
|
|
7588
|
+
await this.startIpcServer();
|
|
7589
|
+
this.proc = spawn6("python3", ["-u", "-i", "-q"], {
|
|
7590
|
+
cwd: this.cwd,
|
|
7591
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
7592
|
+
env: {
|
|
7593
|
+
...process.env,
|
|
7594
|
+
PYTHONUNBUFFERED: "1",
|
|
7595
|
+
PYTHONDONTWRITEBYTECODE: "1",
|
|
7596
|
+
OA_LLM_QUERY_SOCKET: this.ipcPath ?? ""
|
|
7597
|
+
}
|
|
7598
|
+
});
|
|
7599
|
+
this.proc.on("error", () => {
|
|
7600
|
+
});
|
|
7601
|
+
const initCode = this.buildInitCode();
|
|
7602
|
+
await this.executeCode(initCode, true);
|
|
7603
|
+
}
|
|
7604
|
+
buildInitCode() {
|
|
7605
|
+
return `
|
|
7606
|
+
import sys, os, json, socket
|
|
7607
|
+
|
|
7608
|
+
def llm_query(prompt, context=""):
|
|
7609
|
+
"""Invoke the language model on a sub-prompt. Returns the model's text response.
|
|
7610
|
+
Use for semantic analysis, summarization, or reasoning about text chunks.
|
|
7611
|
+
Args:
|
|
7612
|
+
prompt: The question/instruction for the model
|
|
7613
|
+
context: Additional text context (max ~500K chars)
|
|
7614
|
+
Returns: Model's text response as a string
|
|
7615
|
+
"""
|
|
7616
|
+
sock_path = os.environ.get("OA_LLM_QUERY_SOCKET", "")
|
|
7617
|
+
if not sock_path:
|
|
7618
|
+
return "[llm_query unavailable: no IPC socket]"
|
|
7619
|
+
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
7620
|
+
try:
|
|
7621
|
+
sock.connect(sock_path)
|
|
7622
|
+
request = json.dumps({"prompt": str(prompt), "context": str(context)[:500000]})
|
|
7623
|
+
# Send length-prefixed message
|
|
7624
|
+
data = request.encode("utf-8")
|
|
7625
|
+
sock.sendall(len(data).to_bytes(4, "big") + data)
|
|
7626
|
+
# Read length-prefixed response
|
|
7627
|
+
length_bytes = b""
|
|
7628
|
+
while len(length_bytes) < 4:
|
|
7629
|
+
chunk = sock.recv(4 - len(length_bytes))
|
|
7630
|
+
if not chunk:
|
|
7631
|
+
return "[llm_query: connection closed]"
|
|
7632
|
+
length_bytes += chunk
|
|
7633
|
+
resp_len = int.from_bytes(length_bytes, "big")
|
|
7634
|
+
resp_data = b""
|
|
7635
|
+
while len(resp_data) < resp_len:
|
|
7636
|
+
chunk = sock.recv(min(resp_len - len(resp_data), 65536))
|
|
7637
|
+
if not chunk:
|
|
7638
|
+
break
|
|
7639
|
+
resp_data += chunk
|
|
7640
|
+
result = json.loads(resp_data.decode("utf-8"))
|
|
7641
|
+
if "error" in result:
|
|
7642
|
+
return f"[llm_query error: {result['error']}]"
|
|
7643
|
+
return result.get("response", "")
|
|
7644
|
+
except Exception as e:
|
|
7645
|
+
return f"[llm_query error: {e}]"
|
|
7646
|
+
finally:
|
|
7647
|
+
sock.close()
|
|
7648
|
+
|
|
7649
|
+
# Signal REPL ready
|
|
7650
|
+
print("__OA_REPL_READY__")
|
|
7651
|
+
`.trim();
|
|
7652
|
+
}
|
|
7653
|
+
// ── IPC Server (for llm_query bridge) ──────────────────────────────────
|
|
7654
|
+
async startIpcServer() {
|
|
7655
|
+
if (this.ipcServer)
|
|
7656
|
+
return;
|
|
7657
|
+
const sockId = randomBytes2(8).toString("hex");
|
|
7658
|
+
this.ipcPath = join18(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
|
|
7659
|
+
return new Promise((resolve32, reject) => {
|
|
7660
|
+
this.ipcServer = createServer((conn) => {
|
|
7661
|
+
let buffer = new Uint8Array(0);
|
|
7662
|
+
conn.on("data", (chunk) => {
|
|
7663
|
+
const combined = new Uint8Array(buffer.length + chunk.length);
|
|
7664
|
+
combined.set(buffer, 0);
|
|
7665
|
+
combined.set(chunk, buffer.length);
|
|
7666
|
+
buffer = combined;
|
|
7667
|
+
this.processIpcBuffer(conn, buffer).then((remaining) => {
|
|
7668
|
+
buffer = remaining;
|
|
7669
|
+
});
|
|
7670
|
+
});
|
|
7671
|
+
conn.on("error", () => {
|
|
7672
|
+
});
|
|
7673
|
+
});
|
|
7674
|
+
this.ipcServer.on("error", reject);
|
|
7675
|
+
this.ipcServer.listen(this.ipcPath, () => resolve32());
|
|
7676
|
+
});
|
|
7677
|
+
}
|
|
7678
|
+
async processIpcBuffer(conn, input) {
|
|
7679
|
+
let buffer = input;
|
|
7680
|
+
while (buffer.length >= 4) {
|
|
7681
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
7682
|
+
const msgLen = view.getUint32(0, false);
|
|
7683
|
+
if (buffer.length < 4 + msgLen)
|
|
7684
|
+
break;
|
|
7685
|
+
const msgData = new TextDecoder().decode(buffer.subarray(4, 4 + msgLen));
|
|
7686
|
+
buffer = buffer.subarray(4 + msgLen);
|
|
7687
|
+
let response;
|
|
7688
|
+
try {
|
|
7689
|
+
const req = JSON.parse(msgData);
|
|
7690
|
+
if (!this.llmQueryHandler) {
|
|
7691
|
+
response = { error: "llm_query handler not configured" };
|
|
7692
|
+
} else if (this.subCallCount >= this.maxSubCalls) {
|
|
7693
|
+
response = { error: `Sub-call limit reached (${this.maxSubCalls})` };
|
|
7694
|
+
} else {
|
|
7695
|
+
this.subCallCount++;
|
|
7696
|
+
const result = await this.llmQueryHandler(req.prompt, req.context);
|
|
7697
|
+
response = { response: result };
|
|
7698
|
+
}
|
|
7699
|
+
} catch (err) {
|
|
7700
|
+
response = { error: err instanceof Error ? err.message : String(err) };
|
|
7701
|
+
}
|
|
7702
|
+
const respBytes = new TextEncoder().encode(JSON.stringify(response));
|
|
7703
|
+
const header = new Uint8Array(4);
|
|
7704
|
+
new DataView(header.buffer).setUint32(0, respBytes.length, false);
|
|
7705
|
+
const packet = new Uint8Array(4 + respBytes.length);
|
|
7706
|
+
packet.set(header, 0);
|
|
7707
|
+
packet.set(respBytes, 4);
|
|
7708
|
+
try {
|
|
7709
|
+
conn.write(packet);
|
|
7710
|
+
} catch {
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
return buffer;
|
|
7714
|
+
}
|
|
7715
|
+
// ── Code execution ─────────────────────────────────────────────────────
|
|
7716
|
+
executeCode(code, isInit = false) {
|
|
7717
|
+
return new Promise((resolve32) => {
|
|
7718
|
+
if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
|
|
7719
|
+
resolve32({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
|
|
7720
|
+
return;
|
|
7721
|
+
}
|
|
7722
|
+
const sentinel = `__OA_SENTINEL_${randomBytes2(6).toString("hex")}__`;
|
|
7723
|
+
let stdout = "";
|
|
7724
|
+
let stderr = "";
|
|
7725
|
+
let resolved = false;
|
|
7726
|
+
const timeout = setTimeout(() => {
|
|
7727
|
+
if (!resolved) {
|
|
7728
|
+
resolved = true;
|
|
7729
|
+
resolve32({
|
|
7730
|
+
success: false,
|
|
7731
|
+
output: stdout || "Execution timed out",
|
|
7732
|
+
error: `Timeout after ${this.execTimeout / 1e3}s`,
|
|
7733
|
+
durationMs: this.execTimeout
|
|
7734
|
+
});
|
|
7735
|
+
}
|
|
7736
|
+
}, this.execTimeout);
|
|
7737
|
+
const onStdout = (data) => {
|
|
7738
|
+
const text = data.toString();
|
|
7739
|
+
stdout += text;
|
|
7740
|
+
if (stdout.includes(sentinel)) {
|
|
7741
|
+
cleanup();
|
|
7742
|
+
const cleanOutput = stdout.split(sentinel)[0].trim();
|
|
7743
|
+
if (isInit) {
|
|
7744
|
+
const ready = cleanOutput.includes("__OA_REPL_READY__");
|
|
7745
|
+
const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
|
|
7746
|
+
resolve32({
|
|
7747
|
+
success: ready,
|
|
7748
|
+
output: displayOutput || "REPL initialized",
|
|
7749
|
+
durationMs: 0
|
|
7750
|
+
});
|
|
7751
|
+
} else {
|
|
7752
|
+
resolve32({
|
|
7753
|
+
success: true,
|
|
7754
|
+
output: cleanOutput || "(no output)",
|
|
7755
|
+
durationMs: 0
|
|
7756
|
+
});
|
|
7757
|
+
}
|
|
7758
|
+
}
|
|
7759
|
+
if (stdout.length > 2e5) {
|
|
7760
|
+
cleanup();
|
|
7761
|
+
resolve32({
|
|
7762
|
+
success: true,
|
|
7763
|
+
output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
|
|
7764
|
+
durationMs: 0
|
|
7765
|
+
});
|
|
7766
|
+
}
|
|
7767
|
+
};
|
|
7768
|
+
const onStderr = (data) => {
|
|
7769
|
+
stderr += data.toString();
|
|
7770
|
+
if (stderr.length > 5e4) {
|
|
7771
|
+
stderr = stderr.slice(0, 5e4) + "\n[stderr truncated]";
|
|
7772
|
+
}
|
|
7773
|
+
};
|
|
7774
|
+
const cleanup = () => {
|
|
7775
|
+
if (resolved)
|
|
7776
|
+
return;
|
|
7777
|
+
resolved = true;
|
|
7778
|
+
clearTimeout(timeout);
|
|
7779
|
+
this.proc?.stdout?.removeListener("data", onStdout);
|
|
7780
|
+
this.proc?.stderr?.removeListener("data", onStderr);
|
|
7781
|
+
};
|
|
7782
|
+
this.proc.stdout.on("data", onStdout);
|
|
7783
|
+
this.proc.stderr.on("data", onStderr);
|
|
7784
|
+
const wrappedCode = `
|
|
7785
|
+
try:
|
|
7786
|
+
exec(${JSON.stringify(code)})
|
|
7787
|
+
except Exception as __oa_e:
|
|
7788
|
+
import traceback as __oa_tb
|
|
7789
|
+
print(f"Error: {__oa_e}")
|
|
7790
|
+
__oa_tb.print_exc()
|
|
7791
|
+
print("${sentinel}")
|
|
7792
|
+
`;
|
|
7793
|
+
this.proc.stdin.write(wrappedCode + "\n");
|
|
7794
|
+
});
|
|
7795
|
+
}
|
|
7796
|
+
// ── Cleanup ────────────────────────────────────────────────────────────
|
|
7797
|
+
async dispose() {
|
|
7798
|
+
if (this.proc && !this.proc.killed) {
|
|
7799
|
+
try {
|
|
7800
|
+
this.proc.stdin?.end();
|
|
7801
|
+
this.proc.kill("SIGTERM");
|
|
7802
|
+
} catch {
|
|
7803
|
+
}
|
|
7804
|
+
this.proc = null;
|
|
7805
|
+
}
|
|
7806
|
+
if (this.ipcServer) {
|
|
7807
|
+
this.ipcServer.close();
|
|
7808
|
+
this.ipcServer = null;
|
|
7809
|
+
}
|
|
7810
|
+
if (this.ipcPath) {
|
|
7811
|
+
try {
|
|
7812
|
+
unlinkSync2(this.ipcPath);
|
|
7813
|
+
} catch {
|
|
7814
|
+
}
|
|
7815
|
+
this.ipcPath = null;
|
|
7816
|
+
}
|
|
7817
|
+
this.subCallCount = 0;
|
|
7818
|
+
}
|
|
7819
|
+
};
|
|
7820
|
+
}
|
|
7821
|
+
});
|
|
7822
|
+
|
|
7514
7823
|
// packages/execution/dist/tools/structured-read.js
|
|
7515
7824
|
import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
|
|
7516
7825
|
import { resolve as resolve15, extname as extname5 } from "node:path";
|
|
@@ -7848,8 +8157,8 @@ ${parts.join("\n\n")}`,
|
|
|
7848
8157
|
|
|
7849
8158
|
// packages/execution/dist/tools/vision.js
|
|
7850
8159
|
import { readFileSync as readFileSync11, existsSync as existsSync14, statSync as statSync5 } from "node:fs";
|
|
7851
|
-
import { execSync as execSync11, spawn as
|
|
7852
|
-
import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as
|
|
8160
|
+
import { execSync as execSync11, spawn as spawn7 } from "node:child_process";
|
|
8161
|
+
import { resolve as resolve16, extname as extname6, basename as basename5, dirname as dirname6, join as join19 } from "node:path";
|
|
7853
8162
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7854
8163
|
async function probeStation(endpoint) {
|
|
7855
8164
|
try {
|
|
@@ -7864,7 +8173,7 @@ async function probeStation(endpoint) {
|
|
|
7864
8173
|
}
|
|
7865
8174
|
}
|
|
7866
8175
|
function findStationBinary() {
|
|
7867
|
-
const oaVenvPython =
|
|
8176
|
+
const oaVenvPython = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
|
|
7868
8177
|
if (existsSync14(oaVenvPython)) {
|
|
7869
8178
|
try {
|
|
7870
8179
|
execSync11(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
|
|
@@ -7872,7 +8181,7 @@ function findStationBinary() {
|
|
|
7872
8181
|
} catch {
|
|
7873
8182
|
}
|
|
7874
8183
|
}
|
|
7875
|
-
const oaVenvBin =
|
|
8184
|
+
const oaVenvBin = join19(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
|
|
7876
8185
|
if (existsSync14(oaVenvBin))
|
|
7877
8186
|
return oaVenvBin;
|
|
7878
8187
|
const thisDir = dirname6(fileURLToPath2(import.meta.url));
|
|
@@ -7906,7 +8215,7 @@ async function autoLaunchStation(port = 2020) {
|
|
|
7906
8215
|
if (!existsSync14(launcherScript))
|
|
7907
8216
|
return false;
|
|
7908
8217
|
return new Promise((resolvePromise) => {
|
|
7909
|
-
const child =
|
|
8218
|
+
const child = spawn7(pythonBin, [launcherScript, "--port", String(port)], {
|
|
7910
8219
|
stdio: ["ignore", "pipe", "pipe"],
|
|
7911
8220
|
detached: true
|
|
7912
8221
|
});
|
|
@@ -8223,8 +8532,8 @@ ${response}`, durationMs: performance.now() - start };
|
|
|
8223
8532
|
// packages/execution/dist/tools/desktop-click.js
|
|
8224
8533
|
import { readFileSync as readFileSync12, existsSync as existsSync15 } from "node:fs";
|
|
8225
8534
|
import { execSync as execSync12 } from "node:child_process";
|
|
8226
|
-
import { tmpdir as
|
|
8227
|
-
import { join as
|
|
8535
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
8536
|
+
import { join as join20, dirname as dirname7 } from "node:path";
|
|
8228
8537
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8229
8538
|
function hasCommand2(cmd) {
|
|
8230
8539
|
try {
|
|
@@ -8348,7 +8657,7 @@ for i in range(${clicks}):
|
|
|
8348
8657
|
} catch {
|
|
8349
8658
|
}
|
|
8350
8659
|
try {
|
|
8351
|
-
const venvPy =
|
|
8660
|
+
const venvPy = join20(__dirname2, "../../../../.moondream-venv/bin/python");
|
|
8352
8661
|
execSync12(`DISPLAY=:0 ${JSON.stringify(venvPy)} -c "${pyScript}"`, { stdio: "pipe", timeout: 5e3 });
|
|
8353
8662
|
return;
|
|
8354
8663
|
} catch {
|
|
@@ -8440,7 +8749,7 @@ var init_desktop_click = __esm({
|
|
|
8440
8749
|
if (delayMs > 0) {
|
|
8441
8750
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
8442
8751
|
}
|
|
8443
|
-
const screenshotPath =
|
|
8752
|
+
const screenshotPath = join20(tmpdir4(), `oa-desktop-click-${Date.now()}.png`);
|
|
8444
8753
|
captureScreenshot(screenshotPath);
|
|
8445
8754
|
const dims = getImageDimensions2(screenshotPath);
|
|
8446
8755
|
if (!dims) {
|
|
@@ -8615,7 +8924,7 @@ Screenshot: ${screenshotPath}`,
|
|
|
8615
8924
|
if (delayMs > 0) {
|
|
8616
8925
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
8617
8926
|
}
|
|
8618
|
-
const screenshotPath =
|
|
8927
|
+
const screenshotPath = join20(tmpdir4(), `oa-desktop-describe-${Date.now()}.png`);
|
|
8619
8928
|
captureScreenshot(screenshotPath);
|
|
8620
8929
|
const dims = getImageDimensions2(screenshotPath);
|
|
8621
8930
|
const imageBuffer = readFileSync12(screenshotPath);
|
|
@@ -8853,10 +9162,10 @@ Language: ${language}
|
|
|
8853
9162
|
});
|
|
8854
9163
|
|
|
8855
9164
|
// packages/execution/dist/tools/pdf-to-text.js
|
|
8856
|
-
import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as
|
|
8857
|
-
import { resolve as resolve18, basename as basename7, join as
|
|
9165
|
+
import { existsSync as existsSync17, statSync as statSync7, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "node:fs";
|
|
9166
|
+
import { resolve as resolve18, basename as basename7, join as join21 } from "node:path";
|
|
8858
9167
|
import { execSync as execSync14 } from "node:child_process";
|
|
8859
|
-
import { tmpdir as
|
|
9168
|
+
import { tmpdir as tmpdir5 } from "node:os";
|
|
8860
9169
|
var PdfToTextTool;
|
|
8861
9170
|
var init_pdf_to_text = __esm({
|
|
8862
9171
|
"packages/execution/dist/tools/pdf-to-text.js"() {
|
|
@@ -9008,7 +9317,7 @@ ${text}`,
|
|
|
9008
9317
|
if (!ocrCheck.available || !tesCheck.available || !gsCheck.available) {
|
|
9009
9318
|
return null;
|
|
9010
9319
|
}
|
|
9011
|
-
const tmpPdf =
|
|
9320
|
+
const tmpPdf = join21(tmpdir5(), `oa-ocr-${Date.now()}.pdf`);
|
|
9012
9321
|
try {
|
|
9013
9322
|
const ocrCmd = `ocrmypdf -l ${language} --skip-text ${JSON.stringify(inputPath)} ${JSON.stringify(tmpPdf)}`;
|
|
9014
9323
|
execSync14(ocrCmd, { stdio: "pipe", timeout: 6e5 });
|
|
@@ -9028,7 +9337,7 @@ ${text}`,
|
|
|
9028
9337
|
return null;
|
|
9029
9338
|
} finally {
|
|
9030
9339
|
try {
|
|
9031
|
-
|
|
9340
|
+
unlinkSync3(tmpPdf);
|
|
9032
9341
|
} catch {
|
|
9033
9342
|
}
|
|
9034
9343
|
}
|
|
@@ -9039,10 +9348,10 @@ ${text}`,
|
|
|
9039
9348
|
|
|
9040
9349
|
// packages/execution/dist/tools/ocr-image-advanced.js
|
|
9041
9350
|
import { existsSync as existsSync18, statSync as statSync8 } from "node:fs";
|
|
9042
|
-
import { resolve as resolve19, basename as basename8, dirname as dirname8, join as
|
|
9351
|
+
import { resolve as resolve19, basename as basename8, dirname as dirname8, join as join22 } from "node:path";
|
|
9043
9352
|
import { execSync as execSync15 } from "node:child_process";
|
|
9044
9353
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
9045
|
-
import { homedir as homedir7, tmpdir as
|
|
9354
|
+
import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
|
|
9046
9355
|
function findOcrScript() {
|
|
9047
9356
|
const thisDir = dirname8(fileURLToPath4(import.meta.url));
|
|
9048
9357
|
const devPath3 = resolve19(thisDir, "../../scripts/ocr-advanced.py");
|
|
@@ -9057,7 +9366,7 @@ function findOcrScript() {
|
|
|
9057
9366
|
return null;
|
|
9058
9367
|
}
|
|
9059
9368
|
function findPython() {
|
|
9060
|
-
const venvPython =
|
|
9369
|
+
const venvPython = join22(homedir7(), ".open-agents", "venv", "bin", "python");
|
|
9061
9370
|
if (existsSync18(venvPython)) {
|
|
9062
9371
|
try {
|
|
9063
9372
|
execSync15(`${JSON.stringify(venvPython)} -c "import cv2, pytesseract, numpy, PIL"`, {
|
|
@@ -9203,7 +9512,7 @@ var init_ocr_image_advanced = __esm({
|
|
|
9203
9512
|
cmdParts.push("--output-dir", JSON.stringify(resolve19(this.workingDir, outputDir)));
|
|
9204
9513
|
let debugDir;
|
|
9205
9514
|
if (debug) {
|
|
9206
|
-
debugDir =
|
|
9515
|
+
debugDir = join22(tmpdir6(), `oa-ocr-debug-${Date.now()}`);
|
|
9207
9516
|
cmdParts.push("--debug-dir", debugDir);
|
|
9208
9517
|
}
|
|
9209
9518
|
try {
|
|
@@ -9302,7 +9611,7 @@ var init_ocr_image_advanced = __esm({
|
|
|
9302
9611
|
if (region) {
|
|
9303
9612
|
try {
|
|
9304
9613
|
const [x, y, w, h] = region.split(",").map(Number);
|
|
9305
|
-
const croppedPath =
|
|
9614
|
+
const croppedPath = join22(tmpdir6(), `oa-ocr-crop-${Date.now()}.png`);
|
|
9306
9615
|
execSync15(`convert ${JSON.stringify(imagePath)} -crop ${w}x${h}+${x}+${y} +repage ${JSON.stringify(croppedPath)}`, { stdio: "pipe", timeout: 1e4 });
|
|
9307
9616
|
inputPath = croppedPath;
|
|
9308
9617
|
} catch {
|
|
@@ -9341,20 +9650,20 @@ Note: Advanced Python pipeline not available \u2014 install pytesseract, opencv-
|
|
|
9341
9650
|
});
|
|
9342
9651
|
|
|
9343
9652
|
// packages/execution/dist/tools/browser-action.js
|
|
9344
|
-
import { execSync as execSync16, spawn as
|
|
9653
|
+
import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
|
|
9345
9654
|
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
|
|
9346
|
-
import { join as
|
|
9655
|
+
import { join as join23, dirname as dirname9 } from "node:path";
|
|
9347
9656
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
9348
9657
|
function findScrapeScript() {
|
|
9349
9658
|
const candidates = [
|
|
9350
9659
|
// Published npm package: dist/scripts/web_scrape.py
|
|
9351
|
-
|
|
9660
|
+
join23(__dirname3, "scripts", "web_scrape.py"),
|
|
9352
9661
|
// Published npm package (from node_modules): node_modules/open-agents-ai/dist/scripts/
|
|
9353
|
-
|
|
9662
|
+
join23(__dirname3, "..", "node_modules", "open-agents-ai", "dist", "scripts", "web_scrape.py"),
|
|
9354
9663
|
// Dev monorepo: packages/execution/src/tools/../../scripts/
|
|
9355
|
-
|
|
9664
|
+
join23(__dirname3, "..", "..", "scripts", "web_scrape.py"),
|
|
9356
9665
|
// Dev monorepo alt: packages/execution/scripts/
|
|
9357
|
-
|
|
9666
|
+
join23(__dirname3, "..", "scripts", "web_scrape.py")
|
|
9358
9667
|
];
|
|
9359
9668
|
return candidates.find((p) => existsSync19(p)) || candidates[0];
|
|
9360
9669
|
}
|
|
@@ -9389,7 +9698,7 @@ async function launchService() {
|
|
|
9389
9698
|
if (!existsSync19(SCRAPE_SCRIPT)) {
|
|
9390
9699
|
return `Scrape service script not found at ${SCRAPE_SCRIPT}`;
|
|
9391
9700
|
}
|
|
9392
|
-
serviceProcess =
|
|
9701
|
+
serviceProcess = spawn8(python, [SCRAPE_SCRIPT], {
|
|
9393
9702
|
stdio: "ignore",
|
|
9394
9703
|
detached: true,
|
|
9395
9704
|
env: {
|
|
@@ -9607,9 +9916,9 @@ var init_browser_action = __esm({
|
|
|
9607
9916
|
});
|
|
9608
9917
|
|
|
9609
9918
|
// packages/execution/dist/tools/autoresearch.js
|
|
9610
|
-
import { execSync as execSync17, spawn as
|
|
9919
|
+
import { execSync as execSync17, spawn as spawn9 } from "node:child_process";
|
|
9611
9920
|
import { existsSync as existsSync20, readFileSync as readFileSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, appendFileSync, copyFileSync } from "node:fs";
|
|
9612
|
-
import { join as
|
|
9921
|
+
import { join as join24, resolve as resolve20, dirname as dirname10 } from "node:path";
|
|
9613
9922
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
9614
9923
|
function findAutoresearchScript(scriptName) {
|
|
9615
9924
|
const thisDir = dirname10(fileURLToPath6(import.meta.url));
|
|
@@ -9711,7 +10020,7 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
|
|
|
9711
10020
|
async execute(args) {
|
|
9712
10021
|
const start = Date.now();
|
|
9713
10022
|
const action = String(args["action"] ?? "status");
|
|
9714
|
-
const workspacePath = String(args["workspace"] ??
|
|
10023
|
+
const workspacePath = String(args["workspace"] ?? join24(this.repoRoot, ".oa", "autoresearch"));
|
|
9715
10024
|
try {
|
|
9716
10025
|
switch (action) {
|
|
9717
10026
|
case "setup":
|
|
@@ -9752,13 +10061,13 @@ Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
|
|
|
9752
10061
|
const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
|
|
9753
10062
|
const trainScript = findAutoresearchScript("autoresearch-train.py");
|
|
9754
10063
|
if (prepareScript) {
|
|
9755
|
-
copyFileSync(prepareScript,
|
|
10064
|
+
copyFileSync(prepareScript, join24(workspace, "prepare.py"));
|
|
9756
10065
|
output.push("Copied prepare.py template");
|
|
9757
10066
|
} else {
|
|
9758
10067
|
return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
|
|
9759
10068
|
}
|
|
9760
10069
|
if (trainScript) {
|
|
9761
|
-
copyFileSync(trainScript,
|
|
10070
|
+
copyFileSync(trainScript, join24(workspace, "train.py"));
|
|
9762
10071
|
output.push("Copied train.py template");
|
|
9763
10072
|
} else {
|
|
9764
10073
|
return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
|
|
@@ -9790,7 +10099,7 @@ name = "pytorch-cu128"
|
|
|
9790
10099
|
url = "https://download.pytorch.org/whl/cu128"
|
|
9791
10100
|
explicit = true
|
|
9792
10101
|
`;
|
|
9793
|
-
writeFileSync6(
|
|
10102
|
+
writeFileSync6(join24(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
|
|
9794
10103
|
output.push("Created pyproject.toml");
|
|
9795
10104
|
try {
|
|
9796
10105
|
execSync17("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
@@ -9832,7 +10141,7 @@ explicit = true
|
|
|
9832
10141
|
const e = err;
|
|
9833
10142
|
output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
|
|
9834
10143
|
}
|
|
9835
|
-
const tsvPath =
|
|
10144
|
+
const tsvPath = join24(workspace, "results.tsv");
|
|
9836
10145
|
if (!existsSync20(tsvPath)) {
|
|
9837
10146
|
writeFileSync6(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
|
|
9838
10147
|
output.push("Created results.tsv");
|
|
@@ -9854,10 +10163,10 @@ Next steps:
|
|
|
9854
10163
|
}
|
|
9855
10164
|
// ── Run experiment ─────────────────────────────────────────────────────
|
|
9856
10165
|
async run(workspace, args, start) {
|
|
9857
|
-
if (!existsSync20(
|
|
10166
|
+
if (!existsSync20(join24(workspace, "train.py"))) {
|
|
9858
10167
|
return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9859
10168
|
}
|
|
9860
|
-
if (!existsSync20(
|
|
10169
|
+
if (!existsSync20(join24(workspace, ".venv")) && existsSync20(join24(workspace, "pyproject.toml"))) {
|
|
9861
10170
|
try {
|
|
9862
10171
|
execSync17("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
|
|
9863
10172
|
} catch {
|
|
@@ -9865,9 +10174,9 @@ Next steps:
|
|
|
9865
10174
|
}
|
|
9866
10175
|
const timeoutMin = Number(args["timeout_minutes"] ?? 10);
|
|
9867
10176
|
const timeoutMs = timeoutMin * 60 * 1e3;
|
|
9868
|
-
const logPath =
|
|
10177
|
+
const logPath = join24(workspace, "run.log");
|
|
9869
10178
|
return new Promise((resolveResult) => {
|
|
9870
|
-
const proc =
|
|
10179
|
+
const proc = spawn9("uv", ["run", "train.py"], {
|
|
9871
10180
|
cwd: workspace,
|
|
9872
10181
|
timeout: timeoutMs,
|
|
9873
10182
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -9936,7 +10245,7 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9936
10245
|
return;
|
|
9937
10246
|
}
|
|
9938
10247
|
try {
|
|
9939
|
-
writeFileSync6(
|
|
10248
|
+
writeFileSync6(join24(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
|
|
9940
10249
|
} catch {
|
|
9941
10250
|
}
|
|
9942
10251
|
const memGB = (result.peak_vram_mb / 1024).toFixed(1);
|
|
@@ -9972,7 +10281,7 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9972
10281
|
}
|
|
9973
10282
|
// ── Results ────────────────────────────────────────────────────────────
|
|
9974
10283
|
getResults(workspace, start) {
|
|
9975
|
-
const tsvPath =
|
|
10284
|
+
const tsvPath = join24(workspace, "results.tsv");
|
|
9976
10285
|
if (!existsSync20(tsvPath)) {
|
|
9977
10286
|
return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9978
10287
|
}
|
|
@@ -9999,7 +10308,7 @@ ${fullLog.slice(-2e3)}`,
|
|
|
9999
10308
|
// ── Status ─────────────────────────────────────────────────────────────
|
|
10000
10309
|
getStatus(workspace, start) {
|
|
10001
10310
|
const output = [];
|
|
10002
|
-
if (!existsSync20(
|
|
10311
|
+
if (!existsSync20(join24(workspace, "train.py"))) {
|
|
10003
10312
|
return {
|
|
10004
10313
|
success: true,
|
|
10005
10314
|
output: `Autoresearch workspace not initialized at ${workspace}.
|
|
@@ -10022,7 +10331,7 @@ Run autoresearch(action="setup") to begin.`,
|
|
|
10022
10331
|
} catch {
|
|
10023
10332
|
output.push("GPU: not detected");
|
|
10024
10333
|
}
|
|
10025
|
-
const lastResultPath =
|
|
10334
|
+
const lastResultPath = join24(workspace, ".last-result.json");
|
|
10026
10335
|
if (existsSync20(lastResultPath)) {
|
|
10027
10336
|
try {
|
|
10028
10337
|
const last = JSON.parse(readFileSync15(lastResultPath, "utf-8"));
|
|
@@ -10030,20 +10339,20 @@ Run autoresearch(action="setup") to begin.`,
|
|
|
10030
10339
|
} catch {
|
|
10031
10340
|
}
|
|
10032
10341
|
}
|
|
10033
|
-
const tsvPath =
|
|
10342
|
+
const tsvPath = join24(workspace, "results.tsv");
|
|
10034
10343
|
if (existsSync20(tsvPath)) {
|
|
10035
10344
|
const lines = readFileSync15(tsvPath, "utf-8").trim().split("\n");
|
|
10036
10345
|
output.push(`Experiments recorded: ${lines.length - 1}`);
|
|
10037
10346
|
}
|
|
10038
|
-
const cacheDir =
|
|
10347
|
+
const cacheDir = join24(process.env["HOME"] ?? "~", ".cache", "autoresearch");
|
|
10039
10348
|
output.push(`Data cache: ${existsSync20(cacheDir) ? "present" : "not found"} (${cacheDir})`);
|
|
10040
10349
|
return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
|
|
10041
10350
|
}
|
|
10042
10351
|
// ── Keep / Discard ─────────────────────────────────────────────────────
|
|
10043
10352
|
keepExperiment(workspace, args, start) {
|
|
10044
10353
|
const desc = String(args["description"] ?? "experiment");
|
|
10045
|
-
const tsvPath =
|
|
10046
|
-
const lastResultPath =
|
|
10354
|
+
const tsvPath = join24(workspace, "results.tsv");
|
|
10355
|
+
const lastResultPath = join24(workspace, ".last-result.json");
|
|
10047
10356
|
let valBpb = args["val_bpb"];
|
|
10048
10357
|
let memGb = args["memory_gb"];
|
|
10049
10358
|
if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
|
|
@@ -10081,8 +10390,8 @@ Branch advanced. Ready for next experiment.`,
|
|
|
10081
10390
|
}
|
|
10082
10391
|
discardExperiment(workspace, args, start) {
|
|
10083
10392
|
const desc = String(args["description"] ?? "experiment");
|
|
10084
|
-
const tsvPath =
|
|
10085
|
-
const lastResultPath =
|
|
10393
|
+
const tsvPath = join24(workspace, "results.tsv");
|
|
10394
|
+
const lastResultPath = join24(workspace, ".last-result.json");
|
|
10086
10395
|
let valBpb = args["val_bpb"];
|
|
10087
10396
|
let memGb = args["memory_gb"];
|
|
10088
10397
|
if ((valBpb === void 0 || memGb === void 0) && existsSync20(lastResultPath)) {
|
|
@@ -10129,8 +10438,8 @@ train.py reverted to last kept state. Ready for next experiment.`,
|
|
|
10129
10438
|
// packages/execution/dist/tools/scheduler.js
|
|
10130
10439
|
import { execSync as execSync18, exec as execCb } from "node:child_process";
|
|
10131
10440
|
import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
|
|
10132
|
-
import { resolve as resolve21, join as
|
|
10133
|
-
import { randomBytes as
|
|
10441
|
+
import { resolve as resolve21, join as join25 } from "node:path";
|
|
10442
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
10134
10443
|
function isValidCron(expr) {
|
|
10135
10444
|
const parts = expr.trim().split(/\s+/);
|
|
10136
10445
|
if (parts.length !== 5)
|
|
@@ -10213,7 +10522,7 @@ function installCronJob(task, workingDir) {
|
|
|
10213
10522
|
const lines = getCurrentCrontab();
|
|
10214
10523
|
const oaBin = findOaBinary();
|
|
10215
10524
|
const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
|
|
10216
|
-
const logFile =
|
|
10525
|
+
const logFile = join25(logDir, `${task.id}.log`);
|
|
10217
10526
|
const storeFile = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
|
|
10218
10527
|
const taskEscaped = task.task.replace(/'/g, "'\\''");
|
|
10219
10528
|
const taskId = task.id;
|
|
@@ -10255,9 +10564,9 @@ async function loadStore(workingDir) {
|
|
|
10255
10564
|
async function saveStore(workingDir, store) {
|
|
10256
10565
|
const dir = resolve21(workingDir, ".oa", "scheduled");
|
|
10257
10566
|
await mkdir4(dir, { recursive: true });
|
|
10258
|
-
await mkdir4(
|
|
10567
|
+
await mkdir4(join25(dir, "logs"), { recursive: true });
|
|
10259
10568
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10260
|
-
await writeFile8(
|
|
10569
|
+
await writeFile8(join25(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
10261
10570
|
}
|
|
10262
10571
|
var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
|
|
10263
10572
|
var init_scheduler = __esm({
|
|
@@ -10368,7 +10677,7 @@ var init_scheduler = __esm({
|
|
|
10368
10677
|
durationMs: performance.now() - start
|
|
10369
10678
|
};
|
|
10370
10679
|
}
|
|
10371
|
-
const id = `sched-${
|
|
10680
|
+
const id = `sched-${randomBytes3(4).toString("hex")}`;
|
|
10372
10681
|
const oneShot = Boolean(args["one_shot"]);
|
|
10373
10682
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
|
|
10374
10683
|
const newTask = {
|
|
@@ -10491,8 +10800,8 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
10491
10800
|
|
|
10492
10801
|
// packages/execution/dist/tools/reminder.js
|
|
10493
10802
|
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
|
|
10494
|
-
import { resolve as resolve22, join as
|
|
10495
|
-
import { randomBytes as
|
|
10803
|
+
import { resolve as resolve22, join as join26 } from "node:path";
|
|
10804
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
10496
10805
|
function parseDueTime(due) {
|
|
10497
10806
|
const lower = due.toLowerCase().trim();
|
|
10498
10807
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -10543,7 +10852,7 @@ function parseDueTime(due) {
|
|
|
10543
10852
|
async function getStorePath(workingDir) {
|
|
10544
10853
|
const dir = resolve22(workingDir, ".oa", "scheduled");
|
|
10545
10854
|
await mkdir5(dir, { recursive: true });
|
|
10546
|
-
return
|
|
10855
|
+
return join26(dir, STORE_FILE);
|
|
10547
10856
|
}
|
|
10548
10857
|
async function loadReminderStore(workingDir) {
|
|
10549
10858
|
const storePath = await getStorePath(workingDir);
|
|
@@ -10689,7 +10998,7 @@ var init_reminder = __esm({
|
|
|
10689
10998
|
dueAt = parsed.isoDate;
|
|
10690
10999
|
dueDescription = parsed.description;
|
|
10691
11000
|
}
|
|
10692
|
-
const id = `rem-${
|
|
11001
|
+
const id = `rem-${randomBytes4(4).toString("hex")}`;
|
|
10693
11002
|
const entry = {
|
|
10694
11003
|
id,
|
|
10695
11004
|
message,
|
|
@@ -10804,8 +11113,8 @@ var init_reminder = __esm({
|
|
|
10804
11113
|
|
|
10805
11114
|
// packages/execution/dist/tools/agenda.js
|
|
10806
11115
|
import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
|
|
10807
|
-
import { resolve as resolve23, join as
|
|
10808
|
-
import { randomBytes as
|
|
11116
|
+
import { resolve as resolve23, join as join27 } from "node:path";
|
|
11117
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
10809
11118
|
async function loadAttentionStore(workingDir) {
|
|
10810
11119
|
const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
|
|
10811
11120
|
try {
|
|
@@ -10819,7 +11128,7 @@ async function saveAttentionStore(workingDir, store) {
|
|
|
10819
11128
|
const dir = resolve23(workingDir, ".oa", "scheduled");
|
|
10820
11129
|
await mkdir6(dir, { recursive: true });
|
|
10821
11130
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10822
|
-
await writeFile10(
|
|
11131
|
+
await writeFile10(join27(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
10823
11132
|
}
|
|
10824
11133
|
async function getActiveAttentionItems(workingDir) {
|
|
10825
11134
|
const store = await loadAttentionStore(workingDir);
|
|
@@ -11008,7 +11317,7 @@ ${sections.join("\n")}`,
|
|
|
11008
11317
|
expiresAt = target.toISOString();
|
|
11009
11318
|
}
|
|
11010
11319
|
}
|
|
11011
|
-
const id = `attn-${
|
|
11320
|
+
const id = `attn-${randomBytes5(4).toString("hex")}`;
|
|
11012
11321
|
const item = {
|
|
11013
11322
|
id,
|
|
11014
11323
|
title,
|
|
@@ -11127,9 +11436,9 @@ ${sections.join("\n")}`,
|
|
|
11127
11436
|
});
|
|
11128
11437
|
|
|
11129
11438
|
// packages/execution/dist/tools/opencode.js
|
|
11130
|
-
import { execSync as execSync19, spawn as
|
|
11439
|
+
import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
|
|
11131
11440
|
import { existsSync as existsSync21 } from "node:fs";
|
|
11132
|
-
import { join as
|
|
11441
|
+
import { join as join28, resolve as resolve24 } from "node:path";
|
|
11133
11442
|
function findOpencode() {
|
|
11134
11443
|
for (const cmd of ["opencode"]) {
|
|
11135
11444
|
try {
|
|
@@ -11141,8 +11450,8 @@ function findOpencode() {
|
|
|
11141
11450
|
}
|
|
11142
11451
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
11143
11452
|
const candidates = [
|
|
11144
|
-
|
|
11145
|
-
|
|
11453
|
+
join28(homeDir, ".opencode", "bin", "opencode"),
|
|
11454
|
+
join28(homeDir, "bin", "opencode"),
|
|
11146
11455
|
"/usr/local/bin/opencode"
|
|
11147
11456
|
];
|
|
11148
11457
|
for (const p of candidates) {
|
|
@@ -11315,7 +11624,7 @@ var init_opencode = __esm({
|
|
|
11315
11624
|
let output = "";
|
|
11316
11625
|
const maxOutput = 5e5;
|
|
11317
11626
|
let timedOut = false;
|
|
11318
|
-
const child =
|
|
11627
|
+
const child = spawn10(binary, cmdArgs, {
|
|
11319
11628
|
cwd: dir,
|
|
11320
11629
|
env: { ...process.env, CI: "true", NONINTERACTIVE: "1" },
|
|
11321
11630
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -11401,9 +11710,9 @@ var init_opencode = __esm({
|
|
|
11401
11710
|
});
|
|
11402
11711
|
|
|
11403
11712
|
// packages/execution/dist/tools/factory.js
|
|
11404
|
-
import { execSync as execSync20, spawn as
|
|
11713
|
+
import { execSync as execSync20, spawn as spawn11 } from "node:child_process";
|
|
11405
11714
|
import { existsSync as existsSync22 } from "node:fs";
|
|
11406
|
-
import { join as
|
|
11715
|
+
import { join as join29 } from "node:path";
|
|
11407
11716
|
function findDroid() {
|
|
11408
11717
|
for (const cmd of ["droid"]) {
|
|
11409
11718
|
try {
|
|
@@ -11415,8 +11724,8 @@ function findDroid() {
|
|
|
11415
11724
|
}
|
|
11416
11725
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
11417
11726
|
const candidates = [
|
|
11418
|
-
|
|
11419
|
-
|
|
11727
|
+
join29(homeDir, ".factory", "bin", "droid"),
|
|
11728
|
+
join29(homeDir, "bin", "droid"),
|
|
11420
11729
|
"/usr/local/bin/droid"
|
|
11421
11730
|
];
|
|
11422
11731
|
for (const p of candidates) {
|
|
@@ -11620,7 +11929,7 @@ var init_factory = __esm({
|
|
|
11620
11929
|
let output = "";
|
|
11621
11930
|
const maxOutput = 5e5;
|
|
11622
11931
|
let timedOut = false;
|
|
11623
|
-
const child =
|
|
11932
|
+
const child = spawn11(binary, cmdArgs, {
|
|
11624
11933
|
cwd: dir,
|
|
11625
11934
|
env: { ...process.env },
|
|
11626
11935
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -11712,8 +12021,8 @@ var init_factory = __esm({
|
|
|
11712
12021
|
// packages/execution/dist/tools/cron-agent.js
|
|
11713
12022
|
import { execSync as execSync21 } from "node:child_process";
|
|
11714
12023
|
import { readFile as readFile12, writeFile as writeFile11, mkdir as mkdir7 } from "node:fs/promises";
|
|
11715
|
-
import { resolve as resolve25, join as
|
|
11716
|
-
import { randomBytes as
|
|
12024
|
+
import { resolve as resolve25, join as join30 } from "node:path";
|
|
12025
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
11717
12026
|
function isValidCron2(expr) {
|
|
11718
12027
|
const parts = expr.trim().split(/\s+/);
|
|
11719
12028
|
if (parts.length !== 5)
|
|
@@ -11798,7 +12107,7 @@ function installCronAgentJob(job, workingDir) {
|
|
|
11798
12107
|
const lines = getCurrentCrontab2();
|
|
11799
12108
|
const oaBin = findOaBinary2();
|
|
11800
12109
|
const logDir = resolve25(workingDir, ".oa", "cron-agents", "logs");
|
|
11801
|
-
const logFile =
|
|
12110
|
+
const logFile = join30(logDir, `${job.id}.log`);
|
|
11802
12111
|
const storeFile = resolve25(workingDir, ".oa", "cron-agents", "store.json");
|
|
11803
12112
|
const taskEscaped = job.task.replace(/'/g, "'\\''");
|
|
11804
12113
|
const jobId = job.id;
|
|
@@ -11837,9 +12146,9 @@ async function loadStore2(workingDir) {
|
|
|
11837
12146
|
async function saveStore2(workingDir, store) {
|
|
11838
12147
|
const dir = resolve25(workingDir, ".oa", "cron-agents");
|
|
11839
12148
|
await mkdir7(dir, { recursive: true });
|
|
11840
|
-
await mkdir7(
|
|
12149
|
+
await mkdir7(join30(dir, "logs"), { recursive: true });
|
|
11841
12150
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11842
|
-
await writeFile11(
|
|
12151
|
+
await writeFile11(join30(dir, "store.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
11843
12152
|
}
|
|
11844
12153
|
var LONG_HORIZON_PRESETS, CRON_AGENT_MARKER, CronAgentTool;
|
|
11845
12154
|
var init_cron_agent = __esm({
|
|
@@ -11973,7 +12282,7 @@ var init_cron_agent = __esm({
|
|
|
11973
12282
|
durationMs: performance.now() - start
|
|
11974
12283
|
};
|
|
11975
12284
|
}
|
|
11976
|
-
const id = `cron-${
|
|
12285
|
+
const id = `cron-${randomBytes6(4).toString("hex")}`;
|
|
11977
12286
|
const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
|
|
11978
12287
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
|
|
11979
12288
|
const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
|
|
@@ -12177,9 +12486,9 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
12177
12486
|
// packages/execution/dist/tools/nexus.js
|
|
12178
12487
|
import { readFile as readFile13, writeFile as writeFile12, mkdir as mkdir8, chmod, unlink, readdir as readdir3, open as fsOpen } from "node:fs/promises";
|
|
12179
12488
|
import { existsSync as existsSync23, readFileSync as readFileSync16, watch as fsWatchLocal } from "node:fs";
|
|
12180
|
-
import { resolve as resolve26, join as
|
|
12181
|
-
import { randomBytes as
|
|
12182
|
-
import { execSync as execSync22, spawn as
|
|
12489
|
+
import { resolve as resolve26, join as join31 } from "node:path";
|
|
12490
|
+
import { randomBytes as randomBytes7, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
|
|
12491
|
+
import { execSync as execSync22, spawn as spawn12 } from "node:child_process";
|
|
12183
12492
|
import { hostname, userInfo } from "node:os";
|
|
12184
12493
|
function containsKeyMaterial(input) {
|
|
12185
12494
|
for (const pattern of KEY_PATTERNS) {
|
|
@@ -14270,7 +14579,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14270
14579
|
// Daemon management
|
|
14271
14580
|
// =========================================================================
|
|
14272
14581
|
getDaemonPid() {
|
|
14273
|
-
const pidFile =
|
|
14582
|
+
const pidFile = join31(this.nexusDir, "daemon.pid");
|
|
14274
14583
|
if (!existsSync23(pidFile))
|
|
14275
14584
|
return null;
|
|
14276
14585
|
try {
|
|
@@ -14295,9 +14604,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14295
14604
|
if (!pid)
|
|
14296
14605
|
throw new Error("Nexus daemon not running. Use action 'connect' first.");
|
|
14297
14606
|
}
|
|
14298
|
-
const cmdId =
|
|
14299
|
-
const cmdFile =
|
|
14300
|
-
const respFile =
|
|
14607
|
+
const cmdId = randomBytes7(8).toString("hex");
|
|
14608
|
+
const cmdFile = join31(this.nexusDir, "cmd.json");
|
|
14609
|
+
const respFile = join31(this.nexusDir, "resp.json");
|
|
14301
14610
|
if (existsSync23(respFile))
|
|
14302
14611
|
await unlink(respFile).catch(() => {
|
|
14303
14612
|
});
|
|
@@ -14381,7 +14690,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14381
14690
|
const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
|
|
14382
14691
|
const existingPid = this.getDaemonPid();
|
|
14383
14692
|
if (existingPid) {
|
|
14384
|
-
const daemonPath2 =
|
|
14693
|
+
const daemonPath2 = join31(this.nexusDir, "nexus-daemon.mjs");
|
|
14385
14694
|
let needsRestart = true;
|
|
14386
14695
|
if (existsSync23(daemonPath2)) {
|
|
14387
14696
|
try {
|
|
@@ -14405,13 +14714,13 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14405
14714
|
} catch {
|
|
14406
14715
|
}
|
|
14407
14716
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
14408
|
-
const p =
|
|
14717
|
+
const p = join31(this.nexusDir, f);
|
|
14409
14718
|
if (existsSync23(p))
|
|
14410
14719
|
await unlink(p).catch(() => {
|
|
14411
14720
|
});
|
|
14412
14721
|
}
|
|
14413
14722
|
} else {
|
|
14414
|
-
const statusFile2 =
|
|
14723
|
+
const statusFile2 = join31(this.nexusDir, "status.json");
|
|
14415
14724
|
if (existsSync23(statusFile2)) {
|
|
14416
14725
|
try {
|
|
14417
14726
|
const status = JSON.parse(await readFile13(statusFile2, "utf8"));
|
|
@@ -14430,7 +14739,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14430
14739
|
}
|
|
14431
14740
|
}
|
|
14432
14741
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
14433
|
-
const p =
|
|
14742
|
+
const p = join31(this.nexusDir, f);
|
|
14434
14743
|
if (existsSync23(p))
|
|
14435
14744
|
await unlink(p).catch(() => {
|
|
14436
14745
|
});
|
|
@@ -14448,7 +14757,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14448
14757
|
});
|
|
14449
14758
|
});
|
|
14450
14759
|
try {
|
|
14451
|
-
const nexusPkg =
|
|
14760
|
+
const nexusPkg = join31(nodeModulesDir, "open-agents-nexus", "package.json");
|
|
14452
14761
|
if (existsSync23(nexusPkg)) {
|
|
14453
14762
|
nexusResolved = true;
|
|
14454
14763
|
try {
|
|
@@ -14459,7 +14768,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14459
14768
|
} else {
|
|
14460
14769
|
try {
|
|
14461
14770
|
const globalDir = await execAsync2("npm root -g", { timeout: 5e3 });
|
|
14462
|
-
const globalPkg =
|
|
14771
|
+
const globalPkg = join31(globalDir, "open-agents-nexus", "package.json");
|
|
14463
14772
|
if (existsSync23(globalPkg)) {
|
|
14464
14773
|
nexusResolved = true;
|
|
14465
14774
|
try {
|
|
@@ -14504,7 +14813,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14504
14813
|
}
|
|
14505
14814
|
}
|
|
14506
14815
|
await this.ensureWallet();
|
|
14507
|
-
const daemonPath =
|
|
14816
|
+
const daemonPath = join31(this.nexusDir, "nexus-daemon.mjs");
|
|
14508
14817
|
await writeFile12(daemonPath, DAEMON_SCRIPT);
|
|
14509
14818
|
const agentName = args.agent_name || "open-agents-node";
|
|
14510
14819
|
const agentType = args.agent_type || "general";
|
|
@@ -14515,11 +14824,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14515
14824
|
} catch {
|
|
14516
14825
|
}
|
|
14517
14826
|
const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
|
|
14518
|
-
const daemonLogPath =
|
|
14519
|
-
const daemonErrPath =
|
|
14827
|
+
const daemonLogPath = join31(this.nexusDir, "daemon.log");
|
|
14828
|
+
const daemonErrPath = join31(this.nexusDir, "daemon.err");
|
|
14520
14829
|
const outFd = openSync2(daemonLogPath, "w");
|
|
14521
14830
|
const errFd = openSync2(daemonErrPath, "w");
|
|
14522
|
-
const child =
|
|
14831
|
+
const child = spawn12("node", [daemonPath, this.nexusDir, agentName, agentType], {
|
|
14523
14832
|
detached: true,
|
|
14524
14833
|
stdio: ["ignore", outFd, errFd],
|
|
14525
14834
|
cwd: this.repoRoot,
|
|
@@ -14534,7 +14843,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14534
14843
|
closeSync2(errFd);
|
|
14535
14844
|
} catch {
|
|
14536
14845
|
}
|
|
14537
|
-
const statusFile =
|
|
14846
|
+
const statusFile = join31(this.nexusDir, "status.json");
|
|
14538
14847
|
for (let i = 0; i < 40; i++) {
|
|
14539
14848
|
await new Promise((r) => setTimeout(r, 500));
|
|
14540
14849
|
if (existsSync23(statusFile)) {
|
|
@@ -14593,7 +14902,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14593
14902
|
} catch {
|
|
14594
14903
|
}
|
|
14595
14904
|
for (const f of ["daemon.pid", "status.json", "cmd.json", "resp.json"]) {
|
|
14596
|
-
const p =
|
|
14905
|
+
const p = join31(this.nexusDir, f);
|
|
14597
14906
|
if (existsSync23(p))
|
|
14598
14907
|
await unlink(p).catch(() => {
|
|
14599
14908
|
});
|
|
@@ -14604,7 +14913,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14604
14913
|
const pid = this.getDaemonPid();
|
|
14605
14914
|
if (!pid)
|
|
14606
14915
|
return "Nexus daemon not running. Use action 'connect' to start.";
|
|
14607
|
-
const statusFile =
|
|
14916
|
+
const statusFile = join31(this.nexusDir, "status.json");
|
|
14608
14917
|
if (!existsSync23(statusFile))
|
|
14609
14918
|
return `Daemon running (pid: ${pid}) but no status yet.`;
|
|
14610
14919
|
try {
|
|
@@ -14619,7 +14928,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14619
14928
|
` Capabilities: ${(status.capabilities || []).length ? (status.capabilities || []).join(", ") : "none"}`,
|
|
14620
14929
|
` Blocked peers: ${(status.blockedPeers || []).length || 0}`
|
|
14621
14930
|
];
|
|
14622
|
-
const walletPath =
|
|
14931
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
14623
14932
|
if (existsSync23(walletPath)) {
|
|
14624
14933
|
try {
|
|
14625
14934
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
@@ -14630,14 +14939,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14630
14939
|
} else {
|
|
14631
14940
|
lines.push(` Wallet: not configured`);
|
|
14632
14941
|
}
|
|
14633
|
-
const inboxDir =
|
|
14942
|
+
const inboxDir = join31(this.nexusDir, "inbox");
|
|
14634
14943
|
if (existsSync23(inboxDir)) {
|
|
14635
14944
|
try {
|
|
14636
14945
|
const roomDirs = await readdir3(inboxDir);
|
|
14637
14946
|
let totalMsgs = 0;
|
|
14638
14947
|
for (const rd of roomDirs) {
|
|
14639
14948
|
try {
|
|
14640
|
-
totalMsgs += (await readdir3(
|
|
14949
|
+
totalMsgs += (await readdir3(join31(inboxDir, rd))).length;
|
|
14641
14950
|
} catch {
|
|
14642
14951
|
}
|
|
14643
14952
|
}
|
|
@@ -14684,9 +14993,9 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14684
14993
|
}
|
|
14685
14994
|
async doReadMessages(args) {
|
|
14686
14995
|
const roomId = args.room_id;
|
|
14687
|
-
const inboxDir =
|
|
14996
|
+
const inboxDir = join31(this.nexusDir, "inbox");
|
|
14688
14997
|
if (roomId) {
|
|
14689
|
-
const roomInbox =
|
|
14998
|
+
const roomInbox = join31(inboxDir, roomId);
|
|
14690
14999
|
if (!existsSync23(roomInbox))
|
|
14691
15000
|
return `No messages in room: ${roomId}`;
|
|
14692
15001
|
const files = (await readdir3(roomInbox)).sort().slice(-20);
|
|
@@ -14695,7 +15004,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14695
15004
|
const messages = [`Messages in ${roomId} (last ${files.length}):`];
|
|
14696
15005
|
for (const f of files) {
|
|
14697
15006
|
try {
|
|
14698
|
-
const msg = JSON.parse(await readFile13(
|
|
15007
|
+
const msg = JSON.parse(await readFile13(join31(roomInbox, f), "utf8"));
|
|
14699
15008
|
const sender = (msg.sender || "unknown").slice(0, 12);
|
|
14700
15009
|
messages.push(` [${new Date(msg.timestamp).toLocaleTimeString()}] ${sender}...: ${msg.content}`);
|
|
14701
15010
|
} catch {
|
|
@@ -14711,7 +15020,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14711
15020
|
const lines = ["Inbox:"];
|
|
14712
15021
|
for (const rd of roomDirs) {
|
|
14713
15022
|
try {
|
|
14714
|
-
const count = (await readdir3(
|
|
15023
|
+
const count = (await readdir3(join31(inboxDir, rd))).length;
|
|
14715
15024
|
lines.push(` ${rd}: ${count} message(s)`);
|
|
14716
15025
|
} catch {
|
|
14717
15026
|
}
|
|
@@ -14723,7 +15032,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14723
15032
|
// ---------------------------------------------------------------------------
|
|
14724
15033
|
async doWalletStatus() {
|
|
14725
15034
|
await this.ensureDir();
|
|
14726
|
-
const walletPath =
|
|
15035
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
14727
15036
|
if (!existsSync23(walletPath)) {
|
|
14728
15037
|
return "No wallet configured. Use wallet_create to set one up.";
|
|
14729
15038
|
}
|
|
@@ -14762,7 +15071,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14762
15071
|
}
|
|
14763
15072
|
async doWalletCreate(args) {
|
|
14764
15073
|
await this.ensureDir();
|
|
14765
|
-
const walletPath =
|
|
15074
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
14766
15075
|
if (existsSync23(walletPath))
|
|
14767
15076
|
return "Wallet already exists. Delete wallet.enc to create a new one.";
|
|
14768
15077
|
const userAddress = args.wallet_address;
|
|
@@ -14791,24 +15100,24 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14791
15100
|
let privKeyHex;
|
|
14792
15101
|
try {
|
|
14793
15102
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
14794
|
-
const privKey =
|
|
15103
|
+
const privKey = randomBytes7(32);
|
|
14795
15104
|
privKeyHex = privKey.toString("hex");
|
|
14796
15105
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
14797
15106
|
address = account.address;
|
|
14798
15107
|
privKey.fill(0);
|
|
14799
15108
|
} catch {
|
|
14800
|
-
const privKey =
|
|
15109
|
+
const privKey = randomBytes7(32);
|
|
14801
15110
|
privKeyHex = privKey.toString("hex");
|
|
14802
15111
|
address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
14803
15112
|
privKey.fill(0);
|
|
14804
15113
|
}
|
|
14805
|
-
const salt =
|
|
15114
|
+
const salt = randomBytes7(32);
|
|
14806
15115
|
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
14807
|
-
const iv =
|
|
15116
|
+
const iv = randomBytes7(16);
|
|
14808
15117
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
14809
15118
|
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
14810
15119
|
enc += cipher.final("hex");
|
|
14811
|
-
const x402KeyPath =
|
|
15120
|
+
const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
|
|
14812
15121
|
const x402Fh = await fsOpen(x402KeyPath, "w", 384);
|
|
14813
15122
|
await x402Fh.writeFile("0x" + privKeyHex);
|
|
14814
15123
|
await x402Fh.close();
|
|
@@ -14846,31 +15155,31 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14846
15155
|
* Silent — no user output, just ensures the files exist.
|
|
14847
15156
|
*/
|
|
14848
15157
|
async ensureWallet() {
|
|
14849
|
-
const walletPath =
|
|
15158
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
14850
15159
|
if (existsSync23(walletPath))
|
|
14851
15160
|
return;
|
|
14852
15161
|
let address;
|
|
14853
15162
|
let privKeyHex;
|
|
14854
15163
|
try {
|
|
14855
15164
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
14856
|
-
const privKey =
|
|
15165
|
+
const privKey = randomBytes7(32);
|
|
14857
15166
|
privKeyHex = privKey.toString("hex");
|
|
14858
15167
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
14859
15168
|
address = account.address;
|
|
14860
15169
|
privKey.fill(0);
|
|
14861
15170
|
} catch {
|
|
14862
|
-
const privKey =
|
|
15171
|
+
const privKey = randomBytes7(32);
|
|
14863
15172
|
privKeyHex = privKey.toString("hex");
|
|
14864
15173
|
address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
14865
15174
|
privKey.fill(0);
|
|
14866
15175
|
}
|
|
14867
|
-
const salt =
|
|
15176
|
+
const salt = randomBytes7(32);
|
|
14868
15177
|
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
14869
|
-
const iv =
|
|
15178
|
+
const iv = randomBytes7(16);
|
|
14870
15179
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
14871
15180
|
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
14872
15181
|
enc += cipher.final("hex");
|
|
14873
|
-
const x402KeyPath =
|
|
15182
|
+
const x402KeyPath = join31(this.nexusDir, "x402-wallet.key");
|
|
14874
15183
|
const x402Fh = await fsOpen(x402KeyPath, "w", 384);
|
|
14875
15184
|
await x402Fh.writeFile("0x" + privKeyHex);
|
|
14876
15185
|
await x402Fh.close();
|
|
@@ -14930,7 +15239,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14930
15239
|
// ---------------------------------------------------------------------------
|
|
14931
15240
|
async doLedgerStatus() {
|
|
14932
15241
|
await this.ensureDir();
|
|
14933
|
-
const ledgerPath =
|
|
15242
|
+
const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
|
|
14934
15243
|
if (!existsSync23(ledgerPath)) {
|
|
14935
15244
|
return "No ledger entries. Earnings and spending will be tracked here after x402 transactions.";
|
|
14936
15245
|
}
|
|
@@ -14972,7 +15281,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14972
15281
|
}
|
|
14973
15282
|
}
|
|
14974
15283
|
async getLedgerSummary() {
|
|
14975
|
-
const ledgerPath =
|
|
15284
|
+
const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
|
|
14976
15285
|
if (!existsSync23(ledgerPath))
|
|
14977
15286
|
return null;
|
|
14978
15287
|
try {
|
|
@@ -14997,7 +15306,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
14997
15306
|
}
|
|
14998
15307
|
async appendLedger(entry) {
|
|
14999
15308
|
await this.ensureDir();
|
|
15000
|
-
const ledgerPath =
|
|
15309
|
+
const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
|
|
15001
15310
|
const line = JSON.stringify(entry) + "\n";
|
|
15002
15311
|
await writeFile12(ledgerPath, existsSync23(ledgerPath) ? await readFile13(ledgerPath, "utf8") + line : line);
|
|
15003
15312
|
}
|
|
@@ -15005,7 +15314,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15005
15314
|
// Step 4: Budget Policy — Spending limits and auto-approve thresholds
|
|
15006
15315
|
// ---------------------------------------------------------------------------
|
|
15007
15316
|
async loadBudget() {
|
|
15008
|
-
const budgetPath =
|
|
15317
|
+
const budgetPath = join31(this.nexusDir, "budget.json");
|
|
15009
15318
|
if (!existsSync23(budgetPath))
|
|
15010
15319
|
return null;
|
|
15011
15320
|
try {
|
|
@@ -15015,7 +15324,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15015
15324
|
}
|
|
15016
15325
|
}
|
|
15017
15326
|
async ensureDefaultBudget() {
|
|
15018
|
-
const budgetPath =
|
|
15327
|
+
const budgetPath = join31(this.nexusDir, "budget.json");
|
|
15019
15328
|
if (existsSync23(budgetPath))
|
|
15020
15329
|
return;
|
|
15021
15330
|
const defaultBudget = {
|
|
@@ -15085,12 +15394,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15085
15394
|
if (changes.length === 0) {
|
|
15086
15395
|
return "No budget parameters provided. Use daily_limit, per_invoke_max, or auto_approve_below.";
|
|
15087
15396
|
}
|
|
15088
|
-
const budgetPath =
|
|
15397
|
+
const budgetPath = join31(this.nexusDir, "budget.json");
|
|
15089
15398
|
await writeFile12(budgetPath, JSON.stringify(budget, null, 2));
|
|
15090
15399
|
return `Budget updated: ${changes.join(", ")}`;
|
|
15091
15400
|
}
|
|
15092
15401
|
async getTodaySpending() {
|
|
15093
|
-
const ledgerPath =
|
|
15402
|
+
const ledgerPath = join31(this.nexusDir, "ledger.jsonl");
|
|
15094
15403
|
if (!existsSync23(ledgerPath))
|
|
15095
15404
|
return 0;
|
|
15096
15405
|
try {
|
|
@@ -15134,7 +15443,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15134
15443
|
if (todaySpent + amountUsdc > budget.dailyLimitUsdc) {
|
|
15135
15444
|
return { allowed: false, reason: `Would exceed daily limit ($${((todaySpent + amountUsdc) / 1e6).toFixed(6)} > $${(budget.dailyLimitUsdc / 1e6).toFixed(6)})` };
|
|
15136
15445
|
}
|
|
15137
|
-
const walletPath =
|
|
15446
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
15138
15447
|
if (existsSync23(walletPath)) {
|
|
15139
15448
|
try {
|
|
15140
15449
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
@@ -15165,7 +15474,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15165
15474
|
const budgetResult = await this.checkBudget(amountSmallest, "transfer:direct", targetAddress);
|
|
15166
15475
|
if (!budgetResult.allowed)
|
|
15167
15476
|
return `BLOCKED by budget policy: ${budgetResult.reason}`;
|
|
15168
|
-
const walletPath =
|
|
15477
|
+
const walletPath = join31(this.nexusDir, "wallet.enc");
|
|
15169
15478
|
if (!existsSync23(walletPath))
|
|
15170
15479
|
throw new Error("No wallet. Use wallet_create first.");
|
|
15171
15480
|
const w = JSON.parse(await readFile13(walletPath, "utf8"));
|
|
@@ -15180,7 +15489,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15180
15489
|
try {
|
|
15181
15490
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
15182
15491
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
15183
|
-
const nonce = "0x" +
|
|
15492
|
+
const nonce = "0x" + randomBytes7(32).toString("hex");
|
|
15184
15493
|
const now = Math.floor(Date.now() / 1e3);
|
|
15185
15494
|
const validAfter = now - 60;
|
|
15186
15495
|
const validBefore = now + 3600;
|
|
@@ -15226,7 +15535,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15226
15535
|
capability: "transfer:direct",
|
|
15227
15536
|
note: "signed, awaiting submission"
|
|
15228
15537
|
});
|
|
15229
|
-
const proofFile =
|
|
15538
|
+
const proofFile = join31(this.nexusDir, "pending-transfer.json");
|
|
15230
15539
|
const proof = {
|
|
15231
15540
|
from: account.address,
|
|
15232
15541
|
to: targetAddress,
|
|
@@ -15268,7 +15577,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15268
15577
|
throw new Error("prompt is required");
|
|
15269
15578
|
const estimatedTokens = Math.ceil(prompt.length / 4) + 1e3;
|
|
15270
15579
|
let estimatedCostSmallest = 0;
|
|
15271
|
-
const pricingPath =
|
|
15580
|
+
const pricingPath = join31(this.nexusDir, "pricing.json");
|
|
15272
15581
|
if (existsSync23(pricingPath)) {
|
|
15273
15582
|
try {
|
|
15274
15583
|
const pricing = JSON.parse(await readFile13(pricingPath, "utf8"));
|
|
@@ -15383,12 +15692,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15383
15692
|
} catch {
|
|
15384
15693
|
}
|
|
15385
15694
|
}
|
|
15386
|
-
const nonce =
|
|
15695
|
+
const nonce = randomBytes7(16).toString("hex");
|
|
15387
15696
|
const hash = createHash("sha256").update(`${modelName}:${nonce}:${Date.now()}`).digest("hex");
|
|
15388
15697
|
const bar = (s) => "\u2588".repeat(Math.round(s / 5)) + "\u2591".repeat(20 - Math.round(s / 5));
|
|
15389
15698
|
const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
|
|
15390
15699
|
await this.ensureDir();
|
|
15391
|
-
await writeFile12(
|
|
15700
|
+
await writeFile12(join31(this.nexusDir, "inference-proof.json"), JSON.stringify({
|
|
15392
15701
|
modelName,
|
|
15393
15702
|
gpuName,
|
|
15394
15703
|
vramMb,
|
|
@@ -15411,14 +15720,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
15411
15720
|
});
|
|
15412
15721
|
|
|
15413
15722
|
// packages/execution/dist/shellRunner.js
|
|
15414
|
-
import { spawn as
|
|
15723
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
15415
15724
|
async function runShell(options) {
|
|
15416
15725
|
const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
15417
15726
|
const mergedEnv = env ? { ...process.env, ...env } : process.env;
|
|
15418
15727
|
return new Promise((resolve32) => {
|
|
15419
15728
|
const start = Date.now();
|
|
15420
15729
|
let timedOut = false;
|
|
15421
|
-
const child =
|
|
15730
|
+
const child = spawn13(command, args, {
|
|
15422
15731
|
cwd: cwd4,
|
|
15423
15732
|
env: mergedEnv
|
|
15424
15733
|
// Do NOT use shell:true — we pass command + args separately
|
|
@@ -15517,7 +15826,7 @@ var init_gitWorktree = __esm({
|
|
|
15517
15826
|
// packages/execution/dist/patchApplier.js
|
|
15518
15827
|
import { readFileSync as readFileSync17, writeFileSync as writeFileSync7, existsSync as existsSync24, mkdirSync as mkdirSync7 } from "node:fs";
|
|
15519
15828
|
import { dirname as dirname11 } from "node:path";
|
|
15520
|
-
import { spawn as
|
|
15829
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
15521
15830
|
async function applyPatch(patch) {
|
|
15522
15831
|
switch (patch.type) {
|
|
15523
15832
|
case "block-replace":
|
|
@@ -15567,7 +15876,7 @@ async function applyUnifiedDiff(patch) {
|
|
|
15567
15876
|
function runWithStdin(options) {
|
|
15568
15877
|
const { command, args, cwd: cwd4, stdin } = options;
|
|
15569
15878
|
return new Promise((resolve32) => {
|
|
15570
|
-
const child =
|
|
15879
|
+
const child = spawn14(command, args, {
|
|
15571
15880
|
cwd: cwd4,
|
|
15572
15881
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15573
15882
|
});
|
|
@@ -16051,6 +16360,7 @@ __export(dist_exports, {
|
|
|
16051
16360
|
OpenCodeTool: () => OpenCodeTool,
|
|
16052
16361
|
PdfToTextTool: () => PdfToTextTool,
|
|
16053
16362
|
ReminderTool: () => ReminderTool,
|
|
16363
|
+
ReplTool: () => ReplTool,
|
|
16054
16364
|
SchedulerTool: () => SchedulerTool,
|
|
16055
16365
|
ScreenshotTool: () => ScreenshotTool,
|
|
16056
16366
|
ShellTool: () => ShellTool,
|
|
@@ -16135,6 +16445,7 @@ var init_dist2 = __esm({
|
|
|
16135
16445
|
init_transcribe_tool();
|
|
16136
16446
|
init_structured_file();
|
|
16137
16447
|
init_code_sandbox();
|
|
16448
|
+
init_repl();
|
|
16138
16449
|
init_structured_read();
|
|
16139
16450
|
init_vision();
|
|
16140
16451
|
init_desktop_click();
|
|
@@ -16835,12 +17146,12 @@ var init_dist3 = __esm({
|
|
|
16835
17146
|
|
|
16836
17147
|
// packages/orchestrator/dist/promptLoader.js
|
|
16837
17148
|
import { readFileSync as readFileSync18, existsSync as existsSync25 } from "node:fs";
|
|
16838
|
-
import { join as
|
|
17149
|
+
import { join as join32, dirname as dirname12 } from "node:path";
|
|
16839
17150
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
16840
17151
|
function loadPrompt(promptPath, vars) {
|
|
16841
17152
|
let content = cache.get(promptPath);
|
|
16842
17153
|
if (content === void 0) {
|
|
16843
|
-
const fullPath =
|
|
17154
|
+
const fullPath = join32(PROMPTS_DIR, promptPath);
|
|
16844
17155
|
if (!existsSync25(fullPath)) {
|
|
16845
17156
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
16846
17157
|
}
|
|
@@ -16857,7 +17168,7 @@ var init_promptLoader = __esm({
|
|
|
16857
17168
|
"use strict";
|
|
16858
17169
|
__filename = fileURLToPath7(import.meta.url);
|
|
16859
17170
|
__dirname4 = dirname12(__filename);
|
|
16860
|
-
PROMPTS_DIR =
|
|
17171
|
+
PROMPTS_DIR = join32(__dirname4, "..", "prompts");
|
|
16861
17172
|
cache = /* @__PURE__ */ new Map();
|
|
16862
17173
|
}
|
|
16863
17174
|
});
|
|
@@ -17237,7 +17548,7 @@ var init_code_retriever = __esm({
|
|
|
17237
17548
|
import { execFile as execFile5 } from "node:child_process";
|
|
17238
17549
|
import { promisify as promisify4 } from "node:util";
|
|
17239
17550
|
import { readFile as readFile14, readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
17240
|
-
import { join as
|
|
17551
|
+
import { join as join33, extname as extname7 } from "node:path";
|
|
17241
17552
|
async function searchByPath(pathPattern, options) {
|
|
17242
17553
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
17243
17554
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -17379,7 +17690,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
17379
17690
|
continue;
|
|
17380
17691
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
17381
17692
|
continue;
|
|
17382
|
-
const absPath =
|
|
17693
|
+
const absPath = join33(dir, entry.name);
|
|
17383
17694
|
if (entry.isDirectory()) {
|
|
17384
17695
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
17385
17696
|
} else if (entry.isFile()) {
|
|
@@ -17686,7 +17997,7 @@ var init_graphExpand = __esm({
|
|
|
17686
17997
|
|
|
17687
17998
|
// packages/retrieval/dist/snippetPacker.js
|
|
17688
17999
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
17689
|
-
import { join as
|
|
18000
|
+
import { join as join34 } from "node:path";
|
|
17690
18001
|
async function packSnippets(requests, opts = {}) {
|
|
17691
18002
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
17692
18003
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -17712,7 +18023,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
17712
18023
|
return { packed, dropped, totalTokens };
|
|
17713
18024
|
}
|
|
17714
18025
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
17715
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
18026
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join34(repoRoot, req.filePath);
|
|
17716
18027
|
let content;
|
|
17717
18028
|
try {
|
|
17718
18029
|
content = await readFile15(absPath, "utf-8");
|
|
@@ -20253,8 +20564,8 @@ ${marker}` : marker);
|
|
|
20253
20564
|
return;
|
|
20254
20565
|
try {
|
|
20255
20566
|
const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
|
|
20256
|
-
const { join:
|
|
20257
|
-
const sessionDir =
|
|
20567
|
+
const { join: join58 } = __require("node:path");
|
|
20568
|
+
const sessionDir = join58(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
20258
20569
|
mkdirSync21(sessionDir, { recursive: true });
|
|
20259
20570
|
const checkpoint = {
|
|
20260
20571
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -20267,7 +20578,7 @@ ${marker}` : marker);
|
|
|
20267
20578
|
memexEntryCount: this._memexArchive.size,
|
|
20268
20579
|
fileRegistrySize: this._fileRegistry.size
|
|
20269
20580
|
};
|
|
20270
|
-
writeFileSync20(
|
|
20581
|
+
writeFileSync20(join58(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
20271
20582
|
} catch {
|
|
20272
20583
|
}
|
|
20273
20584
|
}
|
|
@@ -21533,11 +21844,11 @@ ${transcript}`
|
|
|
21533
21844
|
});
|
|
21534
21845
|
|
|
21535
21846
|
// packages/orchestrator/dist/nexusBackend.js
|
|
21536
|
-
import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as
|
|
21847
|
+
import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
21537
21848
|
import { watch as fsWatch } from "node:fs";
|
|
21538
|
-
import { join as
|
|
21539
|
-
import { tmpdir as
|
|
21540
|
-
import { randomBytes as
|
|
21849
|
+
import { join as join35 } from "node:path";
|
|
21850
|
+
import { tmpdir as tmpdir7 } from "node:os";
|
|
21851
|
+
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
21541
21852
|
var NexusAgenticBackend;
|
|
21542
21853
|
var init_nexusBackend = __esm({
|
|
21543
21854
|
"packages/orchestrator/dist/nexusBackend.js"() {
|
|
@@ -21685,7 +21996,7 @@ var init_nexusBackend = __esm({
|
|
|
21685
21996
|
* Falls back to unary + word-split if streaming setup fails.
|
|
21686
21997
|
*/
|
|
21687
21998
|
async *chatCompletionStream(request) {
|
|
21688
|
-
const streamFile =
|
|
21999
|
+
const streamFile = join35(tmpdir7(), `nexus-stream-${randomBytes8(6).toString("hex")}.jsonl`);
|
|
21689
22000
|
writeFileSync8(streamFile, "", "utf8");
|
|
21690
22001
|
const daemonArgs = {
|
|
21691
22002
|
model: this.model,
|
|
@@ -21706,7 +22017,7 @@ var init_nexusBackend = __esm({
|
|
|
21706
22017
|
} catch (sendErr) {
|
|
21707
22018
|
this.consecutiveFailures++;
|
|
21708
22019
|
try {
|
|
21709
|
-
|
|
22020
|
+
unlinkSync4(streamFile);
|
|
21710
22021
|
} catch {
|
|
21711
22022
|
}
|
|
21712
22023
|
throw sendErr;
|
|
@@ -21721,7 +22032,7 @@ var init_nexusBackend = __esm({
|
|
|
21721
22032
|
}
|
|
21722
22033
|
if (!isStreaming) {
|
|
21723
22034
|
try {
|
|
21724
|
-
|
|
22035
|
+
unlinkSync4(streamFile);
|
|
21725
22036
|
} catch {
|
|
21726
22037
|
}
|
|
21727
22038
|
let parsed;
|
|
@@ -21877,7 +22188,7 @@ var init_nexusBackend = __esm({
|
|
|
21877
22188
|
}
|
|
21878
22189
|
} finally {
|
|
21879
22190
|
try {
|
|
21880
|
-
|
|
22191
|
+
unlinkSync4(streamFile);
|
|
21881
22192
|
} catch {
|
|
21882
22193
|
}
|
|
21883
22194
|
}
|
|
@@ -22720,9 +23031,9 @@ __export(listen_exports, {
|
|
|
22720
23031
|
isVideoPath: () => isVideoPath,
|
|
22721
23032
|
waitForTranscribeCli: () => waitForTranscribeCli
|
|
22722
23033
|
});
|
|
22723
|
-
import { spawn as
|
|
23034
|
+
import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
|
|
22724
23035
|
import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
|
|
22725
|
-
import { join as
|
|
23036
|
+
import { join as join36, dirname as dirname13 } from "node:path";
|
|
22726
23037
|
import { homedir as homedir8 } from "node:os";
|
|
22727
23038
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
22728
23039
|
import { EventEmitter } from "node:events";
|
|
@@ -22808,12 +23119,12 @@ function findMicCaptureCommand() {
|
|
|
22808
23119
|
function findLiveWhisperScript() {
|
|
22809
23120
|
const thisDir = dirname13(fileURLToPath8(import.meta.url));
|
|
22810
23121
|
const candidates = [
|
|
22811
|
-
|
|
22812
|
-
|
|
22813
|
-
|
|
23122
|
+
join36(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
23123
|
+
join36(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
23124
|
+
join36(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
22814
23125
|
// npm install layout — scripts bundled alongside dist
|
|
22815
|
-
|
|
22816
|
-
|
|
23126
|
+
join36(thisDir, "../scripts/live-whisper.py"),
|
|
23127
|
+
join36(thisDir, "../../scripts/live-whisper.py")
|
|
22817
23128
|
];
|
|
22818
23129
|
for (const p of candidates) {
|
|
22819
23130
|
if (existsSync27(p))
|
|
@@ -22826,8 +23137,8 @@ function findLiveWhisperScript() {
|
|
|
22826
23137
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22827
23138
|
}).trim();
|
|
22828
23139
|
const candidates2 = [
|
|
22829
|
-
|
|
22830
|
-
|
|
23140
|
+
join36(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
23141
|
+
join36(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
22831
23142
|
];
|
|
22832
23143
|
for (const p of candidates2) {
|
|
22833
23144
|
if (existsSync27(p))
|
|
@@ -22835,11 +23146,11 @@ function findLiveWhisperScript() {
|
|
|
22835
23146
|
}
|
|
22836
23147
|
} catch {
|
|
22837
23148
|
}
|
|
22838
|
-
const nvmBase =
|
|
23149
|
+
const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
|
|
22839
23150
|
if (existsSync27(nvmBase)) {
|
|
22840
23151
|
try {
|
|
22841
23152
|
for (const ver of readdirSync6(nvmBase)) {
|
|
22842
|
-
const p =
|
|
23153
|
+
const p = join36(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
22843
23154
|
if (existsSync27(p))
|
|
22844
23155
|
return p;
|
|
22845
23156
|
}
|
|
@@ -22858,7 +23169,7 @@ function ensureTranscribeCliBackground() {
|
|
|
22858
23169
|
timeout: 5e3,
|
|
22859
23170
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22860
23171
|
}).trim();
|
|
22861
|
-
if (existsSync27(
|
|
23172
|
+
if (existsSync27(join36(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
22862
23173
|
return true;
|
|
22863
23174
|
}
|
|
22864
23175
|
} catch {
|
|
@@ -22930,7 +23241,7 @@ var init_listen = __esm({
|
|
|
22930
23241
|
const timeout = setTimeout(() => {
|
|
22931
23242
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
22932
23243
|
}, 3e5);
|
|
22933
|
-
this.process =
|
|
23244
|
+
this.process = spawn15("python3", [
|
|
22934
23245
|
this.scriptPath,
|
|
22935
23246
|
"--model",
|
|
22936
23247
|
this.model,
|
|
@@ -23081,24 +23392,24 @@ var init_listen = __esm({
|
|
|
23081
23392
|
timeout: 5e3,
|
|
23082
23393
|
stdio: ["pipe", "pipe", "pipe"]
|
|
23083
23394
|
}).trim();
|
|
23084
|
-
const tcPath =
|
|
23085
|
-
if (existsSync27(
|
|
23395
|
+
const tcPath = join36(globalRoot, "transcribe-cli");
|
|
23396
|
+
if (existsSync27(join36(tcPath, "dist", "index.js"))) {
|
|
23086
23397
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
23087
23398
|
const req = createRequire4(import.meta.url);
|
|
23088
|
-
return req(
|
|
23399
|
+
return req(join36(tcPath, "dist", "index.js"));
|
|
23089
23400
|
}
|
|
23090
23401
|
} catch {
|
|
23091
23402
|
}
|
|
23092
|
-
const nvmBase =
|
|
23403
|
+
const nvmBase = join36(homedir8(), ".nvm", "versions", "node");
|
|
23093
23404
|
if (existsSync27(nvmBase)) {
|
|
23094
23405
|
try {
|
|
23095
23406
|
const { readdirSync: readdirSync17 } = await import("node:fs");
|
|
23096
23407
|
for (const ver of readdirSync17(nvmBase)) {
|
|
23097
|
-
const tcPath =
|
|
23098
|
-
if (existsSync27(
|
|
23408
|
+
const tcPath = join36(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
23409
|
+
if (existsSync27(join36(tcPath, "dist", "index.js"))) {
|
|
23099
23410
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
23100
23411
|
const req = createRequire4(import.meta.url);
|
|
23101
|
-
return req(
|
|
23412
|
+
return req(join36(tcPath, "dist", "index.js"));
|
|
23102
23413
|
}
|
|
23103
23414
|
}
|
|
23104
23415
|
} catch {
|
|
@@ -23212,7 +23523,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
23212
23523
|
return `Failed to start live transcription: ${msg}${tcHint}`;
|
|
23213
23524
|
}
|
|
23214
23525
|
}
|
|
23215
|
-
this.micProcess =
|
|
23526
|
+
this.micProcess = spawn15(micCmd.cmd, micCmd.args, {
|
|
23216
23527
|
stdio: ["pipe", "pipe", "pipe"],
|
|
23217
23528
|
env: { ...process.env }
|
|
23218
23529
|
});
|
|
@@ -23380,9 +23691,9 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
23380
23691
|
});
|
|
23381
23692
|
if (outputDir) {
|
|
23382
23693
|
const { basename: basename16 } = await import("node:path");
|
|
23383
|
-
const transcriptDir =
|
|
23694
|
+
const transcriptDir = join36(outputDir, ".oa", "transcripts");
|
|
23384
23695
|
mkdirSync8(transcriptDir, { recursive: true });
|
|
23385
|
-
const outFile =
|
|
23696
|
+
const outFile = join36(transcriptDir, `${basename16(filePath)}.txt`);
|
|
23386
23697
|
writeFileSync9(outFile, result.text, "utf-8");
|
|
23387
23698
|
}
|
|
23388
23699
|
return {
|
|
@@ -25631,7 +25942,7 @@ var require_websocket = __commonJS({
|
|
|
25631
25942
|
var http = __require("http");
|
|
25632
25943
|
var net = __require("net");
|
|
25633
25944
|
var tls = __require("tls");
|
|
25634
|
-
var { randomBytes:
|
|
25945
|
+
var { randomBytes: randomBytes12, createHash: createHash5 } = __require("crypto");
|
|
25635
25946
|
var { Duplex, Readable } = __require("stream");
|
|
25636
25947
|
var { URL: URL3 } = __require("url");
|
|
25637
25948
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -26161,7 +26472,7 @@ var require_websocket = __commonJS({
|
|
|
26161
26472
|
}
|
|
26162
26473
|
}
|
|
26163
26474
|
const defaultPort = isSecure ? 443 : 80;
|
|
26164
|
-
const key =
|
|
26475
|
+
const key = randomBytes12(16).toString("base64");
|
|
26165
26476
|
const request = isSecure ? https.request : http.request;
|
|
26166
26477
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
26167
26478
|
let perMessageDeflate;
|
|
@@ -28005,8 +28316,8 @@ var init_render = __esm({
|
|
|
28005
28316
|
});
|
|
28006
28317
|
|
|
28007
28318
|
// packages/cli/dist/tui/voice-session.js
|
|
28008
|
-
import { createServer } from "node:http";
|
|
28009
|
-
import { spawn as
|
|
28319
|
+
import { createServer as createServer2 } from "node:http";
|
|
28320
|
+
import { spawn as spawn16, execSync as execSync24 } from "node:child_process";
|
|
28010
28321
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
28011
28322
|
function generateFrontendHTML() {
|
|
28012
28323
|
return `<!DOCTYPE html>
|
|
@@ -28432,7 +28743,7 @@ var init_voice_session = __esm({
|
|
|
28432
28743
|
return "Voice session already active.";
|
|
28433
28744
|
const port = await this.findFreePort();
|
|
28434
28745
|
this.state.localPort = port;
|
|
28435
|
-
this.server =
|
|
28746
|
+
this.server = createServer2((req, res) => this.handleHTTP(req, res));
|
|
28436
28747
|
this.server.timeout = 0;
|
|
28437
28748
|
this.server.keepAliveTimeout = 0;
|
|
28438
28749
|
this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
|
|
@@ -28660,7 +28971,7 @@ var init_voice_session = __esm({
|
|
|
28660
28971
|
const timeout = setTimeout(() => {
|
|
28661
28972
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
28662
28973
|
}, 3e4);
|
|
28663
|
-
this.cloudflaredProcess =
|
|
28974
|
+
this.cloudflaredProcess = spawn16("cloudflared", [
|
|
28664
28975
|
"tunnel",
|
|
28665
28976
|
"--url",
|
|
28666
28977
|
`http://127.0.0.1:${port}`
|
|
@@ -28715,7 +29026,7 @@ var init_voice_session = __esm({
|
|
|
28715
29026
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
28716
29027
|
findFreePort() {
|
|
28717
29028
|
return new Promise((resolve32, reject) => {
|
|
28718
|
-
const srv =
|
|
29029
|
+
const srv = createServer2();
|
|
28719
29030
|
srv.listen(0, "127.0.0.1", () => {
|
|
28720
29031
|
const addr = srv.address();
|
|
28721
29032
|
if (addr && typeof addr === "object") {
|
|
@@ -28733,14 +29044,14 @@ var init_voice_session = __esm({
|
|
|
28733
29044
|
});
|
|
28734
29045
|
|
|
28735
29046
|
// packages/cli/dist/tui/expose.js
|
|
28736
|
-
import { createServer as
|
|
28737
|
-
import { spawn as
|
|
29047
|
+
import { createServer as createServer3, request as httpRequest } from "node:http";
|
|
29048
|
+
import { spawn as spawn17, exec } from "node:child_process";
|
|
28738
29049
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
28739
|
-
import { randomBytes as
|
|
29050
|
+
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
28740
29051
|
import { URL as URL2 } from "node:url";
|
|
28741
29052
|
import { loadavg, cpus, totalmem, freemem } from "node:os";
|
|
28742
|
-
import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as
|
|
28743
|
-
import { join as
|
|
29053
|
+
import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
|
|
29054
|
+
import { join as join37 } from "node:path";
|
|
28744
29055
|
function cleanForwardHeaders(raw, targetHost) {
|
|
28745
29056
|
const out = {};
|
|
28746
29057
|
for (const [key, value] of Object.entries(raw)) {
|
|
@@ -28768,7 +29079,7 @@ function fmtTokens(n) {
|
|
|
28768
29079
|
}
|
|
28769
29080
|
function readExposeState(stateDir) {
|
|
28770
29081
|
try {
|
|
28771
|
-
const path =
|
|
29082
|
+
const path = join37(stateDir, STATE_FILE_NAME);
|
|
28772
29083
|
if (!existsSync28(path))
|
|
28773
29084
|
return null;
|
|
28774
29085
|
const raw = readFileSync19(path, "utf8");
|
|
@@ -28783,13 +29094,13 @@ function readExposeState(stateDir) {
|
|
|
28783
29094
|
function writeExposeState(stateDir, state) {
|
|
28784
29095
|
try {
|
|
28785
29096
|
mkdirSync9(stateDir, { recursive: true });
|
|
28786
|
-
writeFileSync10(
|
|
29097
|
+
writeFileSync10(join37(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
28787
29098
|
} catch {
|
|
28788
29099
|
}
|
|
28789
29100
|
}
|
|
28790
29101
|
function removeExposeState(stateDir) {
|
|
28791
29102
|
try {
|
|
28792
|
-
|
|
29103
|
+
unlinkSync5(join37(stateDir, STATE_FILE_NAME));
|
|
28793
29104
|
} catch {
|
|
28794
29105
|
}
|
|
28795
29106
|
}
|
|
@@ -28878,7 +29189,7 @@ async function collectSystemMetricsAsync() {
|
|
|
28878
29189
|
}
|
|
28879
29190
|
function readP2PExposeState(stateDir) {
|
|
28880
29191
|
try {
|
|
28881
|
-
const path =
|
|
29192
|
+
const path = join37(stateDir, P2P_STATE_FILE_NAME);
|
|
28882
29193
|
if (!existsSync28(path))
|
|
28883
29194
|
return null;
|
|
28884
29195
|
const raw = readFileSync19(path, "utf8");
|
|
@@ -28893,13 +29204,13 @@ function readP2PExposeState(stateDir) {
|
|
|
28893
29204
|
function writeP2PExposeState(stateDir, state) {
|
|
28894
29205
|
try {
|
|
28895
29206
|
mkdirSync9(stateDir, { recursive: true });
|
|
28896
|
-
writeFileSync10(
|
|
29207
|
+
writeFileSync10(join37(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
|
|
28897
29208
|
} catch {
|
|
28898
29209
|
}
|
|
28899
29210
|
}
|
|
28900
29211
|
function removeP2PExposeState(stateDir) {
|
|
28901
29212
|
try {
|
|
28902
|
-
|
|
29213
|
+
unlinkSync5(join37(stateDir, P2P_STATE_FILE_NAME));
|
|
28903
29214
|
} catch {
|
|
28904
29215
|
}
|
|
28905
29216
|
}
|
|
@@ -28981,7 +29292,7 @@ var init_expose = __esm({
|
|
|
28981
29292
|
this._stateDir = options.stateDir ?? null;
|
|
28982
29293
|
this._fullAccess = options.fullAccess ?? false;
|
|
28983
29294
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
28984
|
-
this._authKey =
|
|
29295
|
+
this._authKey = randomBytes9(24).toString("base64url");
|
|
28985
29296
|
} else {
|
|
28986
29297
|
this._authKey = options.authKey;
|
|
28987
29298
|
}
|
|
@@ -29124,7 +29435,7 @@ var init_expose = __esm({
|
|
|
29124
29435
|
// ── Proxy server ────────────────────────────────────────────────────────
|
|
29125
29436
|
createProxyServer(localPort) {
|
|
29126
29437
|
const target = new URL2(this._targetUrl);
|
|
29127
|
-
const server =
|
|
29438
|
+
const server = createServer3((req, res) => {
|
|
29128
29439
|
res.on("error", () => {
|
|
29129
29440
|
});
|
|
29130
29441
|
const authHeader = req.headers.authorization;
|
|
@@ -29400,7 +29711,7 @@ var init_expose = __esm({
|
|
|
29400
29711
|
const timeout = setTimeout(() => {
|
|
29401
29712
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
29402
29713
|
}, 3e4);
|
|
29403
|
-
this.cloudflaredProcess =
|
|
29714
|
+
this.cloudflaredProcess = spawn17("cloudflared", [
|
|
29404
29715
|
"tunnel",
|
|
29405
29716
|
"--url",
|
|
29406
29717
|
`http://127.0.0.1:${port}`,
|
|
@@ -29515,7 +29826,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29515
29826
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
29516
29827
|
findFreePort() {
|
|
29517
29828
|
return new Promise((resolve32, reject) => {
|
|
29518
|
-
const srv =
|
|
29829
|
+
const srv = createServer3();
|
|
29519
29830
|
srv.listen(0, "127.0.0.1", () => {
|
|
29520
29831
|
const addr = srv.address();
|
|
29521
29832
|
if (addr && typeof addr === "object") {
|
|
@@ -29691,7 +30002,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29691
30002
|
this._onInfo = options.onInfo;
|
|
29692
30003
|
this._onError = options.onError;
|
|
29693
30004
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
29694
|
-
this._authKey =
|
|
30005
|
+
this._authKey = randomBytes9(24).toString("base64url");
|
|
29695
30006
|
} else {
|
|
29696
30007
|
this._authKey = options.authKey;
|
|
29697
30008
|
}
|
|
@@ -29729,7 +30040,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29729
30040
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
29730
30041
|
}
|
|
29731
30042
|
const nexusDir = this._nexusTool.getNexusDir();
|
|
29732
|
-
const statusPath =
|
|
30043
|
+
const statusPath = join37(nexusDir, "status.json");
|
|
29733
30044
|
for (let i = 0; i < 80; i++) {
|
|
29734
30045
|
try {
|
|
29735
30046
|
const raw = readFileSync19(statusPath, "utf8");
|
|
@@ -29763,7 +30074,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29763
30074
|
});
|
|
29764
30075
|
}
|
|
29765
30076
|
try {
|
|
29766
|
-
const invocDir =
|
|
30077
|
+
const invocDir = join37(nexusDir, "invocations");
|
|
29767
30078
|
if (existsSync28(invocDir)) {
|
|
29768
30079
|
this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
|
|
29769
30080
|
this._stats.totalRequests = this._prevInvocCount;
|
|
@@ -29793,7 +30104,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29793
30104
|
if (!state)
|
|
29794
30105
|
return null;
|
|
29795
30106
|
const nexusDir = nexusTool.getNexusDir();
|
|
29796
|
-
const statusPath =
|
|
30107
|
+
const statusPath = join37(nexusDir, "status.json");
|
|
29797
30108
|
try {
|
|
29798
30109
|
if (!existsSync28(statusPath)) {
|
|
29799
30110
|
removeP2PExposeState(stateDir);
|
|
@@ -29852,7 +30163,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29852
30163
|
let lastMeteringLineCount = 0;
|
|
29853
30164
|
this._activityPollTimer = setInterval(() => {
|
|
29854
30165
|
try {
|
|
29855
|
-
const invocDir =
|
|
30166
|
+
const invocDir = join37(nexusDir, "invocations");
|
|
29856
30167
|
if (!existsSync28(invocDir))
|
|
29857
30168
|
return;
|
|
29858
30169
|
const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
|
|
@@ -29868,13 +30179,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
29868
30179
|
let recentActive = 0;
|
|
29869
30180
|
for (const f of files.slice(-10)) {
|
|
29870
30181
|
try {
|
|
29871
|
-
const st = statSync10(
|
|
30182
|
+
const st = statSync10(join37(invocDir, f));
|
|
29872
30183
|
if (now - st.mtimeMs < 1e4)
|
|
29873
30184
|
recentActive++;
|
|
29874
30185
|
} catch {
|
|
29875
30186
|
}
|
|
29876
30187
|
}
|
|
29877
|
-
const meteringFile =
|
|
30188
|
+
const meteringFile = join37(nexusDir, "metering.jsonl");
|
|
29878
30189
|
let meteringLines = lastMeteringLineCount;
|
|
29879
30190
|
try {
|
|
29880
30191
|
if (existsSync28(meteringFile)) {
|
|
@@ -29904,7 +30215,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29904
30215
|
this._activityPollTimer.unref();
|
|
29905
30216
|
this._pollTimer = setInterval(() => {
|
|
29906
30217
|
try {
|
|
29907
|
-
const statusPath =
|
|
30218
|
+
const statusPath = join37(nexusDir, "status.json");
|
|
29908
30219
|
if (existsSync28(statusPath)) {
|
|
29909
30220
|
const status = JSON.parse(readFileSync19(statusPath, "utf8"));
|
|
29910
30221
|
if (status.peerId && !this._peerId) {
|
|
@@ -29915,7 +30226,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29915
30226
|
} catch {
|
|
29916
30227
|
}
|
|
29917
30228
|
try {
|
|
29918
|
-
const invocDir =
|
|
30229
|
+
const invocDir = join37(nexusDir, "invocations");
|
|
29919
30230
|
if (existsSync28(invocDir)) {
|
|
29920
30231
|
const files = readdirSync7(invocDir);
|
|
29921
30232
|
const invocCount = files.filter((f) => f.endsWith(".json")).length;
|
|
@@ -29927,7 +30238,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
29927
30238
|
} catch {
|
|
29928
30239
|
}
|
|
29929
30240
|
try {
|
|
29930
|
-
const meteringFile =
|
|
30241
|
+
const meteringFile = join37(nexusDir, "metering.jsonl");
|
|
29931
30242
|
if (existsSync28(meteringFile)) {
|
|
29932
30243
|
const content = readFileSync19(meteringFile, "utf8");
|
|
29933
30244
|
if (content.length > lastMeteringSize) {
|
|
@@ -30137,9 +30448,9 @@ var init_types = __esm({
|
|
|
30137
30448
|
});
|
|
30138
30449
|
|
|
30139
30450
|
// packages/cli/dist/tui/p2p/secret-vault.js
|
|
30140
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as
|
|
30451
|
+
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes10, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
|
|
30141
30452
|
import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
|
|
30142
|
-
import { join as
|
|
30453
|
+
import { join as join38, dirname as dirname14 } from "node:path";
|
|
30143
30454
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
30144
30455
|
var init_secret_vault = __esm({
|
|
30145
30456
|
"packages/cli/dist/tui/p2p/secret-vault.js"() {
|
|
@@ -30343,9 +30654,9 @@ var init_secret_vault = __esm({
|
|
|
30343
30654
|
minTrust: s.minTrust,
|
|
30344
30655
|
createdAt: s.createdAt
|
|
30345
30656
|
})));
|
|
30346
|
-
const salt =
|
|
30657
|
+
const salt = randomBytes10(SALT_LEN);
|
|
30347
30658
|
const key = scryptSync2(passphrase, salt, KEY_LEN);
|
|
30348
|
-
const iv =
|
|
30659
|
+
const iv = randomBytes10(IV_LEN);
|
|
30349
30660
|
const cipher = createCipheriv2(CIPHER_ALGO, key, iv);
|
|
30350
30661
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
30351
30662
|
const tag = cipher.getAuthTag();
|
|
@@ -30402,8 +30713,8 @@ var init_secret_vault = __esm({
|
|
|
30402
30713
|
|
|
30403
30714
|
// packages/cli/dist/tui/p2p/peer-mesh.js
|
|
30404
30715
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
30405
|
-
import { createServer as
|
|
30406
|
-
import { randomBytes as
|
|
30716
|
+
import { createServer as createServer4 } from "node:http";
|
|
30717
|
+
import { randomBytes as randomBytes11, createHash as createHash3, generateKeyPairSync } from "node:crypto";
|
|
30407
30718
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
30408
30719
|
var init_peer_mesh = __esm({
|
|
30409
30720
|
"packages/cli/dist/tui/p2p/peer-mesh.js"() {
|
|
@@ -30455,14 +30766,14 @@ var init_peer_mesh = __esm({
|
|
|
30455
30766
|
this.peerId = createHash3("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
30456
30767
|
this.capabilities = options.capabilities;
|
|
30457
30768
|
this.displayName = options.displayName;
|
|
30458
|
-
this._authKey = options.authKey ??
|
|
30769
|
+
this._authKey = options.authKey ?? randomBytes11(24).toString("base64url");
|
|
30459
30770
|
}
|
|
30460
30771
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
30461
30772
|
/** Start the mesh node — creates WS server and connects to bootstrap peers */
|
|
30462
30773
|
async start() {
|
|
30463
30774
|
const port = await this.findFreePort();
|
|
30464
30775
|
this._port = port;
|
|
30465
|
-
this.server =
|
|
30776
|
+
this.server = createServer4();
|
|
30466
30777
|
this.wss = new import_websocket_server.default({ server: this.server });
|
|
30467
30778
|
this.wss.on("connection", (ws, req) => {
|
|
30468
30779
|
this.handleInboundConnection(ws, req.url ?? "");
|
|
@@ -30619,7 +30930,7 @@ var init_peer_mesh = __esm({
|
|
|
30619
30930
|
if (!ws || ws.readyState !== import_websocket.default.OPEN) {
|
|
30620
30931
|
throw new Error(`Peer ${peerId} not connected`);
|
|
30621
30932
|
}
|
|
30622
|
-
const msgId =
|
|
30933
|
+
const msgId = randomBytes11(8).toString("hex");
|
|
30623
30934
|
return new Promise((resolve32, reject) => {
|
|
30624
30935
|
const timeout = setTimeout(() => {
|
|
30625
30936
|
this.pendingRequests.delete(msgId);
|
|
@@ -30840,7 +31151,7 @@ var init_peer_mesh = __esm({
|
|
|
30840
31151
|
const msg = {
|
|
30841
31152
|
type,
|
|
30842
31153
|
from: this.peerId,
|
|
30843
|
-
msgId: msgId ??
|
|
31154
|
+
msgId: msgId ?? randomBytes11(8).toString("hex"),
|
|
30844
31155
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30845
31156
|
payload
|
|
30846
31157
|
};
|
|
@@ -30848,7 +31159,7 @@ var init_peer_mesh = __esm({
|
|
|
30848
31159
|
}
|
|
30849
31160
|
findFreePort() {
|
|
30850
31161
|
return new Promise((resolve32, reject) => {
|
|
30851
|
-
const srv =
|
|
31162
|
+
const srv = createServer4();
|
|
30852
31163
|
srv.listen(0, "127.0.0.1", () => {
|
|
30853
31164
|
const addr = srv.address();
|
|
30854
31165
|
if (addr && typeof addr === "object") {
|
|
@@ -31476,13 +31787,13 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31476
31787
|
try {
|
|
31477
31788
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
31478
31789
|
const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
|
|
31479
|
-
const { join:
|
|
31790
|
+
const { join: join58 } = await import("node:path");
|
|
31480
31791
|
const cwd4 = process.cwd();
|
|
31481
31792
|
const nexusTool = new NexusTool2(cwd4);
|
|
31482
31793
|
const nexusDir = nexusTool.getNexusDir();
|
|
31483
31794
|
let isLocalPeer = false;
|
|
31484
31795
|
try {
|
|
31485
|
-
const statusPath =
|
|
31796
|
+
const statusPath = join58(nexusDir, "status.json");
|
|
31486
31797
|
if (existsSync45(statusPath)) {
|
|
31487
31798
|
const status = JSON.parse(readFileSync33(statusPath, "utf8"));
|
|
31488
31799
|
if (status.peerId === peerId)
|
|
@@ -31491,7 +31802,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31491
31802
|
} catch {
|
|
31492
31803
|
}
|
|
31493
31804
|
if (isLocalPeer) {
|
|
31494
|
-
const pricingPath =
|
|
31805
|
+
const pricingPath = join58(nexusDir, "pricing.json");
|
|
31495
31806
|
if (existsSync45(pricingPath)) {
|
|
31496
31807
|
try {
|
|
31497
31808
|
const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
|
|
@@ -31508,7 +31819,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31508
31819
|
}
|
|
31509
31820
|
}
|
|
31510
31821
|
}
|
|
31511
|
-
const cachePath =
|
|
31822
|
+
const cachePath = join58(nexusDir, "peer-models-cache.json");
|
|
31512
31823
|
if (existsSync45(cachePath)) {
|
|
31513
31824
|
try {
|
|
31514
31825
|
const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
|
|
@@ -31626,7 +31937,7 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
31626
31937
|
} catch {
|
|
31627
31938
|
}
|
|
31628
31939
|
if (isLocalPeer) {
|
|
31629
|
-
const pricingPath =
|
|
31940
|
+
const pricingPath = join58(nexusDir, "pricing.json");
|
|
31630
31941
|
if (existsSync45(pricingPath)) {
|
|
31631
31942
|
try {
|
|
31632
31943
|
const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
|
|
@@ -31899,12 +32210,12 @@ var init_render2 = __esm({
|
|
|
31899
32210
|
|
|
31900
32211
|
// packages/prompts/dist/promptLoader.js
|
|
31901
32212
|
import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
|
|
31902
|
-
import { join as
|
|
32213
|
+
import { join as join39, dirname as dirname15 } from "node:path";
|
|
31903
32214
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
31904
32215
|
function loadPrompt2(promptPath, vars) {
|
|
31905
32216
|
let content = cache2.get(promptPath);
|
|
31906
32217
|
if (content === void 0) {
|
|
31907
|
-
const fullPath =
|
|
32218
|
+
const fullPath = join39(PROMPTS_DIR2, promptPath);
|
|
31908
32219
|
if (!existsSync30(fullPath)) {
|
|
31909
32220
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
31910
32221
|
}
|
|
@@ -31921,8 +32232,8 @@ var init_promptLoader2 = __esm({
|
|
|
31921
32232
|
"use strict";
|
|
31922
32233
|
__filename2 = fileURLToPath9(import.meta.url);
|
|
31923
32234
|
__dirname5 = dirname15(__filename2);
|
|
31924
|
-
devPath =
|
|
31925
|
-
publishedPath =
|
|
32235
|
+
devPath = join39(__dirname5, "..", "templates");
|
|
32236
|
+
publishedPath = join39(__dirname5, "..", "prompts", "templates");
|
|
31926
32237
|
PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
|
|
31927
32238
|
cache2 = /* @__PURE__ */ new Map();
|
|
31928
32239
|
}
|
|
@@ -32034,7 +32345,7 @@ var init_task_templates = __esm({
|
|
|
32034
32345
|
});
|
|
32035
32346
|
|
|
32036
32347
|
// packages/prompts/dist/index.js
|
|
32037
|
-
import { join as
|
|
32348
|
+
import { join as join40, dirname as dirname16 } from "node:path";
|
|
32038
32349
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
32039
32350
|
var _dir, _packageRoot;
|
|
32040
32351
|
var init_dist6 = __esm({
|
|
@@ -32045,21 +32356,21 @@ var init_dist6 = __esm({
|
|
|
32045
32356
|
init_task_templates();
|
|
32046
32357
|
init_render2();
|
|
32047
32358
|
_dir = dirname16(fileURLToPath10(import.meta.url));
|
|
32048
|
-
_packageRoot =
|
|
32359
|
+
_packageRoot = join40(_dir, "..");
|
|
32049
32360
|
}
|
|
32050
32361
|
});
|
|
32051
32362
|
|
|
32052
32363
|
// packages/cli/dist/tui/oa-directory.js
|
|
32053
|
-
import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as
|
|
32054
|
-
import { join as
|
|
32364
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync6 } from "node:fs";
|
|
32365
|
+
import { join as join41, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
32055
32366
|
import { homedir as homedir9 } from "node:os";
|
|
32056
32367
|
function initOaDirectory(repoRoot) {
|
|
32057
|
-
const oaPath =
|
|
32368
|
+
const oaPath = join41(repoRoot, OA_DIR);
|
|
32058
32369
|
for (const sub of SUBDIRS) {
|
|
32059
|
-
mkdirSync11(
|
|
32370
|
+
mkdirSync11(join41(oaPath, sub), { recursive: true });
|
|
32060
32371
|
}
|
|
32061
32372
|
try {
|
|
32062
|
-
const gitignorePath =
|
|
32373
|
+
const gitignorePath = join41(repoRoot, ".gitignore");
|
|
32063
32374
|
const settingsPattern = ".oa/settings.json";
|
|
32064
32375
|
if (existsSync31(gitignorePath)) {
|
|
32065
32376
|
const content = readFileSync22(gitignorePath, "utf-8");
|
|
@@ -32072,10 +32383,10 @@ function initOaDirectory(repoRoot) {
|
|
|
32072
32383
|
return oaPath;
|
|
32073
32384
|
}
|
|
32074
32385
|
function hasOaDirectory(repoRoot) {
|
|
32075
|
-
return existsSync31(
|
|
32386
|
+
return existsSync31(join41(repoRoot, OA_DIR, "index"));
|
|
32076
32387
|
}
|
|
32077
32388
|
function loadProjectSettings(repoRoot) {
|
|
32078
|
-
const settingsPath =
|
|
32389
|
+
const settingsPath = join41(repoRoot, OA_DIR, "settings.json");
|
|
32079
32390
|
try {
|
|
32080
32391
|
if (existsSync31(settingsPath)) {
|
|
32081
32392
|
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
@@ -32085,14 +32396,14 @@ function loadProjectSettings(repoRoot) {
|
|
|
32085
32396
|
return {};
|
|
32086
32397
|
}
|
|
32087
32398
|
function saveProjectSettings(repoRoot, settings) {
|
|
32088
|
-
const oaPath =
|
|
32399
|
+
const oaPath = join41(repoRoot, OA_DIR);
|
|
32089
32400
|
mkdirSync11(oaPath, { recursive: true });
|
|
32090
32401
|
const existing = loadProjectSettings(repoRoot);
|
|
32091
32402
|
const merged = { ...existing, ...settings };
|
|
32092
|
-
writeFileSync12(
|
|
32403
|
+
writeFileSync12(join41(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
32093
32404
|
}
|
|
32094
32405
|
function loadGlobalSettings() {
|
|
32095
|
-
const settingsPath =
|
|
32406
|
+
const settingsPath = join41(homedir9(), ".open-agents", "settings.json");
|
|
32096
32407
|
try {
|
|
32097
32408
|
if (existsSync31(settingsPath)) {
|
|
32098
32409
|
return JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
@@ -32102,11 +32413,11 @@ function loadGlobalSettings() {
|
|
|
32102
32413
|
return {};
|
|
32103
32414
|
}
|
|
32104
32415
|
function saveGlobalSettings(settings) {
|
|
32105
|
-
const dir =
|
|
32416
|
+
const dir = join41(homedir9(), ".open-agents");
|
|
32106
32417
|
mkdirSync11(dir, { recursive: true });
|
|
32107
32418
|
const existing = loadGlobalSettings();
|
|
32108
32419
|
const merged = { ...existing, ...settings };
|
|
32109
|
-
writeFileSync12(
|
|
32420
|
+
writeFileSync12(join41(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
32110
32421
|
}
|
|
32111
32422
|
function resolveSettings(repoRoot) {
|
|
32112
32423
|
const global = loadGlobalSettings();
|
|
@@ -32121,7 +32432,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
32121
32432
|
while (dir && !visited.has(dir)) {
|
|
32122
32433
|
visited.add(dir);
|
|
32123
32434
|
for (const name of CONTEXT_FILES) {
|
|
32124
|
-
const filePath =
|
|
32435
|
+
const filePath = join41(dir, name);
|
|
32125
32436
|
const normalizedName = name.toLowerCase();
|
|
32126
32437
|
if (existsSync31(filePath) && !seen.has(filePath)) {
|
|
32127
32438
|
seen.add(filePath);
|
|
@@ -32140,7 +32451,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
32140
32451
|
}
|
|
32141
32452
|
}
|
|
32142
32453
|
}
|
|
32143
|
-
const projectMap =
|
|
32454
|
+
const projectMap = join41(dir, OA_DIR, "context", "project-map.md");
|
|
32144
32455
|
if (existsSync31(projectMap) && !seen.has(projectMap)) {
|
|
32145
32456
|
seen.add(projectMap);
|
|
32146
32457
|
try {
|
|
@@ -32156,7 +32467,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
32156
32467
|
} catch {
|
|
32157
32468
|
}
|
|
32158
32469
|
}
|
|
32159
|
-
const parent =
|
|
32470
|
+
const parent = join41(dir, "..");
|
|
32160
32471
|
if (parent === dir)
|
|
32161
32472
|
break;
|
|
32162
32473
|
dir = parent;
|
|
@@ -32174,7 +32485,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
32174
32485
|
return found;
|
|
32175
32486
|
}
|
|
32176
32487
|
function readIndexMeta(repoRoot) {
|
|
32177
|
-
const metaPath =
|
|
32488
|
+
const metaPath = join41(repoRoot, OA_DIR, "index", "meta.json");
|
|
32178
32489
|
try {
|
|
32179
32490
|
return JSON.parse(readFileSync22(metaPath, "utf-8"));
|
|
32180
32491
|
} catch {
|
|
@@ -32227,28 +32538,28 @@ ${tree}\`\`\`
|
|
|
32227
32538
|
sections.push("");
|
|
32228
32539
|
}
|
|
32229
32540
|
const content = sections.join("\n");
|
|
32230
|
-
const contextDir =
|
|
32541
|
+
const contextDir = join41(repoRoot, OA_DIR, "context");
|
|
32231
32542
|
mkdirSync11(contextDir, { recursive: true });
|
|
32232
|
-
writeFileSync12(
|
|
32543
|
+
writeFileSync12(join41(contextDir, "project-map.md"), content, "utf-8");
|
|
32233
32544
|
return content;
|
|
32234
32545
|
}
|
|
32235
32546
|
function saveSession(repoRoot, session) {
|
|
32236
|
-
const historyDir =
|
|
32547
|
+
const historyDir = join41(repoRoot, OA_DIR, "history");
|
|
32237
32548
|
mkdirSync11(historyDir, { recursive: true });
|
|
32238
|
-
writeFileSync12(
|
|
32549
|
+
writeFileSync12(join41(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
32239
32550
|
}
|
|
32240
32551
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
32241
|
-
const historyDir =
|
|
32552
|
+
const historyDir = join41(repoRoot, OA_DIR, "history");
|
|
32242
32553
|
if (!existsSync31(historyDir))
|
|
32243
32554
|
return [];
|
|
32244
32555
|
try {
|
|
32245
32556
|
const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
32246
|
-
const stat5 = statSync11(
|
|
32557
|
+
const stat5 = statSync11(join41(historyDir, f));
|
|
32247
32558
|
return { file: f, mtime: stat5.mtimeMs };
|
|
32248
32559
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
32249
32560
|
return files.map((f) => {
|
|
32250
32561
|
try {
|
|
32251
|
-
return JSON.parse(readFileSync22(
|
|
32562
|
+
return JSON.parse(readFileSync22(join41(historyDir, f.file), "utf-8"));
|
|
32252
32563
|
} catch {
|
|
32253
32564
|
return null;
|
|
32254
32565
|
}
|
|
@@ -32258,18 +32569,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
32258
32569
|
}
|
|
32259
32570
|
}
|
|
32260
32571
|
function savePendingTask(repoRoot, task) {
|
|
32261
|
-
const historyDir =
|
|
32572
|
+
const historyDir = join41(repoRoot, OA_DIR, "history");
|
|
32262
32573
|
mkdirSync11(historyDir, { recursive: true });
|
|
32263
|
-
writeFileSync12(
|
|
32574
|
+
writeFileSync12(join41(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
32264
32575
|
}
|
|
32265
32576
|
function loadPendingTask(repoRoot) {
|
|
32266
|
-
const filePath =
|
|
32577
|
+
const filePath = join41(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
32267
32578
|
try {
|
|
32268
32579
|
if (!existsSync31(filePath))
|
|
32269
32580
|
return null;
|
|
32270
32581
|
const data = JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
32271
32582
|
try {
|
|
32272
|
-
|
|
32583
|
+
unlinkSync6(filePath);
|
|
32273
32584
|
} catch {
|
|
32274
32585
|
}
|
|
32275
32586
|
return data;
|
|
@@ -32278,9 +32589,9 @@ function loadPendingTask(repoRoot) {
|
|
|
32278
32589
|
}
|
|
32279
32590
|
}
|
|
32280
32591
|
function saveSessionContext(repoRoot, entry) {
|
|
32281
|
-
const contextDir =
|
|
32592
|
+
const contextDir = join41(repoRoot, OA_DIR, "context");
|
|
32282
32593
|
mkdirSync11(contextDir, { recursive: true });
|
|
32283
|
-
const filePath =
|
|
32594
|
+
const filePath = join41(contextDir, CONTEXT_SAVE_FILE);
|
|
32284
32595
|
let ctx;
|
|
32285
32596
|
try {
|
|
32286
32597
|
if (existsSync31(filePath)) {
|
|
@@ -32299,7 +32610,7 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
32299
32610
|
writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
32300
32611
|
}
|
|
32301
32612
|
function loadSessionContext(repoRoot) {
|
|
32302
|
-
const filePath =
|
|
32613
|
+
const filePath = join41(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
32303
32614
|
try {
|
|
32304
32615
|
if (!existsSync31(filePath))
|
|
32305
32616
|
return null;
|
|
@@ -32350,7 +32661,7 @@ function detectManifests(repoRoot) {
|
|
|
32350
32661
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
32351
32662
|
];
|
|
32352
32663
|
for (const check of checks) {
|
|
32353
|
-
const filePath =
|
|
32664
|
+
const filePath = join41(repoRoot, check.file);
|
|
32354
32665
|
if (existsSync31(filePath)) {
|
|
32355
32666
|
let name;
|
|
32356
32667
|
if (check.nameField) {
|
|
@@ -32384,7 +32695,7 @@ function findKeyFiles(repoRoot) {
|
|
|
32384
32695
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
32385
32696
|
];
|
|
32386
32697
|
for (const check of checks) {
|
|
32387
|
-
if (existsSync31(
|
|
32698
|
+
if (existsSync31(join41(repoRoot, check.pattern))) {
|
|
32388
32699
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
32389
32700
|
}
|
|
32390
32701
|
}
|
|
@@ -32410,12 +32721,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
32410
32721
|
if (entry.isDirectory()) {
|
|
32411
32722
|
let fileCount = 0;
|
|
32412
32723
|
try {
|
|
32413
|
-
fileCount = readdirSync8(
|
|
32724
|
+
fileCount = readdirSync8(join41(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
32414
32725
|
} catch {
|
|
32415
32726
|
}
|
|
32416
32727
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
32417
32728
|
`;
|
|
32418
|
-
result += buildDirTree(
|
|
32729
|
+
result += buildDirTree(join41(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
32419
32730
|
} else if (depth < maxDepth) {
|
|
32420
32731
|
result += `${prefix}${connector}${entry.name}
|
|
32421
32732
|
`;
|
|
@@ -32435,7 +32746,7 @@ function loadUsageFile(filePath) {
|
|
|
32435
32746
|
return { records: [] };
|
|
32436
32747
|
}
|
|
32437
32748
|
function saveUsageFile(filePath, data) {
|
|
32438
|
-
const dir =
|
|
32749
|
+
const dir = join41(filePath, "..");
|
|
32439
32750
|
mkdirSync11(dir, { recursive: true });
|
|
32440
32751
|
writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
32441
32752
|
}
|
|
@@ -32465,15 +32776,15 @@ function recordUsage(kind, value, opts) {
|
|
|
32465
32776
|
}
|
|
32466
32777
|
saveUsageFile(filePath, data);
|
|
32467
32778
|
};
|
|
32468
|
-
update(
|
|
32779
|
+
update(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
|
|
32469
32780
|
if (opts?.repoRoot) {
|
|
32470
|
-
update(
|
|
32781
|
+
update(join41(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
32471
32782
|
}
|
|
32472
32783
|
}
|
|
32473
32784
|
function loadUsageHistory(kind, repoRoot) {
|
|
32474
|
-
const globalPath =
|
|
32785
|
+
const globalPath = join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
|
|
32475
32786
|
const globalData = loadUsageFile(globalPath);
|
|
32476
|
-
const localData = repoRoot ? loadUsageFile(
|
|
32787
|
+
const localData = repoRoot ? loadUsageFile(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
|
|
32477
32788
|
const map = /* @__PURE__ */ new Map();
|
|
32478
32789
|
for (const r of globalData.records) {
|
|
32479
32790
|
if (r.kind !== kind)
|
|
@@ -32504,9 +32815,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
|
|
|
32504
32815
|
saveUsageFile(filePath, data);
|
|
32505
32816
|
}
|
|
32506
32817
|
};
|
|
32507
|
-
remove(
|
|
32818
|
+
remove(join41(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
|
|
32508
32819
|
if (repoRoot) {
|
|
32509
|
-
remove(
|
|
32820
|
+
remove(join41(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
|
|
32510
32821
|
}
|
|
32511
32822
|
}
|
|
32512
32823
|
var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
@@ -32554,10 +32865,10 @@ var init_oa_directory = __esm({
|
|
|
32554
32865
|
|
|
32555
32866
|
// packages/cli/dist/tui/setup.js
|
|
32556
32867
|
import * as readline from "node:readline";
|
|
32557
|
-
import { execSync as execSync25, spawn as
|
|
32868
|
+
import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
|
|
32558
32869
|
import { promisify as promisify5 } from "node:util";
|
|
32559
32870
|
import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
|
|
32560
|
-
import { join as
|
|
32871
|
+
import { join as join42 } from "node:path";
|
|
32561
32872
|
import { homedir as homedir10, platform } from "node:os";
|
|
32562
32873
|
function detectSystemSpecs() {
|
|
32563
32874
|
let totalRamGB = 0;
|
|
@@ -32952,7 +33263,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
32952
33263
|
process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
|
|
32953
33264
|
`);
|
|
32954
33265
|
try {
|
|
32955
|
-
const child =
|
|
33266
|
+
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
32956
33267
|
child.unref();
|
|
32957
33268
|
} catch {
|
|
32958
33269
|
process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
|
|
@@ -33420,7 +33731,7 @@ async function doSetup(config, rl) {
|
|
|
33420
33731
|
${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
|
|
33421
33732
|
`);
|
|
33422
33733
|
try {
|
|
33423
|
-
const child =
|
|
33734
|
+
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
33424
33735
|
child.unref();
|
|
33425
33736
|
await new Promise((resolve32) => setTimeout(resolve32, 3e3));
|
|
33426
33737
|
try {
|
|
@@ -33448,7 +33759,7 @@ async function doSetup(config, rl) {
|
|
|
33448
33759
|
${c2.cyan("\u25CF")} Starting ollama serve...
|
|
33449
33760
|
`);
|
|
33450
33761
|
try {
|
|
33451
|
-
const child =
|
|
33762
|
+
const child = spawn18("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
33452
33763
|
child.unref();
|
|
33453
33764
|
await new Promise((resolve32) => setTimeout(resolve32, 3e3));
|
|
33454
33765
|
try {
|
|
@@ -33598,9 +33909,9 @@ async function doSetup(config, rl) {
|
|
|
33598
33909
|
`PARAMETER num_predict ${numPredict}`,
|
|
33599
33910
|
`PARAMETER stop "<|endoftext|>"`
|
|
33600
33911
|
].join("\n");
|
|
33601
|
-
const modelDir2 =
|
|
33912
|
+
const modelDir2 = join42(homedir10(), ".open-agents", "models");
|
|
33602
33913
|
mkdirSync12(modelDir2, { recursive: true });
|
|
33603
|
-
const modelfilePath =
|
|
33914
|
+
const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
|
|
33604
33915
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
33605
33916
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
33606
33917
|
execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
@@ -33646,7 +33957,7 @@ async function isModelAvailable(config) {
|
|
|
33646
33957
|
}
|
|
33647
33958
|
function isFirstRun() {
|
|
33648
33959
|
try {
|
|
33649
|
-
return !existsSync32(
|
|
33960
|
+
return !existsSync32(join42(homedir10(), ".open-agents", "config.json"));
|
|
33650
33961
|
} catch {
|
|
33651
33962
|
return true;
|
|
33652
33963
|
}
|
|
@@ -33683,7 +33994,7 @@ function detectPkgManager() {
|
|
|
33683
33994
|
return null;
|
|
33684
33995
|
}
|
|
33685
33996
|
function getVenvDir() {
|
|
33686
|
-
return
|
|
33997
|
+
return join42(homedir10(), ".open-agents", "venv");
|
|
33687
33998
|
}
|
|
33688
33999
|
function hasVenvModule() {
|
|
33689
34000
|
try {
|
|
@@ -33695,7 +34006,7 @@ function hasVenvModule() {
|
|
|
33695
34006
|
}
|
|
33696
34007
|
function ensureVenv(log) {
|
|
33697
34008
|
const venvDir = getVenvDir();
|
|
33698
|
-
const venvPip =
|
|
34009
|
+
const venvPip = join42(venvDir, "bin", "pip");
|
|
33699
34010
|
if (existsSync32(venvPip))
|
|
33700
34011
|
return venvDir;
|
|
33701
34012
|
log("Creating Python venv for vision deps...");
|
|
@@ -33708,9 +34019,9 @@ function ensureVenv(log) {
|
|
|
33708
34019
|
return null;
|
|
33709
34020
|
}
|
|
33710
34021
|
try {
|
|
33711
|
-
mkdirSync12(
|
|
34022
|
+
mkdirSync12(join42(homedir10(), ".open-agents"), { recursive: true });
|
|
33712
34023
|
execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
33713
|
-
execSync25(`"${
|
|
34024
|
+
execSync25(`"${join42(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
33714
34025
|
stdio: "pipe",
|
|
33715
34026
|
timeout: 6e4
|
|
33716
34027
|
});
|
|
@@ -33901,11 +34212,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
33901
34212
|
}
|
|
33902
34213
|
}
|
|
33903
34214
|
const venvDir = getVenvDir();
|
|
33904
|
-
const venvBin =
|
|
33905
|
-
const venvMoondream =
|
|
34215
|
+
const venvBin = join42(venvDir, "bin");
|
|
34216
|
+
const venvMoondream = join42(venvBin, "moondream-station");
|
|
33906
34217
|
const venv = ensureVenv(log);
|
|
33907
34218
|
if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
|
|
33908
|
-
const venvPip =
|
|
34219
|
+
const venvPip = join42(venvBin, "pip");
|
|
33909
34220
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
33910
34221
|
try {
|
|
33911
34222
|
execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
@@ -33926,8 +34237,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
33926
34237
|
}
|
|
33927
34238
|
}
|
|
33928
34239
|
if (venv) {
|
|
33929
|
-
const venvPython =
|
|
33930
|
-
const venvPip2 =
|
|
34240
|
+
const venvPython = join42(venvBin, "python");
|
|
34241
|
+
const venvPip2 = join42(venvBin, "pip");
|
|
33931
34242
|
let ocrStackInstalled = false;
|
|
33932
34243
|
try {
|
|
33933
34244
|
execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
@@ -34071,9 +34382,9 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
|
|
|
34071
34382
|
`PARAMETER num_predict ${numPredict}`,
|
|
34072
34383
|
`PARAMETER stop "<|endoftext|>"`
|
|
34073
34384
|
].join("\n");
|
|
34074
|
-
const modelDir2 =
|
|
34385
|
+
const modelDir2 = join42(homedir10(), ".open-agents", "models");
|
|
34075
34386
|
mkdirSync12(modelDir2, { recursive: true });
|
|
34076
|
-
const modelfilePath =
|
|
34387
|
+
const modelfilePath = join42(modelDir2, `Modelfile.${customName}`);
|
|
34077
34388
|
writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
|
|
34078
34389
|
await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
34079
34390
|
timeout: 12e4
|
|
@@ -34148,8 +34459,8 @@ async function ensureNeovim() {
|
|
|
34148
34459
|
const platform5 = process.platform;
|
|
34149
34460
|
const arch = process.arch;
|
|
34150
34461
|
if (platform5 === "linux") {
|
|
34151
|
-
const binDir =
|
|
34152
|
-
const nvimDest =
|
|
34462
|
+
const binDir = join42(homedir10(), ".local", "bin");
|
|
34463
|
+
const nvimDest = join42(binDir, "nvim");
|
|
34153
34464
|
try {
|
|
34154
34465
|
mkdirSync12(binDir, { recursive: true });
|
|
34155
34466
|
} catch {
|
|
@@ -34220,7 +34531,7 @@ async function ensureNeovim() {
|
|
|
34220
34531
|
}
|
|
34221
34532
|
function ensurePathInShellRc(binDir) {
|
|
34222
34533
|
const shell = process.env.SHELL ?? "";
|
|
34223
|
-
const rcFile = shell.includes("zsh") ?
|
|
34534
|
+
const rcFile = shell.includes("zsh") ? join42(homedir10(), ".zshrc") : join42(homedir10(), ".bashrc");
|
|
34224
34535
|
try {
|
|
34225
34536
|
const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
|
|
34226
34537
|
if (rcContent.includes(binDir))
|
|
@@ -34990,9 +35301,9 @@ var init_drop_panel = __esm({
|
|
|
34990
35301
|
});
|
|
34991
35302
|
|
|
34992
35303
|
// packages/cli/dist/tui/neovim-mode.js
|
|
34993
|
-
import { existsSync as existsSync34, unlinkSync as
|
|
34994
|
-
import { tmpdir as
|
|
34995
|
-
import { join as
|
|
35304
|
+
import { existsSync as existsSync34, unlinkSync as unlinkSync7 } from "node:fs";
|
|
35305
|
+
import { tmpdir as tmpdir8 } from "node:os";
|
|
35306
|
+
import { join as join43 } from "node:path";
|
|
34996
35307
|
import { execSync as execSync26 } from "node:child_process";
|
|
34997
35308
|
function isNeovimActive() {
|
|
34998
35309
|
return _state !== null && !_state.cleanedUp;
|
|
@@ -35040,10 +35351,10 @@ async function startNeovimMode(opts) {
|
|
|
35040
35351
|
);
|
|
35041
35352
|
} catch {
|
|
35042
35353
|
}
|
|
35043
|
-
const socketPath =
|
|
35354
|
+
const socketPath = join43(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
|
|
35044
35355
|
try {
|
|
35045
35356
|
if (existsSync34(socketPath))
|
|
35046
|
-
|
|
35357
|
+
unlinkSync7(socketPath);
|
|
35047
35358
|
} catch {
|
|
35048
35359
|
}
|
|
35049
35360
|
const ptyCols = opts.cols;
|
|
@@ -35336,7 +35647,7 @@ function doCleanup(state) {
|
|
|
35336
35647
|
}
|
|
35337
35648
|
try {
|
|
35338
35649
|
if (existsSync34(state.socketPath))
|
|
35339
|
-
|
|
35650
|
+
unlinkSync7(state.socketPath);
|
|
35340
35651
|
} catch {
|
|
35341
35652
|
}
|
|
35342
35653
|
if (state.stdinHandler) {
|
|
@@ -35391,9 +35702,9 @@ __export(voice_exports, {
|
|
|
35391
35702
|
registerCustomOnnxModel: () => registerCustomOnnxModel,
|
|
35392
35703
|
resetNarrationContext: () => resetNarrationContext
|
|
35393
35704
|
});
|
|
35394
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as
|
|
35395
|
-
import { join as
|
|
35396
|
-
import { homedir as homedir11, tmpdir as
|
|
35705
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync8, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
|
|
35706
|
+
import { join as join44 } from "node:path";
|
|
35707
|
+
import { homedir as homedir11, tmpdir as tmpdir9, platform as platform2 } from "node:os";
|
|
35397
35708
|
import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
|
|
35398
35709
|
import { createRequire } from "node:module";
|
|
35399
35710
|
function registerCustomOnnxModel(id, label) {
|
|
@@ -35414,34 +35725,34 @@ function listVoiceModels() {
|
|
|
35414
35725
|
}));
|
|
35415
35726
|
}
|
|
35416
35727
|
function voiceDir() {
|
|
35417
|
-
return
|
|
35728
|
+
return join44(homedir11(), ".open-agents", "voice");
|
|
35418
35729
|
}
|
|
35419
35730
|
function modelsDir() {
|
|
35420
|
-
return
|
|
35731
|
+
return join44(voiceDir(), "models");
|
|
35421
35732
|
}
|
|
35422
35733
|
function modelDir(id) {
|
|
35423
|
-
return
|
|
35734
|
+
return join44(modelsDir(), id);
|
|
35424
35735
|
}
|
|
35425
35736
|
function modelOnnxPath(id) {
|
|
35426
|
-
return
|
|
35737
|
+
return join44(modelDir(id), "model.onnx");
|
|
35427
35738
|
}
|
|
35428
35739
|
function modelConfigPath(id) {
|
|
35429
|
-
return
|
|
35740
|
+
return join44(modelDir(id), "config.json");
|
|
35430
35741
|
}
|
|
35431
35742
|
function luxttsVenvDir() {
|
|
35432
|
-
return
|
|
35743
|
+
return join44(voiceDir(), "luxtts-venv");
|
|
35433
35744
|
}
|
|
35434
35745
|
function luxttsVenvPy() {
|
|
35435
|
-
return platform2() === "win32" ?
|
|
35746
|
+
return platform2() === "win32" ? join44(luxttsVenvDir(), "Scripts", "python.exe") : join44(luxttsVenvDir(), "bin", "python3");
|
|
35436
35747
|
}
|
|
35437
35748
|
function luxttsRepoDir() {
|
|
35438
|
-
return
|
|
35749
|
+
return join44(voiceDir(), "LuxTTS");
|
|
35439
35750
|
}
|
|
35440
35751
|
function luxttsCloneRefsDir() {
|
|
35441
|
-
return
|
|
35752
|
+
return join44(voiceDir(), "clone-refs");
|
|
35442
35753
|
}
|
|
35443
35754
|
function luxttsInferScript() {
|
|
35444
|
-
return
|
|
35755
|
+
return join44(voiceDir(), "luxtts-infer.py");
|
|
35445
35756
|
}
|
|
35446
35757
|
function emotionToPitchBias(emotion, stark = false, autist = false) {
|
|
35447
35758
|
if (autist)
|
|
@@ -36249,7 +36560,7 @@ var init_voice = __esm({
|
|
|
36249
36560
|
const refsDir = luxttsCloneRefsDir();
|
|
36250
36561
|
const targets = ["glados", "overwatch"];
|
|
36251
36562
|
for (const modelId of targets) {
|
|
36252
|
-
const refFile =
|
|
36563
|
+
const refFile = join44(refsDir, `${modelId}-ref.wav`);
|
|
36253
36564
|
if (existsSync35(refFile))
|
|
36254
36565
|
continue;
|
|
36255
36566
|
try {
|
|
@@ -36329,7 +36640,7 @@ var init_voice = __esm({
|
|
|
36329
36640
|
}
|
|
36330
36641
|
p = p.replace(/\\ /g, " ");
|
|
36331
36642
|
if (p.startsWith("~/") || p === "~") {
|
|
36332
|
-
p =
|
|
36643
|
+
p = join44(homedir11(), p.slice(1));
|
|
36333
36644
|
}
|
|
36334
36645
|
if (!existsSync35(p)) {
|
|
36335
36646
|
return `File not found: ${p}
|
|
@@ -36343,7 +36654,7 @@ var init_voice = __esm({
|
|
|
36343
36654
|
const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
36344
36655
|
const ts = Date.now().toString(36);
|
|
36345
36656
|
const destFilename = `clone-${srcName}-${ts}.${ext}`;
|
|
36346
|
-
const destPath =
|
|
36657
|
+
const destPath = join44(refsDir, destFilename);
|
|
36347
36658
|
try {
|
|
36348
36659
|
const data = readFileSync24(audioPath);
|
|
36349
36660
|
writeFileSync14(destPath, data);
|
|
@@ -36388,7 +36699,7 @@ var init_voice = __esm({
|
|
|
36388
36699
|
const refsDir = luxttsCloneRefsDir();
|
|
36389
36700
|
if (!existsSync35(refsDir))
|
|
36390
36701
|
mkdirSync13(refsDir, { recursive: true });
|
|
36391
|
-
const destPath =
|
|
36702
|
+
const destPath = join44(refsDir, `${sourceModelId}-ref.wav`);
|
|
36392
36703
|
const sampleRate = this.config?.audio?.sample_rate ?? 22050;
|
|
36393
36704
|
this.writeWav(audioData, sampleRate, destPath);
|
|
36394
36705
|
this.luxttsCloneRef = destPath;
|
|
@@ -36404,7 +36715,7 @@ var init_voice = __esm({
|
|
|
36404
36715
|
// -------------------------------------------------------------------------
|
|
36405
36716
|
/** Metadata file for friendly names of clone refs */
|
|
36406
36717
|
static cloneMetaFile() {
|
|
36407
|
-
return
|
|
36718
|
+
return join44(luxttsCloneRefsDir(), "meta.json");
|
|
36408
36719
|
}
|
|
36409
36720
|
loadCloneMeta() {
|
|
36410
36721
|
const p = _VoiceEngine.cloneMetaFile();
|
|
@@ -36438,7 +36749,7 @@ var init_voice = __esm({
|
|
|
36438
36749
|
return _VoiceEngine.AUDIO_EXTS.has(ext);
|
|
36439
36750
|
});
|
|
36440
36751
|
return files.map((f) => {
|
|
36441
|
-
const p =
|
|
36752
|
+
const p = join44(dir, f);
|
|
36442
36753
|
let size = 0;
|
|
36443
36754
|
try {
|
|
36444
36755
|
size = statSync12(p).size;
|
|
@@ -36455,11 +36766,11 @@ var init_voice = __esm({
|
|
|
36455
36766
|
}
|
|
36456
36767
|
/** Delete a clone reference file by filename. Returns true if deleted. */
|
|
36457
36768
|
deleteCloneRef(filename) {
|
|
36458
|
-
const p =
|
|
36769
|
+
const p = join44(luxttsCloneRefsDir(), filename);
|
|
36459
36770
|
if (!existsSync35(p))
|
|
36460
36771
|
return false;
|
|
36461
36772
|
try {
|
|
36462
|
-
|
|
36773
|
+
unlinkSync8(p);
|
|
36463
36774
|
const meta = this.loadCloneMeta();
|
|
36464
36775
|
delete meta[filename];
|
|
36465
36776
|
this.saveCloneMeta(meta);
|
|
@@ -36480,7 +36791,7 @@ var init_voice = __esm({
|
|
|
36480
36791
|
}
|
|
36481
36792
|
/** Set the active clone reference by filename. */
|
|
36482
36793
|
setActiveCloneRef(filename) {
|
|
36483
|
-
const p =
|
|
36794
|
+
const p = join44(luxttsCloneRefsDir(), filename);
|
|
36484
36795
|
if (!existsSync35(p))
|
|
36485
36796
|
return `File not found: ${filename}`;
|
|
36486
36797
|
this.luxttsCloneRef = p;
|
|
@@ -36766,11 +37077,11 @@ var init_voice = __esm({
|
|
|
36766
37077
|
}
|
|
36767
37078
|
this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
|
|
36768
37079
|
}
|
|
36769
|
-
const wavPath =
|
|
37080
|
+
const wavPath = join44(tmpdir9(), `oa-voice-${Date.now()}.wav`);
|
|
36770
37081
|
this.writeWav(audioData, sampleRate, wavPath);
|
|
36771
37082
|
await this.playWav(wavPath);
|
|
36772
37083
|
try {
|
|
36773
|
-
|
|
37084
|
+
unlinkSync8(wavPath);
|
|
36774
37085
|
} catch {
|
|
36775
37086
|
}
|
|
36776
37087
|
}
|
|
@@ -37015,7 +37326,7 @@ var init_voice = __esm({
|
|
|
37015
37326
|
return new Promise((resolve32, reject) => {
|
|
37016
37327
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
37017
37328
|
stdio: ["ignore", "pipe", "pipe"],
|
|
37018
|
-
cwd:
|
|
37329
|
+
cwd: tmpdir9()
|
|
37019
37330
|
});
|
|
37020
37331
|
let stdout = "";
|
|
37021
37332
|
let stderr = "";
|
|
@@ -37109,7 +37420,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37109
37420
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
37110
37421
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
37111
37422
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
37112
|
-
const wavPath =
|
|
37423
|
+
const wavPath = join44(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
|
|
37113
37424
|
const pyScript = [
|
|
37114
37425
|
"import sys, json",
|
|
37115
37426
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -37117,11 +37428,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37117
37428
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
37118
37429
|
].join("; ");
|
|
37119
37430
|
try {
|
|
37120
|
-
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37431
|
+
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
37121
37432
|
} catch (err) {
|
|
37122
37433
|
try {
|
|
37123
37434
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
37124
|
-
execSync27(`${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:
|
|
37435
|
+
execSync27(`${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() });
|
|
37125
37436
|
} catch (err2) {
|
|
37126
37437
|
return;
|
|
37127
37438
|
}
|
|
@@ -37156,7 +37467,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37156
37467
|
}
|
|
37157
37468
|
await this.playWav(wavPath);
|
|
37158
37469
|
try {
|
|
37159
|
-
|
|
37470
|
+
unlinkSync8(wavPath);
|
|
37160
37471
|
} catch {
|
|
37161
37472
|
}
|
|
37162
37473
|
}
|
|
@@ -37177,7 +37488,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37177
37488
|
const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
|
|
37178
37489
|
const mlxVoice = model.mlxVoice ?? "af_heart";
|
|
37179
37490
|
const mlxLangCode = model.mlxLangCode ?? "a";
|
|
37180
|
-
const wavPath =
|
|
37491
|
+
const wavPath = join44(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
|
|
37181
37492
|
const pyScript = [
|
|
37182
37493
|
"import sys, json",
|
|
37183
37494
|
"from mlx_audio.tts import generate as tts_gen",
|
|
@@ -37185,11 +37496,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37185
37496
|
`tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
|
|
37186
37497
|
].join("; ");
|
|
37187
37498
|
try {
|
|
37188
|
-
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd:
|
|
37499
|
+
execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
|
|
37189
37500
|
} catch {
|
|
37190
37501
|
try {
|
|
37191
37502
|
const safeText = cleaned.replace(/'/g, "'\\''");
|
|
37192
|
-
execSync27(`${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:
|
|
37503
|
+
execSync27(`${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() });
|
|
37193
37504
|
} catch {
|
|
37194
37505
|
return null;
|
|
37195
37506
|
}
|
|
@@ -37198,7 +37509,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37198
37509
|
return null;
|
|
37199
37510
|
try {
|
|
37200
37511
|
const data = readFileSync24(wavPath);
|
|
37201
|
-
|
|
37512
|
+
unlinkSync8(wavPath);
|
|
37202
37513
|
return data;
|
|
37203
37514
|
} catch {
|
|
37204
37515
|
return null;
|
|
@@ -37288,7 +37599,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37288
37599
|
}
|
|
37289
37600
|
}
|
|
37290
37601
|
const repoDir = luxttsRepoDir();
|
|
37291
|
-
if (!existsSync35(
|
|
37602
|
+
if (!existsSync35(join44(repoDir, "zipvoice", "luxvoice.py"))) {
|
|
37292
37603
|
renderInfo(" Cloning LuxTTS repository...");
|
|
37293
37604
|
try {
|
|
37294
37605
|
if (existsSync35(repoDir)) {
|
|
@@ -37337,7 +37648,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
37337
37648
|
if (!existsSync35(refsDir))
|
|
37338
37649
|
return;
|
|
37339
37650
|
for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
|
|
37340
|
-
const p =
|
|
37651
|
+
const p = join44(refsDir, name);
|
|
37341
37652
|
if (existsSync35(p)) {
|
|
37342
37653
|
this.luxttsCloneRef = p;
|
|
37343
37654
|
return;
|
|
@@ -37452,7 +37763,7 @@ if __name__ == '__main__':
|
|
|
37452
37763
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
37453
37764
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
37454
37765
|
stdio: ["pipe", "pipe", "pipe"],
|
|
37455
|
-
cwd:
|
|
37766
|
+
cwd: tmpdir9(),
|
|
37456
37767
|
env
|
|
37457
37768
|
});
|
|
37458
37769
|
this._luxttsDaemon = daemon;
|
|
@@ -37534,7 +37845,7 @@ if __name__ == '__main__':
|
|
|
37534
37845
|
const ready = await this.ensureLuxttsDaemon();
|
|
37535
37846
|
if (!ready)
|
|
37536
37847
|
return;
|
|
37537
|
-
const wavPath =
|
|
37848
|
+
const wavPath = join44(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
|
|
37538
37849
|
try {
|
|
37539
37850
|
await this.luxttsRequest({
|
|
37540
37851
|
action: "synthesize",
|
|
@@ -37591,7 +37902,7 @@ if __name__ == '__main__':
|
|
|
37591
37902
|
}
|
|
37592
37903
|
await this.playWav(wavPath);
|
|
37593
37904
|
try {
|
|
37594
|
-
|
|
37905
|
+
unlinkSync8(wavPath);
|
|
37595
37906
|
} catch {
|
|
37596
37907
|
}
|
|
37597
37908
|
}
|
|
@@ -37608,7 +37919,7 @@ if __name__ == '__main__':
|
|
|
37608
37919
|
const ready = await this.ensureLuxttsDaemon();
|
|
37609
37920
|
if (!ready)
|
|
37610
37921
|
return null;
|
|
37611
|
-
const wavPath =
|
|
37922
|
+
const wavPath = join44(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
|
|
37612
37923
|
try {
|
|
37613
37924
|
await this.luxttsRequest({
|
|
37614
37925
|
action: "synthesize",
|
|
@@ -37624,7 +37935,7 @@ if __name__ == '__main__':
|
|
|
37624
37935
|
return null;
|
|
37625
37936
|
try {
|
|
37626
37937
|
const data = readFileSync24(wavPath);
|
|
37627
|
-
|
|
37938
|
+
unlinkSync8(wavPath);
|
|
37628
37939
|
return data;
|
|
37629
37940
|
} catch {
|
|
37630
37941
|
return null;
|
|
@@ -37638,7 +37949,7 @@ if __name__ == '__main__':
|
|
|
37638
37949
|
return;
|
|
37639
37950
|
const arch = process.arch;
|
|
37640
37951
|
mkdirSync13(voiceDir(), { recursive: true });
|
|
37641
|
-
const pkgPath =
|
|
37952
|
+
const pkgPath = join44(voiceDir(), "package.json");
|
|
37642
37953
|
const expectedDeps = {
|
|
37643
37954
|
"onnxruntime-node": "^1.21.0",
|
|
37644
37955
|
"phonemizer": "^1.2.1"
|
|
@@ -37660,17 +37971,17 @@ if __name__ == '__main__':
|
|
|
37660
37971
|
dependencies: expectedDeps
|
|
37661
37972
|
}, null, 2));
|
|
37662
37973
|
}
|
|
37663
|
-
const voiceRequire = createRequire(
|
|
37974
|
+
const voiceRequire = createRequire(join44(voiceDir(), "index.js"));
|
|
37664
37975
|
const probeOnnx = () => {
|
|
37665
37976
|
try {
|
|
37666
|
-
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH:
|
|
37977
|
+
const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join44(voiceDir(), "node_modules") } });
|
|
37667
37978
|
const output = result.toString().trim();
|
|
37668
37979
|
return output === "OK";
|
|
37669
37980
|
} catch {
|
|
37670
37981
|
return false;
|
|
37671
37982
|
}
|
|
37672
37983
|
};
|
|
37673
|
-
const onnxNodeModules =
|
|
37984
|
+
const onnxNodeModules = join44(voiceDir(), "node_modules", "onnxruntime-node");
|
|
37674
37985
|
const onnxInstalled = existsSync35(onnxNodeModules);
|
|
37675
37986
|
if (onnxInstalled && !probeOnnx()) {
|
|
37676
37987
|
throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). 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.`);
|
|
@@ -40014,8 +40325,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
40014
40325
|
if (models.length > 0) {
|
|
40015
40326
|
try {
|
|
40016
40327
|
const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
|
|
40017
|
-
const { join:
|
|
40018
|
-
const cachePath =
|
|
40328
|
+
const { join: join58, dirname: dirname20 } = await import("node:path");
|
|
40329
|
+
const cachePath = join58(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
40019
40330
|
mkdirSync21(dirname20(cachePath), { recursive: true });
|
|
40020
40331
|
writeFileSync20(cachePath, JSON.stringify({
|
|
40021
40332
|
peerId,
|
|
@@ -40168,8 +40479,8 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
40168
40479
|
}
|
|
40169
40480
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
40170
40481
|
process.env.OLLAMA_NUM_PARALLEL = String(n);
|
|
40171
|
-
const { spawn:
|
|
40172
|
-
const child =
|
|
40482
|
+
const { spawn: spawn20 } = await import("node:child_process");
|
|
40483
|
+
const child = spawn20("ollama", ["serve"], {
|
|
40173
40484
|
stdio: "ignore",
|
|
40174
40485
|
detached: true,
|
|
40175
40486
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
|
|
@@ -40216,14 +40527,14 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
40216
40527
|
try {
|
|
40217
40528
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
40218
40529
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
40219
|
-
const { dirname: dirname20, join:
|
|
40530
|
+
const { dirname: dirname20, join: join58 } = await import("node:path");
|
|
40220
40531
|
const { existsSync: existsSync45 } = await import("node:fs");
|
|
40221
40532
|
const req = createRequire4(import.meta.url);
|
|
40222
40533
|
const thisDir = dirname20(fileURLToPath14(import.meta.url));
|
|
40223
40534
|
const candidates = [
|
|
40224
|
-
|
|
40225
|
-
|
|
40226
|
-
|
|
40535
|
+
join58(thisDir, "..", "package.json"),
|
|
40536
|
+
join58(thisDir, "..", "..", "package.json"),
|
|
40537
|
+
join58(thisDir, "..", "..", "..", "package.json")
|
|
40227
40538
|
];
|
|
40228
40539
|
for (const pkgPath of candidates) {
|
|
40229
40540
|
if (existsSync45(pkgPath)) {
|
|
@@ -40941,7 +41252,7 @@ var init_commands = __esm({
|
|
|
40941
41252
|
|
|
40942
41253
|
// packages/cli/dist/tui/project-context.js
|
|
40943
41254
|
import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
|
|
40944
|
-
import { join as
|
|
41255
|
+
import { join as join45, basename as basename10 } from "node:path";
|
|
40945
41256
|
import { execSync as execSync28 } from "node:child_process";
|
|
40946
41257
|
import { homedir as homedir12, platform as platform3, release } from "node:os";
|
|
40947
41258
|
function getModelTier(modelName) {
|
|
@@ -40976,7 +41287,7 @@ function loadProjectMap(repoRoot) {
|
|
|
40976
41287
|
if (!hasOaDirectory(repoRoot)) {
|
|
40977
41288
|
initOaDirectory(repoRoot);
|
|
40978
41289
|
}
|
|
40979
|
-
const mapPath =
|
|
41290
|
+
const mapPath = join45(repoRoot, OA_DIR, "context", "project-map.md");
|
|
40980
41291
|
if (existsSync36(mapPath)) {
|
|
40981
41292
|
try {
|
|
40982
41293
|
const content = readFileSync25(mapPath, "utf-8");
|
|
@@ -41020,17 +41331,17 @@ ${log}`);
|
|
|
41020
41331
|
}
|
|
41021
41332
|
function loadMemoryContext(repoRoot) {
|
|
41022
41333
|
const sections = [];
|
|
41023
|
-
const oaMemDir =
|
|
41334
|
+
const oaMemDir = join45(repoRoot, OA_DIR, "memory");
|
|
41024
41335
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
41025
41336
|
if (oaEntries)
|
|
41026
41337
|
sections.push(oaEntries);
|
|
41027
|
-
const legacyMemDir =
|
|
41338
|
+
const legacyMemDir = join45(repoRoot, ".open-agents", "memory");
|
|
41028
41339
|
if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
|
|
41029
41340
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
41030
41341
|
if (legacyEntries)
|
|
41031
41342
|
sections.push(legacyEntries);
|
|
41032
41343
|
}
|
|
41033
|
-
const globalMemDir =
|
|
41344
|
+
const globalMemDir = join45(homedir12(), ".open-agents", "memory");
|
|
41034
41345
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
41035
41346
|
if (globalEntries)
|
|
41036
41347
|
sections.push(globalEntries);
|
|
@@ -41044,7 +41355,7 @@ function loadMemoryDir(memDir, scope) {
|
|
|
41044
41355
|
const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
|
|
41045
41356
|
for (const file of files.slice(0, 10)) {
|
|
41046
41357
|
try {
|
|
41047
|
-
const raw = readFileSync25(
|
|
41358
|
+
const raw = readFileSync25(join45(memDir, file), "utf-8");
|
|
41048
41359
|
const entries = JSON.parse(raw);
|
|
41049
41360
|
const topic = basename10(file, ".json");
|
|
41050
41361
|
const keys = Object.keys(entries);
|
|
@@ -42068,9 +42379,9 @@ var init_carousel = __esm({
|
|
|
42068
42379
|
|
|
42069
42380
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
42070
42381
|
import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
|
|
42071
|
-
import { join as
|
|
42382
|
+
import { join as join46, basename as basename11 } from "node:path";
|
|
42072
42383
|
function loadToolProfile(repoRoot) {
|
|
42073
|
-
const filePath =
|
|
42384
|
+
const filePath = join46(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
42074
42385
|
try {
|
|
42075
42386
|
if (!existsSync37(filePath))
|
|
42076
42387
|
return null;
|
|
@@ -42080,9 +42391,9 @@ function loadToolProfile(repoRoot) {
|
|
|
42080
42391
|
}
|
|
42081
42392
|
}
|
|
42082
42393
|
function saveToolProfile(repoRoot, profile) {
|
|
42083
|
-
const contextDir =
|
|
42394
|
+
const contextDir = join46(repoRoot, OA_DIR, "context");
|
|
42084
42395
|
mkdirSync14(contextDir, { recursive: true });
|
|
42085
|
-
writeFileSync15(
|
|
42396
|
+
writeFileSync15(join46(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
42086
42397
|
}
|
|
42087
42398
|
function categorizeToolCall(toolName) {
|
|
42088
42399
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -42140,7 +42451,7 @@ function weightedColor(profile) {
|
|
|
42140
42451
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
42141
42452
|
}
|
|
42142
42453
|
function loadCachedDescriptors(repoRoot) {
|
|
42143
|
-
const filePath =
|
|
42454
|
+
const filePath = join46(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
42144
42455
|
try {
|
|
42145
42456
|
if (!existsSync37(filePath))
|
|
42146
42457
|
return null;
|
|
@@ -42151,14 +42462,14 @@ function loadCachedDescriptors(repoRoot) {
|
|
|
42151
42462
|
}
|
|
42152
42463
|
}
|
|
42153
42464
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
42154
|
-
const contextDir =
|
|
42465
|
+
const contextDir = join46(repoRoot, OA_DIR, "context");
|
|
42155
42466
|
mkdirSync14(contextDir, { recursive: true });
|
|
42156
42467
|
const cached = {
|
|
42157
42468
|
phrases,
|
|
42158
42469
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
42159
42470
|
sourceHash
|
|
42160
42471
|
};
|
|
42161
|
-
writeFileSync15(
|
|
42472
|
+
writeFileSync15(join46(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
42162
42473
|
}
|
|
42163
42474
|
function generateDescriptors(repoRoot) {
|
|
42164
42475
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -42206,7 +42517,7 @@ function generateDescriptors(repoRoot) {
|
|
|
42206
42517
|
return phrases;
|
|
42207
42518
|
}
|
|
42208
42519
|
function extractFromPackageJson(repoRoot, tags) {
|
|
42209
|
-
const pkgPath =
|
|
42520
|
+
const pkgPath = join46(repoRoot, "package.json");
|
|
42210
42521
|
try {
|
|
42211
42522
|
if (!existsSync37(pkgPath))
|
|
42212
42523
|
return;
|
|
@@ -42254,7 +42565,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
42254
42565
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
42255
42566
|
];
|
|
42256
42567
|
for (const check of manifestChecks) {
|
|
42257
|
-
if (existsSync37(
|
|
42568
|
+
if (existsSync37(join46(repoRoot, check.file))) {
|
|
42258
42569
|
tags.push(check.tag);
|
|
42259
42570
|
}
|
|
42260
42571
|
}
|
|
@@ -42276,7 +42587,7 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
42276
42587
|
}
|
|
42277
42588
|
}
|
|
42278
42589
|
function extractFromMemory(repoRoot, tags) {
|
|
42279
|
-
const memoryDir =
|
|
42590
|
+
const memoryDir = join46(repoRoot, OA_DIR, "memory");
|
|
42280
42591
|
try {
|
|
42281
42592
|
if (!existsSync37(memoryDir))
|
|
42282
42593
|
return;
|
|
@@ -42285,7 +42596,7 @@ function extractFromMemory(repoRoot, tags) {
|
|
|
42285
42596
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
42286
42597
|
tags.push(topic);
|
|
42287
42598
|
try {
|
|
42288
|
-
const data = JSON.parse(readFileSync26(
|
|
42599
|
+
const data = JSON.parse(readFileSync26(join46(memoryDir, file), "utf-8"));
|
|
42289
42600
|
if (data && typeof data === "object") {
|
|
42290
42601
|
const keys = Object.keys(data).slice(0, 3);
|
|
42291
42602
|
for (const key of keys) {
|
|
@@ -42908,10 +43219,10 @@ var init_stream_renderer = __esm({
|
|
|
42908
43219
|
|
|
42909
43220
|
// packages/cli/dist/tui/edit-history.js
|
|
42910
43221
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
|
|
42911
|
-
import { join as
|
|
43222
|
+
import { join as join47 } from "node:path";
|
|
42912
43223
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
42913
|
-
const historyDir =
|
|
42914
|
-
const logPath =
|
|
43224
|
+
const historyDir = join47(repoRoot, ".oa", "history");
|
|
43225
|
+
const logPath = join47(historyDir, "edits.jsonl");
|
|
42915
43226
|
try {
|
|
42916
43227
|
mkdirSync15(historyDir, { recursive: true });
|
|
42917
43228
|
} catch {
|
|
@@ -43023,12 +43334,12 @@ var init_edit_history = __esm({
|
|
|
43023
43334
|
|
|
43024
43335
|
// packages/cli/dist/tui/promptLoader.js
|
|
43025
43336
|
import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
|
|
43026
|
-
import { join as
|
|
43337
|
+
import { join as join48, dirname as dirname17 } from "node:path";
|
|
43027
43338
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
43028
43339
|
function loadPrompt3(promptPath, vars) {
|
|
43029
43340
|
let content = cache3.get(promptPath);
|
|
43030
43341
|
if (content === void 0) {
|
|
43031
|
-
const fullPath =
|
|
43342
|
+
const fullPath = join48(PROMPTS_DIR3, promptPath);
|
|
43032
43343
|
if (!existsSync38(fullPath)) {
|
|
43033
43344
|
throw new Error(`Prompt file not found: ${fullPath}`);
|
|
43034
43345
|
}
|
|
@@ -43045,8 +43356,8 @@ var init_promptLoader3 = __esm({
|
|
|
43045
43356
|
"use strict";
|
|
43046
43357
|
__filename3 = fileURLToPath11(import.meta.url);
|
|
43047
43358
|
__dirname6 = dirname17(__filename3);
|
|
43048
|
-
devPath2 =
|
|
43049
|
-
publishedPath2 =
|
|
43359
|
+
devPath2 = join48(__dirname6, "..", "..", "prompts");
|
|
43360
|
+
publishedPath2 = join48(__dirname6, "..", "prompts");
|
|
43050
43361
|
PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
|
|
43051
43362
|
cache3 = /* @__PURE__ */ new Map();
|
|
43052
43363
|
}
|
|
@@ -43054,10 +43365,10 @@ var init_promptLoader3 = __esm({
|
|
|
43054
43365
|
|
|
43055
43366
|
// packages/cli/dist/tui/dream-engine.js
|
|
43056
43367
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
|
|
43057
|
-
import { join as
|
|
43368
|
+
import { join as join49, basename as basename12 } from "node:path";
|
|
43058
43369
|
import { execSync as execSync29 } from "node:child_process";
|
|
43059
43370
|
function loadAutoresearchMemory(repoRoot) {
|
|
43060
|
-
const memoryPath =
|
|
43371
|
+
const memoryPath = join49(repoRoot, ".oa", "memory", "autoresearch.json");
|
|
43061
43372
|
if (!existsSync39(memoryPath))
|
|
43062
43373
|
return "";
|
|
43063
43374
|
try {
|
|
@@ -43251,12 +43562,12 @@ var init_dream_engine = __esm({
|
|
|
43251
43562
|
const content = String(args["content"] ?? "");
|
|
43252
43563
|
if (!rawPath)
|
|
43253
43564
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
43254
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
43565
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
|
|
43255
43566
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
43256
43567
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
43257
43568
|
}
|
|
43258
43569
|
try {
|
|
43259
|
-
const dir =
|
|
43570
|
+
const dir = join49(targetPath, "..");
|
|
43260
43571
|
mkdirSync16(dir, { recursive: true });
|
|
43261
43572
|
writeFileSync16(targetPath, content, "utf-8");
|
|
43262
43573
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
@@ -43286,7 +43597,7 @@ var init_dream_engine = __esm({
|
|
|
43286
43597
|
const rawPath = String(args["path"] ?? "");
|
|
43287
43598
|
const oldStr = String(args["old_string"] ?? "");
|
|
43288
43599
|
const newStr = String(args["new_string"] ?? "");
|
|
43289
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ?
|
|
43600
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join49(this.autoresearchDir, basename12(rawPath)) : join49(this.autoresearchDir, rawPath);
|
|
43290
43601
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
43291
43602
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
|
|
43292
43603
|
}
|
|
@@ -43340,12 +43651,12 @@ var init_dream_engine = __esm({
|
|
|
43340
43651
|
const content = String(args["content"] ?? "");
|
|
43341
43652
|
if (!rawPath)
|
|
43342
43653
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
43343
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
43654
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
|
|
43344
43655
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
43345
43656
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
43346
43657
|
}
|
|
43347
43658
|
try {
|
|
43348
|
-
const dir =
|
|
43659
|
+
const dir = join49(targetPath, "..");
|
|
43349
43660
|
mkdirSync16(dir, { recursive: true });
|
|
43350
43661
|
writeFileSync16(targetPath, content, "utf-8");
|
|
43351
43662
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
@@ -43375,7 +43686,7 @@ var init_dream_engine = __esm({
|
|
|
43375
43686
|
const rawPath = String(args["path"] ?? "");
|
|
43376
43687
|
const oldStr = String(args["old_string"] ?? "");
|
|
43377
43688
|
const newStr = String(args["new_string"] ?? "");
|
|
43378
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
43689
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join49(this.dreamsDir, basename12(rawPath)) : join49(this.dreamsDir, rawPath);
|
|
43379
43690
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
43380
43691
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
43381
43692
|
}
|
|
@@ -43442,7 +43753,7 @@ var init_dream_engine = __esm({
|
|
|
43442
43753
|
constructor(config, repoRoot) {
|
|
43443
43754
|
this.config = config;
|
|
43444
43755
|
this.repoRoot = repoRoot;
|
|
43445
|
-
this.dreamsDir =
|
|
43756
|
+
this.dreamsDir = join49(repoRoot, ".oa", "dreams");
|
|
43446
43757
|
this.state = {
|
|
43447
43758
|
mode: "default",
|
|
43448
43759
|
active: false,
|
|
@@ -43526,7 +43837,7 @@ ${result.summary}`;
|
|
|
43526
43837
|
if (mode !== "default" || cycle === totalCycles) {
|
|
43527
43838
|
renderDreamContraction(cycle);
|
|
43528
43839
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
43529
|
-
const summaryPath =
|
|
43840
|
+
const summaryPath = join49(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
43530
43841
|
writeFileSync16(summaryPath, cycleSummary, "utf-8");
|
|
43531
43842
|
}
|
|
43532
43843
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
@@ -43739,7 +44050,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
43739
44050
|
}
|
|
43740
44051
|
/** Build role-specific tool sets for swarm agents */
|
|
43741
44052
|
buildSwarmTools(role, _workspace) {
|
|
43742
|
-
const autoresearchDir =
|
|
44053
|
+
const autoresearchDir = join49(this.repoRoot, ".oa", "autoresearch");
|
|
43743
44054
|
const taskComplete = this.createSwarmTaskCompleteTool(role);
|
|
43744
44055
|
switch (role) {
|
|
43745
44056
|
case "researcher": {
|
|
@@ -44103,7 +44414,7 @@ INSTRUCTIONS:
|
|
|
44103
44414
|
2. Summarize the key learnings and next steps
|
|
44104
44415
|
|
|
44105
44416
|
Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
|
|
44106
|
-
const reportPath =
|
|
44417
|
+
const reportPath = join49(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
|
|
44107
44418
|
const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
|
|
44108
44419
|
|
|
44109
44420
|
**Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
|
|
@@ -44192,7 +44503,7 @@ ${summaryResult}
|
|
|
44192
44503
|
}
|
|
44193
44504
|
/** Save workspace backup for lucid mode */
|
|
44194
44505
|
saveVersionCheckpoint(cycle) {
|
|
44195
|
-
const checkpointDir =
|
|
44506
|
+
const checkpointDir = join49(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
44196
44507
|
try {
|
|
44197
44508
|
mkdirSync16(checkpointDir, { recursive: true });
|
|
44198
44509
|
try {
|
|
@@ -44211,10 +44522,10 @@ ${summaryResult}
|
|
|
44211
44522
|
encoding: "utf-8",
|
|
44212
44523
|
timeout: 5e3
|
|
44213
44524
|
}).trim();
|
|
44214
|
-
writeFileSync16(
|
|
44215
|
-
writeFileSync16(
|
|
44216
|
-
writeFileSync16(
|
|
44217
|
-
writeFileSync16(
|
|
44525
|
+
writeFileSync16(join49(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
44526
|
+
writeFileSync16(join49(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
44527
|
+
writeFileSync16(join49(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
44528
|
+
writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
44218
44529
|
cycle,
|
|
44219
44530
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44220
44531
|
gitHash,
|
|
@@ -44222,7 +44533,7 @@ ${summaryResult}
|
|
|
44222
44533
|
}, null, 2), "utf-8");
|
|
44223
44534
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
44224
44535
|
} catch {
|
|
44225
|
-
writeFileSync16(
|
|
44536
|
+
writeFileSync16(join49(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
44226
44537
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
44227
44538
|
}
|
|
44228
44539
|
} catch (err) {
|
|
@@ -44280,14 +44591,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
44280
44591
|
---
|
|
44281
44592
|
*Auto-generated by open-agents dream engine*
|
|
44282
44593
|
`;
|
|
44283
|
-
writeFileSync16(
|
|
44594
|
+
writeFileSync16(join49(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
44284
44595
|
} catch {
|
|
44285
44596
|
}
|
|
44286
44597
|
}
|
|
44287
44598
|
/** Save dream state for resume/inspection */
|
|
44288
44599
|
saveDreamState() {
|
|
44289
44600
|
try {
|
|
44290
|
-
writeFileSync16(
|
|
44601
|
+
writeFileSync16(join49(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
44291
44602
|
} catch {
|
|
44292
44603
|
}
|
|
44293
44604
|
}
|
|
@@ -44661,8 +44972,8 @@ var init_bless_engine = __esm({
|
|
|
44661
44972
|
});
|
|
44662
44973
|
|
|
44663
44974
|
// packages/cli/dist/tui/dmn-engine.js
|
|
44664
|
-
import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as
|
|
44665
|
-
import { join as
|
|
44975
|
+
import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync9 } from "node:fs";
|
|
44976
|
+
import { join as join50, basename as basename13 } from "node:path";
|
|
44666
44977
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
44667
44978
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
44668
44979
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -44775,8 +45086,8 @@ var init_dmn_engine = __esm({
|
|
|
44775
45086
|
constructor(config, repoRoot) {
|
|
44776
45087
|
this.config = config;
|
|
44777
45088
|
this.repoRoot = repoRoot;
|
|
44778
|
-
this.stateDir =
|
|
44779
|
-
this.historyDir =
|
|
45089
|
+
this.stateDir = join50(repoRoot, ".oa", "dmn");
|
|
45090
|
+
this.historyDir = join50(repoRoot, ".oa", "dmn", "cycles");
|
|
44780
45091
|
mkdirSync17(this.historyDir, { recursive: true });
|
|
44781
45092
|
this.loadState();
|
|
44782
45093
|
}
|
|
@@ -45366,8 +45677,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
45366
45677
|
async gatherMemoryTopics() {
|
|
45367
45678
|
const topics = [];
|
|
45368
45679
|
const dirs = [
|
|
45369
|
-
|
|
45370
|
-
|
|
45680
|
+
join50(this.repoRoot, ".oa", "memory"),
|
|
45681
|
+
join50(this.repoRoot, ".open-agents", "memory")
|
|
45371
45682
|
];
|
|
45372
45683
|
for (const dir of dirs) {
|
|
45373
45684
|
if (!existsSync40(dir))
|
|
@@ -45386,7 +45697,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
45386
45697
|
}
|
|
45387
45698
|
// ── State persistence ─────────────────────────────────────────────────
|
|
45388
45699
|
loadState() {
|
|
45389
|
-
const path =
|
|
45700
|
+
const path = join50(this.stateDir, "state.json");
|
|
45390
45701
|
if (existsSync40(path)) {
|
|
45391
45702
|
try {
|
|
45392
45703
|
this.state = JSON.parse(readFileSync29(path, "utf-8"));
|
|
@@ -45396,19 +45707,19 @@ OUTPUT: Call task_complete with JSON:
|
|
|
45396
45707
|
}
|
|
45397
45708
|
saveState() {
|
|
45398
45709
|
try {
|
|
45399
|
-
writeFileSync17(
|
|
45710
|
+
writeFileSync17(join50(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
45400
45711
|
} catch {
|
|
45401
45712
|
}
|
|
45402
45713
|
}
|
|
45403
45714
|
saveCycleResult(result) {
|
|
45404
45715
|
try {
|
|
45405
45716
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
45406
|
-
writeFileSync17(
|
|
45717
|
+
writeFileSync17(join50(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
45407
45718
|
const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
45408
45719
|
if (files.length > 50) {
|
|
45409
45720
|
for (const old of files.slice(0, files.length - 50)) {
|
|
45410
45721
|
try {
|
|
45411
|
-
|
|
45722
|
+
unlinkSync9(join50(this.historyDir, old));
|
|
45412
45723
|
} catch {
|
|
45413
45724
|
}
|
|
45414
45725
|
}
|
|
@@ -45422,7 +45733,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
45422
45733
|
|
|
45423
45734
|
// packages/cli/dist/tui/snr-engine.js
|
|
45424
45735
|
import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
|
|
45425
|
-
import { join as
|
|
45736
|
+
import { join as join51, basename as basename14 } from "node:path";
|
|
45426
45737
|
function computeDPrime(signalScores, noiseScores) {
|
|
45427
45738
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
45428
45739
|
return 0;
|
|
@@ -45662,8 +45973,8 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
45662
45973
|
loadMemoryEntries(topics) {
|
|
45663
45974
|
const entries = [];
|
|
45664
45975
|
const dirs = [
|
|
45665
|
-
|
|
45666
|
-
|
|
45976
|
+
join51(this.repoRoot, ".oa", "memory"),
|
|
45977
|
+
join51(this.repoRoot, ".open-agents", "memory")
|
|
45667
45978
|
];
|
|
45668
45979
|
for (const dir of dirs) {
|
|
45669
45980
|
if (!existsSync41(dir))
|
|
@@ -45675,7 +45986,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
45675
45986
|
if (topics.length > 0 && !topics.includes(topic))
|
|
45676
45987
|
continue;
|
|
45677
45988
|
try {
|
|
45678
|
-
const data = JSON.parse(readFileSync30(
|
|
45989
|
+
const data = JSON.parse(readFileSync30(join51(dir, f), "utf-8"));
|
|
45679
45990
|
for (const [key, val] of Object.entries(data)) {
|
|
45680
45991
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
45681
45992
|
entries.push({ topic, key, value });
|
|
@@ -46242,8 +46553,8 @@ var init_tool_policy = __esm({
|
|
|
46242
46553
|
});
|
|
46243
46554
|
|
|
46244
46555
|
// packages/cli/dist/tui/telegram-bridge.js
|
|
46245
|
-
import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as
|
|
46246
|
-
import { join as
|
|
46556
|
+
import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync10, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
|
|
46557
|
+
import { join as join52, resolve as resolve28 } from "node:path";
|
|
46247
46558
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
46248
46559
|
function convertMarkdownToTelegramHTML(md) {
|
|
46249
46560
|
let html = md;
|
|
@@ -47008,7 +47319,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
47008
47319
|
return null;
|
|
47009
47320
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47010
47321
|
const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
|
|
47011
|
-
const localPath =
|
|
47322
|
+
const localPath = join52(this.mediaCacheDir, fileName);
|
|
47012
47323
|
await writeFileAsync(localPath, buffer);
|
|
47013
47324
|
return localPath;
|
|
47014
47325
|
} catch {
|
|
@@ -47096,7 +47407,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
47096
47407
|
for (const [key, entry] of this.mediaCache) {
|
|
47097
47408
|
if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
|
|
47098
47409
|
try {
|
|
47099
|
-
|
|
47410
|
+
unlinkSync10(entry.localPath);
|
|
47100
47411
|
} catch {
|
|
47101
47412
|
}
|
|
47102
47413
|
this.mediaCache.delete(key);
|
|
@@ -47172,11 +47483,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
|
|
|
47172
47483
|
let mimeType = "audio/wav";
|
|
47173
47484
|
try {
|
|
47174
47485
|
const { execSync: execSyncLocal } = await import("node:child_process");
|
|
47175
|
-
const { tmpdir:
|
|
47486
|
+
const { tmpdir: tmpdir11 } = await import("node:os");
|
|
47176
47487
|
const { join: joinPath } = await import("node:path");
|
|
47177
47488
|
const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
|
|
47178
|
-
const tmpWav = joinPath(
|
|
47179
|
-
const tmpOgg = joinPath(
|
|
47489
|
+
const tmpWav = joinPath(tmpdir11(), `oa-tg-voice-${Date.now()}.wav`);
|
|
47490
|
+
const tmpOgg = joinPath(tmpdir11(), `oa-tg-voice-${Date.now()}.ogg`);
|
|
47180
47491
|
writeFs(tmpWav, wavBuffer);
|
|
47181
47492
|
execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
|
|
47182
47493
|
timeout: 15e3,
|
|
@@ -49446,7 +49757,7 @@ var init_status_bar = __esm({
|
|
|
49446
49757
|
import * as readline2 from "node:readline";
|
|
49447
49758
|
import { Writable } from "node:stream";
|
|
49448
49759
|
import { cwd } from "node:process";
|
|
49449
|
-
import { resolve as resolve29, join as
|
|
49760
|
+
import { resolve as resolve29, join as join53, dirname as dirname18, extname as extname10 } from "node:path";
|
|
49450
49761
|
import { createRequire as createRequire2 } from "node:module";
|
|
49451
49762
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
49452
49763
|
import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
|
|
@@ -49470,9 +49781,9 @@ function getVersion3() {
|
|
|
49470
49781
|
const require2 = createRequire2(import.meta.url);
|
|
49471
49782
|
const thisDir = dirname18(fileURLToPath12(import.meta.url));
|
|
49472
49783
|
const candidates = [
|
|
49473
|
-
|
|
49474
|
-
|
|
49475
|
-
|
|
49784
|
+
join53(thisDir, "..", "package.json"),
|
|
49785
|
+
join53(thisDir, "..", "..", "package.json"),
|
|
49786
|
+
join53(thisDir, "..", "..", "..", "package.json")
|
|
49476
49787
|
];
|
|
49477
49788
|
for (const pkgPath of candidates) {
|
|
49478
49789
|
if (existsSync43(pkgPath)) {
|
|
@@ -49563,6 +49874,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
49563
49874
|
new StructuredFileTool(repoRoot),
|
|
49564
49875
|
// Code sandbox (isolated code execution)
|
|
49565
49876
|
new CodeSandboxTool(repoRoot),
|
|
49877
|
+
// Persistent Python REPL — RLM (arxiv:2512.24601)
|
|
49878
|
+
new ReplTool(repoRoot),
|
|
49566
49879
|
// Structured file reading (CSV, JSON, Markdown, binary detection)
|
|
49567
49880
|
new StructuredReadTool(repoRoot),
|
|
49568
49881
|
// Vision tools (Moondream — desktop awareness + point-and-click)
|
|
@@ -49682,15 +49995,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
49682
49995
|
function gatherMemorySnippets(root) {
|
|
49683
49996
|
const snippets = [];
|
|
49684
49997
|
const dirs = [
|
|
49685
|
-
|
|
49686
|
-
|
|
49998
|
+
join53(root, ".oa", "memory"),
|
|
49999
|
+
join53(root, ".open-agents", "memory")
|
|
49687
50000
|
];
|
|
49688
50001
|
for (const dir of dirs) {
|
|
49689
50002
|
if (!existsSync43(dir))
|
|
49690
50003
|
continue;
|
|
49691
50004
|
try {
|
|
49692
50005
|
for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
49693
|
-
const data = JSON.parse(readFileSync32(
|
|
50006
|
+
const data = JSON.parse(readFileSync32(join53(dir, f), "utf-8"));
|
|
49694
50007
|
for (const val of Object.values(data)) {
|
|
49695
50008
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
49696
50009
|
if (v.length > 10)
|
|
@@ -49906,6 +50219,27 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
49906
50219
|
tool.setActiveModel(config.model, hasVision);
|
|
49907
50220
|
}
|
|
49908
50221
|
}
|
|
50222
|
+
for (const tool of tools) {
|
|
50223
|
+
if ("setLlmQueryHandler" in tool && typeof tool.setLlmQueryHandler === "function") {
|
|
50224
|
+
tool.setLlmQueryHandler(async (prompt, context) => {
|
|
50225
|
+
const subPrompt = context ? `${prompt}
|
|
50226
|
+
|
|
50227
|
+
Context:
|
|
50228
|
+
${context}` : prompt;
|
|
50229
|
+
const response = await backend.chatCompletion({
|
|
50230
|
+
messages: [
|
|
50231
|
+
{ role: "system", content: "You are a helpful assistant. Respond concisely and accurately." },
|
|
50232
|
+
{ role: "user", content: subPrompt }
|
|
50233
|
+
],
|
|
50234
|
+
tools: [],
|
|
50235
|
+
temperature: 0,
|
|
50236
|
+
maxTokens: 4096,
|
|
50237
|
+
timeoutMs: 12e4
|
|
50238
|
+
});
|
|
50239
|
+
return response.choices?.[0]?.message?.content ?? "";
|
|
50240
|
+
});
|
|
50241
|
+
}
|
|
50242
|
+
}
|
|
49909
50243
|
runner.registerTools(tools);
|
|
49910
50244
|
runner.registerTool({
|
|
49911
50245
|
name: "memex_retrieve",
|
|
@@ -50654,7 +50988,7 @@ async function startInteractive(config, repoPath) {
|
|
|
50654
50988
|
let p2pGateway = null;
|
|
50655
50989
|
let peerMesh = null;
|
|
50656
50990
|
let inferenceRouter = null;
|
|
50657
|
-
const secretVault = new SecretVault(
|
|
50991
|
+
const secretVault = new SecretVault(join53(repoRoot, ".oa", "vault.enc"));
|
|
50658
50992
|
let adminSessionKey = null;
|
|
50659
50993
|
const callSubAgents = /* @__PURE__ */ new Map();
|
|
50660
50994
|
const streamRenderer = new StreamRenderer();
|
|
@@ -50863,8 +51197,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
50863
51197
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
50864
51198
|
return [hits, line];
|
|
50865
51199
|
}
|
|
50866
|
-
const HISTORY_DIR =
|
|
50867
|
-
const HISTORY_FILE =
|
|
51200
|
+
const HISTORY_DIR = join53(homedir13(), ".open-agents");
|
|
51201
|
+
const HISTORY_FILE = join53(HISTORY_DIR, "repl-history");
|
|
50868
51202
|
const MAX_HISTORY_LINES = 500;
|
|
50869
51203
|
let savedHistory = [];
|
|
50870
51204
|
try {
|
|
@@ -51074,7 +51408,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
51074
51408
|
} catch {
|
|
51075
51409
|
}
|
|
51076
51410
|
try {
|
|
51077
|
-
const oaDir =
|
|
51411
|
+
const oaDir = join53(repoRoot, ".oa");
|
|
51078
51412
|
const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
|
|
51079
51413
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
51080
51414
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -51097,7 +51431,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
51097
51431
|
} catch {
|
|
51098
51432
|
}
|
|
51099
51433
|
try {
|
|
51100
|
-
const oaDir =
|
|
51434
|
+
const oaDir = join53(repoRoot, ".oa");
|
|
51101
51435
|
const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
|
|
51102
51436
|
onInfo: (msg) => writeContent(() => renderInfo(msg)),
|
|
51103
51437
|
onError: (msg) => writeContent(() => renderWarning(msg))
|
|
@@ -51916,7 +52250,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
51916
52250
|
kind,
|
|
51917
52251
|
targetUrl,
|
|
51918
52252
|
authKey,
|
|
51919
|
-
stateDir:
|
|
52253
|
+
stateDir: join53(repoRoot, ".oa"),
|
|
51920
52254
|
passthrough: passthrough ?? false,
|
|
51921
52255
|
loadbalance: loadbalance ?? false,
|
|
51922
52256
|
endpointAuth: passthrough ? currentConfig.apiKey : void 0,
|
|
@@ -51964,7 +52298,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
51964
52298
|
await tunnelGateway.stop();
|
|
51965
52299
|
tunnelGateway = null;
|
|
51966
52300
|
}
|
|
51967
|
-
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir:
|
|
52301
|
+
const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join53(repoRoot, ".oa") });
|
|
51968
52302
|
newTunnel.on("stats", (stats) => {
|
|
51969
52303
|
statusBar.setExposeStatus({
|
|
51970
52304
|
status: stats.status,
|
|
@@ -52226,7 +52560,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
52226
52560
|
}
|
|
52227
52561
|
},
|
|
52228
52562
|
destroyProject() {
|
|
52229
|
-
const oaPath =
|
|
52563
|
+
const oaPath = join53(repoRoot, OA_DIR);
|
|
52230
52564
|
if (existsSync43(oaPath)) {
|
|
52231
52565
|
try {
|
|
52232
52566
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
@@ -53161,7 +53495,7 @@ import { glob } from "glob";
|
|
|
53161
53495
|
import ignore from "ignore";
|
|
53162
53496
|
import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
|
|
53163
53497
|
import { createHash as createHash4 } from "node:crypto";
|
|
53164
|
-
import { join as
|
|
53498
|
+
import { join as join54, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
|
|
53165
53499
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
53166
53500
|
var init_codebase_indexer = __esm({
|
|
53167
53501
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -53205,7 +53539,7 @@ var init_codebase_indexer = __esm({
|
|
|
53205
53539
|
const ig = ignore.default();
|
|
53206
53540
|
if (this.config.respectGitignore) {
|
|
53207
53541
|
try {
|
|
53208
|
-
const gitignoreContent = await readFile17(
|
|
53542
|
+
const gitignoreContent = await readFile17(join54(this.config.rootDir, ".gitignore"), "utf-8");
|
|
53209
53543
|
ig.add(gitignoreContent);
|
|
53210
53544
|
} catch {
|
|
53211
53545
|
}
|
|
@@ -53220,7 +53554,7 @@ var init_codebase_indexer = __esm({
|
|
|
53220
53554
|
for (const relativePath of files) {
|
|
53221
53555
|
if (ig.ignores(relativePath))
|
|
53222
53556
|
continue;
|
|
53223
|
-
const fullPath =
|
|
53557
|
+
const fullPath = join54(this.config.rootDir, relativePath);
|
|
53224
53558
|
try {
|
|
53225
53559
|
const fileStat = await stat4(fullPath);
|
|
53226
53560
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -53266,7 +53600,7 @@ var init_codebase_indexer = __esm({
|
|
|
53266
53600
|
if (!child) {
|
|
53267
53601
|
child = {
|
|
53268
53602
|
name: part,
|
|
53269
|
-
path:
|
|
53603
|
+
path: join54(current.path, part),
|
|
53270
53604
|
type: "directory",
|
|
53271
53605
|
children: []
|
|
53272
53606
|
};
|
|
@@ -53607,7 +53941,7 @@ var config_exports = {};
|
|
|
53607
53941
|
__export(config_exports, {
|
|
53608
53942
|
configCommand: () => configCommand
|
|
53609
53943
|
});
|
|
53610
|
-
import { join as
|
|
53944
|
+
import { join as join55, resolve as resolve31 } from "node:path";
|
|
53611
53945
|
import { homedir as homedir14 } from "node:os";
|
|
53612
53946
|
import { cwd as cwd3 } from "node:process";
|
|
53613
53947
|
function redactIfSensitive(key, value) {
|
|
@@ -53690,7 +54024,7 @@ function handleShow(opts, config) {
|
|
|
53690
54024
|
}
|
|
53691
54025
|
}
|
|
53692
54026
|
printSection("Config File");
|
|
53693
|
-
printInfo(`~/.open-agents/config.json (${
|
|
54027
|
+
printInfo(`~/.open-agents/config.json (${join55(homedir14(), ".open-agents", "config.json")})`);
|
|
53694
54028
|
printSection("Priority Chain");
|
|
53695
54029
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
53696
54030
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -53729,7 +54063,7 @@ function handleSet(opts, _config) {
|
|
|
53729
54063
|
const coerced = coerceForSettings(key, value);
|
|
53730
54064
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
53731
54065
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
53732
|
-
printInfo(`Saved to ${
|
|
54066
|
+
printInfo(`Saved to ${join55(repoRoot, ".oa", "settings.json")}`);
|
|
53733
54067
|
printInfo("This override applies only when running in this workspace.");
|
|
53734
54068
|
} catch (err) {
|
|
53735
54069
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -53829,7 +54163,7 @@ var serve_exports = {};
|
|
|
53829
54163
|
__export(serve_exports, {
|
|
53830
54164
|
serveCommand: () => serveCommand
|
|
53831
54165
|
});
|
|
53832
|
-
import { spawn as
|
|
54166
|
+
import { spawn as spawn19 } from "node:child_process";
|
|
53833
54167
|
async function serveCommand(opts, config) {
|
|
53834
54168
|
const backendType = config.backendType;
|
|
53835
54169
|
if (backendType === "ollama") {
|
|
@@ -53922,7 +54256,7 @@ async function serveVllm(opts, config) {
|
|
|
53922
54256
|
}
|
|
53923
54257
|
async function runVllmServer(args, verbose) {
|
|
53924
54258
|
return new Promise((resolve32, reject) => {
|
|
53925
|
-
const child =
|
|
54259
|
+
const child = spawn19("python", args, {
|
|
53926
54260
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
53927
54261
|
env: { ...process.env }
|
|
53928
54262
|
});
|
|
@@ -53986,9 +54320,9 @@ var eval_exports = {};
|
|
|
53986
54320
|
__export(eval_exports, {
|
|
53987
54321
|
evalCommand: () => evalCommand
|
|
53988
54322
|
});
|
|
53989
|
-
import { tmpdir as
|
|
54323
|
+
import { tmpdir as tmpdir10 } from "node:os";
|
|
53990
54324
|
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
|
|
53991
|
-
import { join as
|
|
54325
|
+
import { join as join56 } from "node:path";
|
|
53992
54326
|
async function evalCommand(opts, config) {
|
|
53993
54327
|
const suiteName = opts.suite ?? "basic";
|
|
53994
54328
|
const suite = SUITES[suiteName];
|
|
@@ -54113,9 +54447,9 @@ async function evalCommand(opts, config) {
|
|
|
54113
54447
|
process.exit(failed > 0 ? 1 : 0);
|
|
54114
54448
|
}
|
|
54115
54449
|
function createTempEvalRepo() {
|
|
54116
|
-
const dir =
|
|
54450
|
+
const dir = join56(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
54117
54451
|
mkdirSync20(dir, { recursive: true });
|
|
54118
|
-
writeFileSync19(
|
|
54452
|
+
writeFileSync19(join56(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
54119
54453
|
return dir;
|
|
54120
54454
|
}
|
|
54121
54455
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -54175,7 +54509,7 @@ init_updater();
|
|
|
54175
54509
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
54176
54510
|
import { createRequire as createRequire3 } from "node:module";
|
|
54177
54511
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
54178
|
-
import { dirname as dirname19, join as
|
|
54512
|
+
import { dirname as dirname19, join as join57 } from "node:path";
|
|
54179
54513
|
|
|
54180
54514
|
// packages/cli/dist/cli.js
|
|
54181
54515
|
import { createInterface } from "node:readline";
|
|
@@ -54282,7 +54616,7 @@ init_output();
|
|
|
54282
54616
|
function getVersion4() {
|
|
54283
54617
|
try {
|
|
54284
54618
|
const require2 = createRequire3(import.meta.url);
|
|
54285
|
-
const pkgPath =
|
|
54619
|
+
const pkgPath = join57(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
54286
54620
|
const pkg = require2(pkgPath);
|
|
54287
54621
|
return pkg.version;
|
|
54288
54622
|
} catch {
|