open-agents-ai 0.42.1 → 0.43.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 +918 -401
- package/dist/scripts/autoresearch-prepare.py +389 -0
- package/dist/scripts/autoresearch-train.py +630 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1285,7 +1285,7 @@ ${stdinInput ?? ""}`);
|
|
|
1285
1285
|
}
|
|
1286
1286
|
runCommand(command, timeout, stdinInput) {
|
|
1287
1287
|
const start = performance.now();
|
|
1288
|
-
return new Promise((
|
|
1288
|
+
return new Promise((resolve27) => {
|
|
1289
1289
|
const child = spawn("bash", ["-c", command], {
|
|
1290
1290
|
cwd: this.workingDir,
|
|
1291
1291
|
env: {
|
|
@@ -1313,7 +1313,7 @@ ${stdinInput ?? ""}`);
|
|
|
1313
1313
|
clearTimeout(timer);
|
|
1314
1314
|
if (exitFlushTimer)
|
|
1315
1315
|
clearTimeout(exitFlushTimer);
|
|
1316
|
-
|
|
1316
|
+
resolve27(result);
|
|
1317
1317
|
};
|
|
1318
1318
|
const timer = setTimeout(() => {
|
|
1319
1319
|
killed = true;
|
|
@@ -2317,7 +2317,7 @@ Meta: ${metaKeys.map((k) => `${k}="${meta[k]?.slice(0, 80)}"`).join(", ")}`);
|
|
|
2317
2317
|
return null;
|
|
2318
2318
|
}
|
|
2319
2319
|
runProcess(cmd, args, timeoutMs) {
|
|
2320
|
-
return new Promise((
|
|
2320
|
+
return new Promise((resolve27, reject) => {
|
|
2321
2321
|
const proc = execFile3(cmd, args, {
|
|
2322
2322
|
timeout: timeoutMs,
|
|
2323
2323
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -2327,7 +2327,7 @@ Meta: ${metaKeys.map((k) => `${k}="${meta[k]?.slice(0, 80)}"`).join(", ")}`);
|
|
|
2327
2327
|
reject(new Error(`Process timeout after ${timeoutMs}ms`));
|
|
2328
2328
|
return;
|
|
2329
2329
|
}
|
|
2330
|
-
|
|
2330
|
+
resolve27({
|
|
2331
2331
|
stdout: String(stdout),
|
|
2332
2332
|
stderr: String(stderr),
|
|
2333
2333
|
exitCode: error ? error.code ?? 1 : 0
|
|
@@ -5361,7 +5361,7 @@ var init_custom_tool = __esm({
|
|
|
5361
5361
|
}
|
|
5362
5362
|
/** Execute a single shell command and return output */
|
|
5363
5363
|
runCommand(command) {
|
|
5364
|
-
return new Promise((
|
|
5364
|
+
return new Promise((resolve27) => {
|
|
5365
5365
|
const child = spawn3("bash", ["-c", command], {
|
|
5366
5366
|
cwd: this.workingDir,
|
|
5367
5367
|
env: { ...process.env, CI: "true", NO_COLOR: "1" },
|
|
@@ -5386,11 +5386,11 @@ var init_custom_tool = __esm({
|
|
|
5386
5386
|
child.kill("SIGTERM");
|
|
5387
5387
|
} catch {
|
|
5388
5388
|
}
|
|
5389
|
-
|
|
5389
|
+
resolve27({ success: false, output: stdout, error: "Command timed out after 60s" });
|
|
5390
5390
|
}, 6e4);
|
|
5391
5391
|
child.on("close", (code) => {
|
|
5392
5392
|
clearTimeout(timer);
|
|
5393
|
-
|
|
5393
|
+
resolve27({
|
|
5394
5394
|
success: code === 0,
|
|
5395
5395
|
output: stdout + (stderr && code === 0 ? `
|
|
5396
5396
|
STDERR:
|
|
@@ -5400,7 +5400,7 @@ ${stderr}` : ""),
|
|
|
5400
5400
|
});
|
|
5401
5401
|
child.on("error", (err) => {
|
|
5402
5402
|
clearTimeout(timer);
|
|
5403
|
-
|
|
5403
|
+
resolve27({ success: false, output: stdout, error: err.message });
|
|
5404
5404
|
});
|
|
5405
5405
|
});
|
|
5406
5406
|
}
|
|
@@ -6582,7 +6582,7 @@ import { writeFile as writeFile7, mkdtemp, rm, readdir as readdir2, stat } from
|
|
|
6582
6582
|
import { join as join16 } from "node:path";
|
|
6583
6583
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
6584
6584
|
function runProcess(cmd, args, options) {
|
|
6585
|
-
return new Promise((
|
|
6585
|
+
return new Promise((resolve27) => {
|
|
6586
6586
|
const proc = spawn5(cmd, args, {
|
|
6587
6587
|
cwd: options.cwd,
|
|
6588
6588
|
timeout: options.timeout,
|
|
@@ -6612,7 +6612,7 @@ function runProcess(cmd, args, options) {
|
|
|
6612
6612
|
}
|
|
6613
6613
|
});
|
|
6614
6614
|
proc.on("error", (err) => {
|
|
6615
|
-
|
|
6615
|
+
resolve27({
|
|
6616
6616
|
stdout,
|
|
6617
6617
|
stderr: stderr || err.message,
|
|
6618
6618
|
exitCode: 1,
|
|
@@ -6624,7 +6624,7 @@ function runProcess(cmd, args, options) {
|
|
|
6624
6624
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
6625
6625
|
timedOut = true;
|
|
6626
6626
|
}
|
|
6627
|
-
|
|
6627
|
+
resolve27({
|
|
6628
6628
|
stdout,
|
|
6629
6629
|
stderr,
|
|
6630
6630
|
exitCode: code ?? (timedOut ? 124 : 1),
|
|
@@ -8907,10 +8907,524 @@ var init_browser_action = __esm({
|
|
|
8907
8907
|
}
|
|
8908
8908
|
});
|
|
8909
8909
|
|
|
8910
|
+
// packages/execution/dist/tools/autoresearch.js
|
|
8911
|
+
import { execSync as execSync16, spawn as spawn8 } from "node:child_process";
|
|
8912
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, appendFileSync, copyFileSync } from "node:fs";
|
|
8913
|
+
import { join as join22, resolve as resolve20, dirname as dirname9 } from "node:path";
|
|
8914
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
8915
|
+
function findAutoresearchScript(scriptName) {
|
|
8916
|
+
const thisDir = dirname9(fileURLToPath6(import.meta.url));
|
|
8917
|
+
const devPath = resolve20(thisDir, "../../scripts", scriptName);
|
|
8918
|
+
if (existsSync19(devPath))
|
|
8919
|
+
return devPath;
|
|
8920
|
+
const bundledPath = resolve20(thisDir, "../scripts", scriptName);
|
|
8921
|
+
if (existsSync19(bundledPath))
|
|
8922
|
+
return bundledPath;
|
|
8923
|
+
const sameDirPath = resolve20(thisDir, scriptName);
|
|
8924
|
+
if (existsSync19(sameDirPath))
|
|
8925
|
+
return sameDirPath;
|
|
8926
|
+
return null;
|
|
8927
|
+
}
|
|
8928
|
+
function parseRunLog(logContent) {
|
|
8929
|
+
const lines = logContent.split("\n");
|
|
8930
|
+
const result = {};
|
|
8931
|
+
for (const line of lines) {
|
|
8932
|
+
const match = line.match(/^(\w+):\s+([\d.]+)/);
|
|
8933
|
+
if (match) {
|
|
8934
|
+
result[match[1]] = parseFloat(match[2]);
|
|
8935
|
+
}
|
|
8936
|
+
}
|
|
8937
|
+
if (!result["val_bpb"])
|
|
8938
|
+
return null;
|
|
8939
|
+
return {
|
|
8940
|
+
val_bpb: result["val_bpb"],
|
|
8941
|
+
training_seconds: result["training_seconds"] ?? 0,
|
|
8942
|
+
total_seconds: result["total_seconds"] ?? 0,
|
|
8943
|
+
peak_vram_mb: result["peak_vram_mb"] ?? 0,
|
|
8944
|
+
mfu_percent: result["mfu_percent"] ?? 0,
|
|
8945
|
+
total_tokens_M: result["total_tokens_M"] ?? 0,
|
|
8946
|
+
num_steps: result["num_steps"] ?? 0,
|
|
8947
|
+
num_params_M: result["num_params_M"] ?? 0,
|
|
8948
|
+
depth: result["depth"] ?? 0
|
|
8949
|
+
};
|
|
8950
|
+
}
|
|
8951
|
+
var AutoresearchTool;
|
|
8952
|
+
var init_autoresearch = __esm({
|
|
8953
|
+
"packages/execution/dist/tools/autoresearch.js"() {
|
|
8954
|
+
"use strict";
|
|
8955
|
+
AutoresearchTool = class {
|
|
8956
|
+
repoRoot;
|
|
8957
|
+
name = "autoresearch";
|
|
8958
|
+
description = `Autonomous ML research experimentation (based on Karpathy's autoresearch).
|
|
8959
|
+
|
|
8960
|
+
Actions:
|
|
8961
|
+
- setup: Initialize workspace with training scripts, install deps, download data
|
|
8962
|
+
- run: Execute a single 5-minute training experiment, return parsed metrics
|
|
8963
|
+
- results: Show experiment history from results.tsv
|
|
8964
|
+
- status: Check workspace state (GPU, branch, last result)
|
|
8965
|
+
- keep: Record current experiment as keeper in results.tsv and commit
|
|
8966
|
+
- discard: Revert train.py to last committed state
|
|
8967
|
+
|
|
8968
|
+
The agent modifies train.py between experiments using file_edit. This tool handles infrastructure.
|
|
8969
|
+
Requires: NVIDIA GPU, Python 3.10+, uv (astral.sh package manager).`;
|
|
8970
|
+
parameters = {
|
|
8971
|
+
type: "object",
|
|
8972
|
+
properties: {
|
|
8973
|
+
action: {
|
|
8974
|
+
type: "string",
|
|
8975
|
+
enum: ["setup", "run", "results", "status", "keep", "discard"],
|
|
8976
|
+
description: "Action to perform"
|
|
8977
|
+
},
|
|
8978
|
+
workspace: {
|
|
8979
|
+
type: "string",
|
|
8980
|
+
description: "Path to autoresearch workspace (default: .oa/autoresearch)"
|
|
8981
|
+
},
|
|
8982
|
+
tag: {
|
|
8983
|
+
type: "string",
|
|
8984
|
+
description: "Experiment tag for git branch (setup action, e.g. 'mar14')"
|
|
8985
|
+
},
|
|
8986
|
+
description: {
|
|
8987
|
+
type: "string",
|
|
8988
|
+
description: "Short description of the experiment (keep/discard actions)"
|
|
8989
|
+
},
|
|
8990
|
+
val_bpb: {
|
|
8991
|
+
type: "number",
|
|
8992
|
+
description: "val_bpb result to record (keep/discard actions \u2014 auto-detected from last run if omitted)"
|
|
8993
|
+
},
|
|
8994
|
+
memory_gb: {
|
|
8995
|
+
type: "number",
|
|
8996
|
+
description: "Peak memory in GB (keep/discard actions \u2014 auto-detected from last run if omitted)"
|
|
8997
|
+
},
|
|
8998
|
+
num_shards: {
|
|
8999
|
+
type: "number",
|
|
9000
|
+
description: "Number of data shards to download (setup action, default: 10)"
|
|
9001
|
+
},
|
|
9002
|
+
timeout_minutes: {
|
|
9003
|
+
type: "number",
|
|
9004
|
+
description: "Max wall-clock minutes for a run (default: 10, kills if exceeded)"
|
|
9005
|
+
}
|
|
9006
|
+
},
|
|
9007
|
+
required: ["action"]
|
|
9008
|
+
};
|
|
9009
|
+
constructor(repoRoot) {
|
|
9010
|
+
this.repoRoot = repoRoot;
|
|
9011
|
+
}
|
|
9012
|
+
async execute(args) {
|
|
9013
|
+
const start = Date.now();
|
|
9014
|
+
const action = String(args["action"] ?? "status");
|
|
9015
|
+
const workspacePath = String(args["workspace"] ?? join22(this.repoRoot, ".oa", "autoresearch"));
|
|
9016
|
+
try {
|
|
9017
|
+
switch (action) {
|
|
9018
|
+
case "setup":
|
|
9019
|
+
return await this.setup(workspacePath, args, start);
|
|
9020
|
+
case "run":
|
|
9021
|
+
return await this.run(workspacePath, args, start);
|
|
9022
|
+
case "results":
|
|
9023
|
+
return this.getResults(workspacePath, start);
|
|
9024
|
+
case "status":
|
|
9025
|
+
return this.getStatus(workspacePath, start);
|
|
9026
|
+
case "keep":
|
|
9027
|
+
return this.keepExperiment(workspacePath, args, start);
|
|
9028
|
+
case "discard":
|
|
9029
|
+
return this.discardExperiment(workspacePath, args, start);
|
|
9030
|
+
default:
|
|
9031
|
+
return { success: false, output: "", error: `Unknown action: ${action}. Use: setup, run, results, status, keep, discard`, durationMs: Date.now() - start };
|
|
9032
|
+
}
|
|
9033
|
+
} catch (err) {
|
|
9034
|
+
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
9037
|
+
// ── Setup ──────────────────────────────────────────────────────────────
|
|
9038
|
+
async setup(workspace, args, start) {
|
|
9039
|
+
const output = [];
|
|
9040
|
+
try {
|
|
9041
|
+
execSync16("which uv", { encoding: "utf-8", timeout: 5e3 });
|
|
9042
|
+
output.push("uv: found");
|
|
9043
|
+
} catch {
|
|
9044
|
+
return { success: false, output: "", error: "uv not found. Install with: curl -LsSf https://astral.sh/uv/install.sh | sh", durationMs: Date.now() - start };
|
|
9045
|
+
}
|
|
9046
|
+
try {
|
|
9047
|
+
const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo 'no GPU'", { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
9048
|
+
output.push(`GPU: ${gpuInfo}`);
|
|
9049
|
+
} catch {
|
|
9050
|
+
output.push("GPU: detection failed (nvidia-smi not available)");
|
|
9051
|
+
}
|
|
9052
|
+
mkdirSync5(workspace, { recursive: true });
|
|
9053
|
+
const prepareScript = findAutoresearchScript("autoresearch-prepare.py");
|
|
9054
|
+
const trainScript = findAutoresearchScript("autoresearch-train.py");
|
|
9055
|
+
if (prepareScript) {
|
|
9056
|
+
copyFileSync(prepareScript, join22(workspace, "prepare.py"));
|
|
9057
|
+
output.push("Copied prepare.py template");
|
|
9058
|
+
} else {
|
|
9059
|
+
return { success: false, output: output.join("\n"), error: "autoresearch-prepare.py template not found in distribution", durationMs: Date.now() - start };
|
|
9060
|
+
}
|
|
9061
|
+
if (trainScript) {
|
|
9062
|
+
copyFileSync(trainScript, join22(workspace, "train.py"));
|
|
9063
|
+
output.push("Copied train.py template");
|
|
9064
|
+
} else {
|
|
9065
|
+
return { success: false, output: output.join("\n"), error: "autoresearch-train.py template not found in distribution", durationMs: Date.now() - start };
|
|
9066
|
+
}
|
|
9067
|
+
const pyprojectContent = `[project]
|
|
9068
|
+
name = "autoresearch"
|
|
9069
|
+
version = "0.1.0"
|
|
9070
|
+
description = "Autonomous pretraining research"
|
|
9071
|
+
requires-python = ">=3.10"
|
|
9072
|
+
dependencies = [
|
|
9073
|
+
"kernels>=0.11.7",
|
|
9074
|
+
"matplotlib>=3.10.8",
|
|
9075
|
+
"numpy>=2.2.6",
|
|
9076
|
+
"pandas>=2.3.3",
|
|
9077
|
+
"pyarrow>=21.0.0",
|
|
9078
|
+
"requests>=2.32.0",
|
|
9079
|
+
"rustbpe>=0.1.0",
|
|
9080
|
+
"tiktoken>=0.11.0",
|
|
9081
|
+
"torch==2.9.1",
|
|
9082
|
+
]
|
|
9083
|
+
|
|
9084
|
+
[tool.uv.sources]
|
|
9085
|
+
torch = [
|
|
9086
|
+
{ index = "pytorch-cu128" },
|
|
9087
|
+
]
|
|
9088
|
+
|
|
9089
|
+
[[tool.uv.index]]
|
|
9090
|
+
name = "pytorch-cu128"
|
|
9091
|
+
url = "https://download.pytorch.org/whl/cu128"
|
|
9092
|
+
explicit = true
|
|
9093
|
+
`;
|
|
9094
|
+
writeFileSync5(join22(workspace, "pyproject.toml"), pyprojectContent, "utf-8");
|
|
9095
|
+
output.push("Created pyproject.toml");
|
|
9096
|
+
try {
|
|
9097
|
+
execSync16("git rev-parse --git-dir", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
9098
|
+
output.push("Git: already initialized");
|
|
9099
|
+
} catch {
|
|
9100
|
+
execSync16("git init && git add -A && git commit -m 'autoresearch: initial setup'", {
|
|
9101
|
+
cwd: workspace,
|
|
9102
|
+
encoding: "utf-8",
|
|
9103
|
+
timeout: 1e4
|
|
9104
|
+
});
|
|
9105
|
+
output.push("Git: initialized with initial commit");
|
|
9106
|
+
}
|
|
9107
|
+
const tag = String(args["tag"] ?? (/* @__PURE__ */ new Date()).toISOString().slice(5, 10).replace("-", ""));
|
|
9108
|
+
const branchName = `autoresearch/${tag}`;
|
|
9109
|
+
try {
|
|
9110
|
+
execSync16(`git checkout -b ${branchName}`, { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
9111
|
+
output.push(`Branch: created ${branchName}`);
|
|
9112
|
+
} catch {
|
|
9113
|
+
output.push(`Branch: ${branchName} may already exist, staying on current branch`);
|
|
9114
|
+
}
|
|
9115
|
+
output.push("Installing dependencies with uv sync (this may take a while)...");
|
|
9116
|
+
try {
|
|
9117
|
+
const uvOut = execSync16("uv sync 2>&1", { cwd: workspace, encoding: "utf-8", timeout: 3e5 });
|
|
9118
|
+
output.push(`uv sync: ${uvOut.trim().split("\n").slice(-3).join(" | ")}`);
|
|
9119
|
+
} catch (err) {
|
|
9120
|
+
const e = err;
|
|
9121
|
+
output.push(`uv sync warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
|
|
9122
|
+
}
|
|
9123
|
+
const numShards = Number(args["num_shards"] ?? 10);
|
|
9124
|
+
output.push(`Preparing data (${numShards} shards)...`);
|
|
9125
|
+
try {
|
|
9126
|
+
const prepOut = execSync16(`uv run prepare.py --num-shards ${numShards} 2>&1`, {
|
|
9127
|
+
cwd: workspace,
|
|
9128
|
+
encoding: "utf-8",
|
|
9129
|
+
timeout: 6e5
|
|
9130
|
+
});
|
|
9131
|
+
output.push(`Data prep: ${prepOut.trim().split("\n").slice(-3).join(" | ")}`);
|
|
9132
|
+
} catch (err) {
|
|
9133
|
+
const e = err;
|
|
9134
|
+
output.push(`Data prep warning: ${(e.stderr ?? e.stdout ?? "failed").slice(0, 500)}`);
|
|
9135
|
+
}
|
|
9136
|
+
const tsvPath = join22(workspace, "results.tsv");
|
|
9137
|
+
if (!existsSync19(tsvPath)) {
|
|
9138
|
+
writeFileSync5(tsvPath, "commit val_bpb memory_gb status description\n", "utf-8");
|
|
9139
|
+
output.push("Created results.tsv");
|
|
9140
|
+
}
|
|
9141
|
+
return {
|
|
9142
|
+
success: true,
|
|
9143
|
+
output: `Autoresearch workspace ready at ${workspace}
|
|
9144
|
+
|
|
9145
|
+
${output.join("\n")}
|
|
9146
|
+
|
|
9147
|
+
Next steps:
|
|
9148
|
+
1. Run baseline: autoresearch(action="run") \u2014 establishes starting val_bpb
|
|
9149
|
+
2. Record baseline: autoresearch(action="keep", description="baseline")
|
|
9150
|
+
3. Modify train.py with file_edit, then run again
|
|
9151
|
+
4. Keep or discard based on val_bpb improvement
|
|
9152
|
+
5. Repeat \u2014 iteration beats perfection!`,
|
|
9153
|
+
durationMs: Date.now() - start
|
|
9154
|
+
};
|
|
9155
|
+
}
|
|
9156
|
+
// ── Run experiment ─────────────────────────────────────────────────────
|
|
9157
|
+
async run(workspace, args, start) {
|
|
9158
|
+
if (!existsSync19(join22(workspace, "train.py"))) {
|
|
9159
|
+
return { success: false, output: "", error: `No train.py found in ${workspace}. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9160
|
+
}
|
|
9161
|
+
const timeoutMin = Number(args["timeout_minutes"] ?? 10);
|
|
9162
|
+
const timeoutMs = timeoutMin * 60 * 1e3;
|
|
9163
|
+
const logPath = join22(workspace, "run.log");
|
|
9164
|
+
return new Promise((resolveResult) => {
|
|
9165
|
+
const proc = spawn8("uv", ["run", "train.py"], {
|
|
9166
|
+
cwd: workspace,
|
|
9167
|
+
timeout: timeoutMs,
|
|
9168
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
9169
|
+
env: { ...process.env, PYTORCH_ALLOC_CONF: "expandable_segments:True" }
|
|
9170
|
+
});
|
|
9171
|
+
let stdout = "";
|
|
9172
|
+
let stderr = "";
|
|
9173
|
+
let timedOut = false;
|
|
9174
|
+
proc.stdout.on("data", (d) => {
|
|
9175
|
+
stdout += d.toString();
|
|
9176
|
+
if (stdout.length > 5e5) {
|
|
9177
|
+
stdout = stdout.slice(-2e5);
|
|
9178
|
+
}
|
|
9179
|
+
});
|
|
9180
|
+
proc.stderr.on("data", (d) => {
|
|
9181
|
+
stderr += d.toString();
|
|
9182
|
+
if (stderr.length > 1e5) {
|
|
9183
|
+
stderr = stderr.slice(-5e4);
|
|
9184
|
+
}
|
|
9185
|
+
});
|
|
9186
|
+
const timer = setTimeout(() => {
|
|
9187
|
+
timedOut = true;
|
|
9188
|
+
proc.kill("SIGKILL");
|
|
9189
|
+
}, timeoutMs);
|
|
9190
|
+
proc.on("close", (code) => {
|
|
9191
|
+
clearTimeout(timer);
|
|
9192
|
+
const fullLog = stdout + "\n" + stderr;
|
|
9193
|
+
try {
|
|
9194
|
+
writeFileSync5(logPath, fullLog, "utf-8");
|
|
9195
|
+
} catch {
|
|
9196
|
+
}
|
|
9197
|
+
if (timedOut) {
|
|
9198
|
+
resolveResult({
|
|
9199
|
+
success: false,
|
|
9200
|
+
output: `Experiment timed out after ${timeoutMin} minutes.
|
|
9201
|
+
Last output:
|
|
9202
|
+
${fullLog.slice(-2e3)}`,
|
|
9203
|
+
error: "Training exceeded timeout \u2014 treat as failed experiment",
|
|
9204
|
+
durationMs: Date.now() - start
|
|
9205
|
+
});
|
|
9206
|
+
return;
|
|
9207
|
+
}
|
|
9208
|
+
if (code !== 0) {
|
|
9209
|
+
const tail = fullLog.split("\n").slice(-50).join("\n");
|
|
9210
|
+
resolveResult({
|
|
9211
|
+
success: false,
|
|
9212
|
+
output: `Experiment crashed (exit code ${code}).
|
|
9213
|
+
|
|
9214
|
+
Last 50 lines:
|
|
9215
|
+
${tail}`,
|
|
9216
|
+
error: "Training crashed \u2014 check the error above, fix train.py, and re-run",
|
|
9217
|
+
durationMs: Date.now() - start
|
|
9218
|
+
});
|
|
9219
|
+
return;
|
|
9220
|
+
}
|
|
9221
|
+
const result = parseRunLog(fullLog);
|
|
9222
|
+
if (!result) {
|
|
9223
|
+
resolveResult({
|
|
9224
|
+
success: false,
|
|
9225
|
+
output: `Experiment completed but no val_bpb found in output.
|
|
9226
|
+
Log tail:
|
|
9227
|
+
${fullLog.slice(-2e3)}`,
|
|
9228
|
+
error: "Could not parse experiment results",
|
|
9229
|
+
durationMs: Date.now() - start
|
|
9230
|
+
});
|
|
9231
|
+
return;
|
|
9232
|
+
}
|
|
9233
|
+
try {
|
|
9234
|
+
writeFileSync5(join22(workspace, ".last-result.json"), JSON.stringify(result, null, 2), "utf-8");
|
|
9235
|
+
} catch {
|
|
9236
|
+
}
|
|
9237
|
+
const memGB = (result.peak_vram_mb / 1024).toFixed(1);
|
|
9238
|
+
const output = [
|
|
9239
|
+
`Experiment complete!`,
|
|
9240
|
+
``,
|
|
9241
|
+
`val_bpb: ${result.val_bpb.toFixed(6)}`,
|
|
9242
|
+
`training_seconds: ${result.training_seconds.toFixed(1)}`,
|
|
9243
|
+
`total_seconds: ${result.total_seconds.toFixed(1)}`,
|
|
9244
|
+
`peak_vram_mb: ${result.peak_vram_mb.toFixed(1)} (${memGB} GB)`,
|
|
9245
|
+
`mfu_percent: ${result.mfu_percent.toFixed(2)}`,
|
|
9246
|
+
`total_tokens_M: ${result.total_tokens_M.toFixed(1)}`,
|
|
9247
|
+
`num_steps: ${result.num_steps}`,
|
|
9248
|
+
`num_params_M: ${result.num_params_M.toFixed(1)}`,
|
|
9249
|
+
`depth: ${result.depth}`,
|
|
9250
|
+
``,
|
|
9251
|
+
`Next: Compare val_bpb to previous best.`,
|
|
9252
|
+
` If improved: autoresearch(action="keep", description="what you changed")`,
|
|
9253
|
+
` If worse: autoresearch(action="discard", description="what you tried")`
|
|
9254
|
+
].join("\n");
|
|
9255
|
+
resolveResult({ success: true, output, durationMs: Date.now() - start });
|
|
9256
|
+
});
|
|
9257
|
+
proc.on("error", (err) => {
|
|
9258
|
+
clearTimeout(timer);
|
|
9259
|
+
resolveResult({
|
|
9260
|
+
success: false,
|
|
9261
|
+
output: "",
|
|
9262
|
+
error: `Failed to start training: ${err.message}. Is uv installed and GPU available?`,
|
|
9263
|
+
durationMs: Date.now() - start
|
|
9264
|
+
});
|
|
9265
|
+
});
|
|
9266
|
+
});
|
|
9267
|
+
}
|
|
9268
|
+
// ── Results ────────────────────────────────────────────────────────────
|
|
9269
|
+
getResults(workspace, start) {
|
|
9270
|
+
const tsvPath = join22(workspace, "results.tsv");
|
|
9271
|
+
if (!existsSync19(tsvPath)) {
|
|
9272
|
+
return { success: false, output: "", error: `No results.tsv found. Run autoresearch(action="setup") first.`, durationMs: Date.now() - start };
|
|
9273
|
+
}
|
|
9274
|
+
const content = readFileSync14(tsvPath, "utf-8");
|
|
9275
|
+
const lines = content.trim().split("\n");
|
|
9276
|
+
if (lines.length <= 1) {
|
|
9277
|
+
return { success: true, output: 'No experiments recorded yet. Run autoresearch(action="run") to start.', durationMs: Date.now() - start };
|
|
9278
|
+
}
|
|
9279
|
+
const experiments = lines.slice(1).map((line) => {
|
|
9280
|
+
const [commit, bpb, mem, status, desc] = line.split(" ");
|
|
9281
|
+
return { commit, val_bpb: parseFloat(bpb ?? "0"), memory_gb: parseFloat(mem ?? "0"), status, description: desc };
|
|
9282
|
+
});
|
|
9283
|
+
const kept = experiments.filter((e) => e.status === "keep");
|
|
9284
|
+
const best = kept.reduce((a, b) => a.val_bpb < b.val_bpb && a.val_bpb > 0 ? a : b, kept[0]);
|
|
9285
|
+
const summary = [
|
|
9286
|
+
`Experiments: ${experiments.length} total, ${kept.length} kept, ${experiments.filter((e) => e.status === "discard").length} discarded, ${experiments.filter((e) => e.status === "crash").length} crashed`,
|
|
9287
|
+
`Best val_bpb: ${best?.val_bpb?.toFixed(6) ?? "N/A"} (${best?.description ?? "N/A"})`,
|
|
9288
|
+
``,
|
|
9289
|
+
`Full history:`,
|
|
9290
|
+
content
|
|
9291
|
+
].join("\n");
|
|
9292
|
+
return { success: true, output: summary, durationMs: Date.now() - start };
|
|
9293
|
+
}
|
|
9294
|
+
// ── Status ─────────────────────────────────────────────────────────────
|
|
9295
|
+
getStatus(workspace, start) {
|
|
9296
|
+
const output = [];
|
|
9297
|
+
if (!existsSync19(join22(workspace, "train.py"))) {
|
|
9298
|
+
return {
|
|
9299
|
+
success: true,
|
|
9300
|
+
output: `Autoresearch workspace not initialized at ${workspace}.
|
|
9301
|
+
Run autoresearch(action="setup") to begin.`,
|
|
9302
|
+
durationMs: Date.now() - start
|
|
9303
|
+
};
|
|
9304
|
+
}
|
|
9305
|
+
output.push(`Workspace: ${workspace}`);
|
|
9306
|
+
try {
|
|
9307
|
+
const branch = execSync16("git branch --show-current", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9308
|
+
output.push(`Branch: ${branch}`);
|
|
9309
|
+
const lastCommit = execSync16("git log --oneline -1", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9310
|
+
output.push(`Last commit: ${lastCommit}`);
|
|
9311
|
+
} catch {
|
|
9312
|
+
output.push("Git: not initialized");
|
|
9313
|
+
}
|
|
9314
|
+
try {
|
|
9315
|
+
const gpuInfo = execSync16("nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv,noheader 2>/dev/null", { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
9316
|
+
output.push(`GPU: ${gpuInfo}`);
|
|
9317
|
+
} catch {
|
|
9318
|
+
output.push("GPU: not detected");
|
|
9319
|
+
}
|
|
9320
|
+
const lastResultPath = join22(workspace, ".last-result.json");
|
|
9321
|
+
if (existsSync19(lastResultPath)) {
|
|
9322
|
+
try {
|
|
9323
|
+
const last = JSON.parse(readFileSync14(lastResultPath, "utf-8"));
|
|
9324
|
+
output.push(`Last experiment: val_bpb=${last.val_bpb.toFixed(6)}, ${(last.peak_vram_mb / 1024).toFixed(1)}GB VRAM, ${last.num_params_M.toFixed(1)}M params`);
|
|
9325
|
+
} catch {
|
|
9326
|
+
}
|
|
9327
|
+
}
|
|
9328
|
+
const tsvPath = join22(workspace, "results.tsv");
|
|
9329
|
+
if (existsSync19(tsvPath)) {
|
|
9330
|
+
const lines = readFileSync14(tsvPath, "utf-8").trim().split("\n");
|
|
9331
|
+
output.push(`Experiments recorded: ${lines.length - 1}`);
|
|
9332
|
+
}
|
|
9333
|
+
const cacheDir = join22(process.env["HOME"] ?? "~", ".cache", "autoresearch");
|
|
9334
|
+
output.push(`Data cache: ${existsSync19(cacheDir) ? "present" : "not found"} (${cacheDir})`);
|
|
9335
|
+
return { success: true, output: output.join("\n"), durationMs: Date.now() - start };
|
|
9336
|
+
}
|
|
9337
|
+
// ── Keep / Discard ─────────────────────────────────────────────────────
|
|
9338
|
+
keepExperiment(workspace, args, start) {
|
|
9339
|
+
const desc = String(args["description"] ?? "experiment");
|
|
9340
|
+
const tsvPath = join22(workspace, "results.tsv");
|
|
9341
|
+
const lastResultPath = join22(workspace, ".last-result.json");
|
|
9342
|
+
let valBpb = args["val_bpb"];
|
|
9343
|
+
let memGb = args["memory_gb"];
|
|
9344
|
+
if ((valBpb === void 0 || memGb === void 0) && existsSync19(lastResultPath)) {
|
|
9345
|
+
try {
|
|
9346
|
+
const last = JSON.parse(readFileSync14(lastResultPath, "utf-8"));
|
|
9347
|
+
if (valBpb === void 0)
|
|
9348
|
+
valBpb = last.val_bpb;
|
|
9349
|
+
if (memGb === void 0)
|
|
9350
|
+
memGb = parseFloat((last.peak_vram_mb / 1024).toFixed(1));
|
|
9351
|
+
} catch {
|
|
9352
|
+
}
|
|
9353
|
+
}
|
|
9354
|
+
valBpb = valBpb ?? 0;
|
|
9355
|
+
memGb = memGb ?? 0;
|
|
9356
|
+
let commitHash = "0000000";
|
|
9357
|
+
try {
|
|
9358
|
+
execSync16("git add train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
9359
|
+
execSync16(`git commit -m "autoresearch: ${desc}"`, { cwd: workspace, encoding: "utf-8", timeout: 1e4 });
|
|
9360
|
+
commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9361
|
+
} catch {
|
|
9362
|
+
try {
|
|
9363
|
+
commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9364
|
+
} catch {
|
|
9365
|
+
}
|
|
9366
|
+
}
|
|
9367
|
+
const row = `${commitHash} ${valBpb.toFixed(6)} ${memGb.toFixed(1)} keep ${desc}
|
|
9368
|
+
`;
|
|
9369
|
+
appendFileSync(tsvPath, row, "utf-8");
|
|
9370
|
+
return {
|
|
9371
|
+
success: true,
|
|
9372
|
+
output: `Kept: ${commitHash} | val_bpb=${valBpb.toFixed(6)} | ${memGb.toFixed(1)}GB | ${desc}
|
|
9373
|
+
Branch advanced. Ready for next experiment.`,
|
|
9374
|
+
durationMs: Date.now() - start
|
|
9375
|
+
};
|
|
9376
|
+
}
|
|
9377
|
+
discardExperiment(workspace, args, start) {
|
|
9378
|
+
const desc = String(args["description"] ?? "experiment");
|
|
9379
|
+
const tsvPath = join22(workspace, "results.tsv");
|
|
9380
|
+
const lastResultPath = join22(workspace, ".last-result.json");
|
|
9381
|
+
let valBpb = args["val_bpb"];
|
|
9382
|
+
let memGb = args["memory_gb"];
|
|
9383
|
+
if ((valBpb === void 0 || memGb === void 0) && existsSync19(lastResultPath)) {
|
|
9384
|
+
try {
|
|
9385
|
+
const last = JSON.parse(readFileSync14(lastResultPath, "utf-8"));
|
|
9386
|
+
if (valBpb === void 0)
|
|
9387
|
+
valBpb = last.val_bpb;
|
|
9388
|
+
if (memGb === void 0)
|
|
9389
|
+
memGb = parseFloat((last.peak_vram_mb / 1024).toFixed(1));
|
|
9390
|
+
} catch {
|
|
9391
|
+
}
|
|
9392
|
+
}
|
|
9393
|
+
valBpb = valBpb ?? 0;
|
|
9394
|
+
memGb = memGb ?? 0;
|
|
9395
|
+
let commitHash = "0000000";
|
|
9396
|
+
try {
|
|
9397
|
+
commitHash = execSync16("git rev-parse --short HEAD", { cwd: workspace, encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9398
|
+
} catch {
|
|
9399
|
+
}
|
|
9400
|
+
const row = `${commitHash} ${valBpb.toFixed(6)} ${memGb.toFixed(1)} discard ${desc}
|
|
9401
|
+
`;
|
|
9402
|
+
appendFileSync(tsvPath, row, "utf-8");
|
|
9403
|
+
try {
|
|
9404
|
+
execSync16("git checkout -- train.py", { cwd: workspace, encoding: "utf-8", timeout: 5e3 });
|
|
9405
|
+
} catch {
|
|
9406
|
+
return {
|
|
9407
|
+
success: false,
|
|
9408
|
+
output: `Recorded discard but failed to revert train.py`,
|
|
9409
|
+
error: "git checkout -- train.py failed",
|
|
9410
|
+
durationMs: Date.now() - start
|
|
9411
|
+
};
|
|
9412
|
+
}
|
|
9413
|
+
return {
|
|
9414
|
+
success: true,
|
|
9415
|
+
output: `Discarded: val_bpb=${valBpb.toFixed(6)} | ${memGb.toFixed(1)}GB | ${desc}
|
|
9416
|
+
train.py reverted to last kept state. Ready for next experiment.`,
|
|
9417
|
+
durationMs: Date.now() - start
|
|
9418
|
+
};
|
|
9419
|
+
}
|
|
9420
|
+
};
|
|
9421
|
+
}
|
|
9422
|
+
});
|
|
9423
|
+
|
|
8910
9424
|
// packages/execution/dist/tools/scheduler.js
|
|
8911
|
-
import { execSync as
|
|
9425
|
+
import { execSync as execSync17, exec as execCb } from "node:child_process";
|
|
8912
9426
|
import { readFile as readFile9, writeFile as writeFile8, mkdir as mkdir4 } from "node:fs/promises";
|
|
8913
|
-
import { resolve as
|
|
9427
|
+
import { resolve as resolve21, join as join23 } from "node:path";
|
|
8914
9428
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
8915
9429
|
function isValidCron(expr) {
|
|
8916
9430
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -8970,19 +9484,19 @@ function describeCron(expr) {
|
|
|
8970
9484
|
}
|
|
8971
9485
|
function getCurrentCrontab() {
|
|
8972
9486
|
try {
|
|
8973
|
-
return
|
|
9487
|
+
return execSync17("crontab -l 2>/dev/null", { stdio: "pipe" }).toString().split("\n");
|
|
8974
9488
|
} catch {
|
|
8975
9489
|
return [];
|
|
8976
9490
|
}
|
|
8977
9491
|
}
|
|
8978
9492
|
function writeCrontab(lines) {
|
|
8979
9493
|
const content = lines.join("\n") + "\n";
|
|
8980
|
-
|
|
9494
|
+
execSync17(`echo ${JSON.stringify(content)} | crontab -`, { stdio: "pipe" });
|
|
8981
9495
|
}
|
|
8982
9496
|
function findOaBinary() {
|
|
8983
9497
|
for (const cmd of ["oa", "open-agents"]) {
|
|
8984
9498
|
try {
|
|
8985
|
-
const path =
|
|
9499
|
+
const path = execSync17(`which ${cmd} 2>/dev/null`, { stdio: "pipe" }).toString().trim();
|
|
8986
9500
|
if (path)
|
|
8987
9501
|
return path;
|
|
8988
9502
|
} catch {
|
|
@@ -8993,8 +9507,8 @@ function findOaBinary() {
|
|
|
8993
9507
|
function installCronJob(task, workingDir) {
|
|
8994
9508
|
const lines = getCurrentCrontab();
|
|
8995
9509
|
const oaBin = findOaBinary();
|
|
8996
|
-
const logDir =
|
|
8997
|
-
const logFile =
|
|
9510
|
+
const logDir = resolve21(workingDir, ".oa", "scheduled", "logs");
|
|
9511
|
+
const logFile = join23(logDir, `${task.id}.log`);
|
|
8998
9512
|
const cronLine = `${task.schedule} cd ${JSON.stringify(workingDir)} && ${oaBin} ${JSON.stringify(task.task)} >> ${JSON.stringify(logFile)} 2>&1 ${CRON_MARKER}${task.id}`;
|
|
8999
9513
|
const filtered = lines.filter((l) => !l.includes(`${CRON_MARKER}${task.id}`));
|
|
9000
9514
|
filtered.push(cronLine);
|
|
@@ -9014,7 +9528,7 @@ function listCronJobs() {
|
|
|
9014
9528
|
});
|
|
9015
9529
|
}
|
|
9016
9530
|
async function loadStore(workingDir) {
|
|
9017
|
-
const storePath =
|
|
9531
|
+
const storePath = resolve21(workingDir, ".oa", "scheduled", "tasks.json");
|
|
9018
9532
|
try {
|
|
9019
9533
|
const raw = await readFile9(storePath, "utf-8");
|
|
9020
9534
|
return JSON.parse(raw);
|
|
@@ -9023,11 +9537,11 @@ async function loadStore(workingDir) {
|
|
|
9023
9537
|
}
|
|
9024
9538
|
}
|
|
9025
9539
|
async function saveStore(workingDir, store) {
|
|
9026
|
-
const dir =
|
|
9540
|
+
const dir = resolve21(workingDir, ".oa", "scheduled");
|
|
9027
9541
|
await mkdir4(dir, { recursive: true });
|
|
9028
|
-
await mkdir4(
|
|
9542
|
+
await mkdir4(join23(dir, "logs"), { recursive: true });
|
|
9029
9543
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9030
|
-
await writeFile8(
|
|
9544
|
+
await writeFile8(join23(dir, "tasks.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
9031
9545
|
}
|
|
9032
9546
|
var SCHEDULE_PRESETS, CRON_MARKER, SchedulerTool;
|
|
9033
9547
|
var init_scheduler = __esm({
|
|
@@ -9245,7 +9759,7 @@ var init_scheduler = __esm({
|
|
|
9245
9759
|
const id = String(args["id"] ?? "");
|
|
9246
9760
|
if (!id)
|
|
9247
9761
|
return { success: false, output: "", error: "id is required for logs action", durationMs: performance.now() - start };
|
|
9248
|
-
const logFile =
|
|
9762
|
+
const logFile = resolve21(this.workingDir, ".oa", "scheduled", "logs", `${id}.log`);
|
|
9249
9763
|
try {
|
|
9250
9764
|
const raw = await readFile9(logFile, "utf-8");
|
|
9251
9765
|
const truncated = raw.length > 1e4 ? "...(truncated)\n" + raw.slice(-1e4) : raw;
|
|
@@ -9261,7 +9775,7 @@ ${truncated}`, durationMs: performance.now() - start };
|
|
|
9261
9775
|
|
|
9262
9776
|
// packages/execution/dist/tools/reminder.js
|
|
9263
9777
|
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
|
|
9264
|
-
import { resolve as
|
|
9778
|
+
import { resolve as resolve22, join as join24 } from "node:path";
|
|
9265
9779
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
9266
9780
|
function parseDueTime(due) {
|
|
9267
9781
|
const lower = due.toLowerCase().trim();
|
|
@@ -9311,9 +9825,9 @@ function parseDueTime(due) {
|
|
|
9311
9825
|
return null;
|
|
9312
9826
|
}
|
|
9313
9827
|
async function getStorePath(workingDir) {
|
|
9314
|
-
const dir =
|
|
9828
|
+
const dir = resolve22(workingDir, ".oa", "scheduled");
|
|
9315
9829
|
await mkdir5(dir, { recursive: true });
|
|
9316
|
-
return
|
|
9830
|
+
return join24(dir, STORE_FILE);
|
|
9317
9831
|
}
|
|
9318
9832
|
async function loadReminderStore(workingDir) {
|
|
9319
9833
|
const storePath = await getStorePath(workingDir);
|
|
@@ -9574,10 +10088,10 @@ var init_reminder = __esm({
|
|
|
9574
10088
|
|
|
9575
10089
|
// packages/execution/dist/tools/agenda.js
|
|
9576
10090
|
import { readFile as readFile11, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
|
|
9577
|
-
import { resolve as
|
|
10091
|
+
import { resolve as resolve23, join as join25 } from "node:path";
|
|
9578
10092
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
9579
10093
|
async function loadAttentionStore(workingDir) {
|
|
9580
|
-
const storePath =
|
|
10094
|
+
const storePath = resolve23(workingDir, ".oa", "scheduled", "attention.json");
|
|
9581
10095
|
try {
|
|
9582
10096
|
const raw = await readFile11(storePath, "utf-8");
|
|
9583
10097
|
return JSON.parse(raw);
|
|
@@ -9586,10 +10100,10 @@ async function loadAttentionStore(workingDir) {
|
|
|
9586
10100
|
}
|
|
9587
10101
|
}
|
|
9588
10102
|
async function saveAttentionStore(workingDir, store) {
|
|
9589
|
-
const dir =
|
|
10103
|
+
const dir = resolve23(workingDir, ".oa", "scheduled");
|
|
9590
10104
|
await mkdir6(dir, { recursive: true });
|
|
9591
10105
|
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9592
|
-
await writeFile10(
|
|
10106
|
+
await writeFile10(join25(dir, "attention.json"), JSON.stringify(store, null, 2), "utf-8");
|
|
9593
10107
|
}
|
|
9594
10108
|
async function getActiveAttentionItems(workingDir) {
|
|
9595
10109
|
const store = await loadAttentionStore(workingDir);
|
|
@@ -9884,7 +10398,7 @@ ${sections.join("\n")}`,
|
|
|
9884
10398
|
}
|
|
9885
10399
|
async loadScheduleStore() {
|
|
9886
10400
|
try {
|
|
9887
|
-
const storePath =
|
|
10401
|
+
const storePath = resolve23(this.workingDir, ".oa", "scheduled", "tasks.json");
|
|
9888
10402
|
const raw = await readFile11(storePath, "utf-8");
|
|
9889
10403
|
const store = JSON.parse(raw);
|
|
9890
10404
|
return store.tasks ?? [];
|
|
@@ -10012,6 +10526,7 @@ var init_dist2 = __esm({
|
|
|
10012
10526
|
init_pdf_to_text();
|
|
10013
10527
|
init_ocr_image_advanced();
|
|
10014
10528
|
init_browser_action();
|
|
10529
|
+
init_autoresearch();
|
|
10015
10530
|
init_scheduler();
|
|
10016
10531
|
init_reminder();
|
|
10017
10532
|
init_agenda();
|
|
@@ -11147,7 +11662,7 @@ var init_code_retriever = __esm({
|
|
|
11147
11662
|
import { execFile as execFile5 } from "node:child_process";
|
|
11148
11663
|
import { promisify as promisify4 } from "node:util";
|
|
11149
11664
|
import { readFile as readFile12, readdir as readdir3, stat as stat3 } from "node:fs/promises";
|
|
11150
|
-
import { join as
|
|
11665
|
+
import { join as join26, extname as extname7 } from "node:path";
|
|
11151
11666
|
async function searchByPath(pathPattern, options) {
|
|
11152
11667
|
const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
|
|
11153
11668
|
const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
|
|
@@ -11289,7 +11804,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
|
|
|
11289
11804
|
continue;
|
|
11290
11805
|
if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
|
|
11291
11806
|
continue;
|
|
11292
|
-
const absPath =
|
|
11807
|
+
const absPath = join26(dir, entry.name);
|
|
11293
11808
|
if (entry.isDirectory()) {
|
|
11294
11809
|
await walkForFiles(rootDir, absPath, excludeGlobs, results);
|
|
11295
11810
|
} else if (entry.isFile()) {
|
|
@@ -11596,7 +12111,7 @@ var init_graphExpand = __esm({
|
|
|
11596
12111
|
|
|
11597
12112
|
// packages/retrieval/dist/snippetPacker.js
|
|
11598
12113
|
import { readFile as readFile13 } from "node:fs/promises";
|
|
11599
|
-
import { join as
|
|
12114
|
+
import { join as join27 } from "node:path";
|
|
11600
12115
|
async function packSnippets(requests, opts = {}) {
|
|
11601
12116
|
const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
11602
12117
|
const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
@@ -11622,7 +12137,7 @@ async function packSnippets(requests, opts = {}) {
|
|
|
11622
12137
|
return { packed, dropped, totalTokens };
|
|
11623
12138
|
}
|
|
11624
12139
|
async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
11625
|
-
const absPath = req.filePath.startsWith("/") ? req.filePath :
|
|
12140
|
+
const absPath = req.filePath.startsWith("/") ? req.filePath : join27(repoRoot, req.filePath);
|
|
11626
12141
|
let content;
|
|
11627
12142
|
try {
|
|
11628
12143
|
content = await readFile13(absPath, "utf-8");
|
|
@@ -13358,8 +13873,8 @@ Rules:
|
|
|
13358
13873
|
async waitIfPaused() {
|
|
13359
13874
|
if (!this._paused)
|
|
13360
13875
|
return true;
|
|
13361
|
-
await new Promise((
|
|
13362
|
-
this._pauseResolve =
|
|
13876
|
+
await new Promise((resolve27) => {
|
|
13877
|
+
this._pauseResolve = resolve27;
|
|
13363
13878
|
});
|
|
13364
13879
|
return !this.aborted;
|
|
13365
13880
|
}
|
|
@@ -13939,14 +14454,14 @@ ${result.output}`;
|
|
|
13939
14454
|
waitForSudoPassword(timeoutMs = 12e4) {
|
|
13940
14455
|
if (this._sudoPassword)
|
|
13941
14456
|
return Promise.resolve(this._sudoPassword);
|
|
13942
|
-
return new Promise((
|
|
14457
|
+
return new Promise((resolve27) => {
|
|
13943
14458
|
const timer = setTimeout(() => {
|
|
13944
14459
|
this._sudoResolve = null;
|
|
13945
|
-
|
|
14460
|
+
resolve27(null);
|
|
13946
14461
|
}, timeoutMs);
|
|
13947
14462
|
this._sudoResolve = (pw) => {
|
|
13948
14463
|
clearTimeout(timer);
|
|
13949
|
-
|
|
14464
|
+
resolve27(pw);
|
|
13950
14465
|
};
|
|
13951
14466
|
});
|
|
13952
14467
|
}
|
|
@@ -14068,10 +14583,10 @@ ${marker}` : marker);
|
|
|
14068
14583
|
if (!this._workingDirectory)
|
|
14069
14584
|
return;
|
|
14070
14585
|
try {
|
|
14071
|
-
const { mkdirSync:
|
|
14072
|
-
const { join:
|
|
14073
|
-
const sessionDir =
|
|
14074
|
-
|
|
14586
|
+
const { mkdirSync: mkdirSync15, writeFileSync: writeFileSync14 } = __require("node:fs");
|
|
14587
|
+
const { join: join44 } = __require("node:path");
|
|
14588
|
+
const sessionDir = join44(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
14589
|
+
mkdirSync15(sessionDir, { recursive: true });
|
|
14075
14590
|
const checkpoint = {
|
|
14076
14591
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14077
14592
|
sessionId: this._sessionId,
|
|
@@ -14083,7 +14598,7 @@ ${marker}` : marker);
|
|
|
14083
14598
|
memexEntryCount: this._memexArchive.size,
|
|
14084
14599
|
fileRegistrySize: this._fileRegistry.size
|
|
14085
14600
|
};
|
|
14086
|
-
|
|
14601
|
+
writeFileSync14(join44(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
14087
14602
|
} catch {
|
|
14088
14603
|
}
|
|
14089
14604
|
}
|
|
@@ -15621,11 +16136,11 @@ var init_dist5 = __esm({
|
|
|
15621
16136
|
});
|
|
15622
16137
|
|
|
15623
16138
|
// packages/cli/dist/tui/listen.js
|
|
15624
|
-
import { spawn as
|
|
15625
|
-
import { existsSync as
|
|
15626
|
-
import { join as
|
|
16139
|
+
import { spawn as spawn9, execSync as execSync18 } from "node:child_process";
|
|
16140
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readdirSync as readdirSync6 } from "node:fs";
|
|
16141
|
+
import { join as join28, dirname as dirname10 } from "node:path";
|
|
15627
16142
|
import { homedir as homedir8 } from "node:os";
|
|
15628
|
-
import { fileURLToPath as
|
|
16143
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
15629
16144
|
import { EventEmitter } from "node:events";
|
|
15630
16145
|
import { createInterface as createInterface2 } from "node:readline";
|
|
15631
16146
|
function isAudioPath(path) {
|
|
@@ -15643,7 +16158,7 @@ function findMicCaptureCommand() {
|
|
|
15643
16158
|
const platform4 = process.platform;
|
|
15644
16159
|
if (platform4 === "linux") {
|
|
15645
16160
|
try {
|
|
15646
|
-
|
|
16161
|
+
execSync18("which arecord", { stdio: "pipe" });
|
|
15647
16162
|
return {
|
|
15648
16163
|
cmd: "arecord",
|
|
15649
16164
|
args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
|
|
@@ -15653,7 +16168,7 @@ function findMicCaptureCommand() {
|
|
|
15653
16168
|
}
|
|
15654
16169
|
if (platform4 === "darwin") {
|
|
15655
16170
|
try {
|
|
15656
|
-
|
|
16171
|
+
execSync18("which sox", { stdio: "pipe" });
|
|
15657
16172
|
return {
|
|
15658
16173
|
cmd: "sox",
|
|
15659
16174
|
args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
|
|
@@ -15662,7 +16177,7 @@ function findMicCaptureCommand() {
|
|
|
15662
16177
|
}
|
|
15663
16178
|
}
|
|
15664
16179
|
try {
|
|
15665
|
-
|
|
16180
|
+
execSync18("which ffmpeg", { stdio: "pipe" });
|
|
15666
16181
|
if (platform4 === "linux") {
|
|
15667
16182
|
return {
|
|
15668
16183
|
cmd: "ffmpeg",
|
|
@@ -15707,41 +16222,41 @@ function findMicCaptureCommand() {
|
|
|
15707
16222
|
return null;
|
|
15708
16223
|
}
|
|
15709
16224
|
function findLiveWhisperScript() {
|
|
15710
|
-
const thisDir =
|
|
16225
|
+
const thisDir = dirname10(fileURLToPath7(import.meta.url));
|
|
15711
16226
|
const candidates = [
|
|
15712
|
-
|
|
15713
|
-
|
|
15714
|
-
|
|
16227
|
+
join28(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
|
|
16228
|
+
join28(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
|
|
16229
|
+
join28(thisDir, "../../execution/scripts/live-whisper.py"),
|
|
15715
16230
|
// npm install layout — scripts bundled alongside dist
|
|
15716
|
-
|
|
15717
|
-
|
|
16231
|
+
join28(thisDir, "../scripts/live-whisper.py"),
|
|
16232
|
+
join28(thisDir, "../../scripts/live-whisper.py")
|
|
15718
16233
|
];
|
|
15719
16234
|
for (const p of candidates) {
|
|
15720
|
-
if (
|
|
16235
|
+
if (existsSync20(p))
|
|
15721
16236
|
return p;
|
|
15722
16237
|
}
|
|
15723
16238
|
try {
|
|
15724
|
-
const globalRoot =
|
|
16239
|
+
const globalRoot = execSync18("npm root -g", {
|
|
15725
16240
|
encoding: "utf-8",
|
|
15726
16241
|
timeout: 5e3,
|
|
15727
16242
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15728
16243
|
}).trim();
|
|
15729
16244
|
const candidates2 = [
|
|
15730
|
-
|
|
15731
|
-
|
|
16245
|
+
join28(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
|
|
16246
|
+
join28(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
|
|
15732
16247
|
];
|
|
15733
16248
|
for (const p of candidates2) {
|
|
15734
|
-
if (
|
|
16249
|
+
if (existsSync20(p))
|
|
15735
16250
|
return p;
|
|
15736
16251
|
}
|
|
15737
16252
|
} catch {
|
|
15738
16253
|
}
|
|
15739
|
-
const nvmBase =
|
|
15740
|
-
if (
|
|
16254
|
+
const nvmBase = join28(homedir8(), ".nvm", "versions", "node");
|
|
16255
|
+
if (existsSync20(nvmBase)) {
|
|
15741
16256
|
try {
|
|
15742
16257
|
for (const ver of readdirSync6(nvmBase)) {
|
|
15743
|
-
const p =
|
|
15744
|
-
if (
|
|
16258
|
+
const p = join28(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
|
|
16259
|
+
if (existsSync20(p))
|
|
15745
16260
|
return p;
|
|
15746
16261
|
}
|
|
15747
16262
|
} catch {
|
|
@@ -15754,21 +16269,21 @@ function ensureTranscribeCliBackground() {
|
|
|
15754
16269
|
return;
|
|
15755
16270
|
_bgInstallPromise = (async () => {
|
|
15756
16271
|
try {
|
|
15757
|
-
const globalRoot =
|
|
16272
|
+
const globalRoot = execSync18("npm root -g", {
|
|
15758
16273
|
encoding: "utf-8",
|
|
15759
16274
|
timeout: 5e3,
|
|
15760
16275
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15761
16276
|
}).trim();
|
|
15762
|
-
if (
|
|
16277
|
+
if (existsSync20(join28(globalRoot, "transcribe-cli", "dist", "index.js"))) {
|
|
15763
16278
|
return true;
|
|
15764
16279
|
}
|
|
15765
16280
|
} catch {
|
|
15766
16281
|
}
|
|
15767
16282
|
try {
|
|
15768
16283
|
const { exec } = await import("node:child_process");
|
|
15769
|
-
return new Promise((
|
|
16284
|
+
return new Promise((resolve27) => {
|
|
15770
16285
|
exec("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
|
|
15771
|
-
|
|
16286
|
+
resolve27(!err);
|
|
15772
16287
|
});
|
|
15773
16288
|
});
|
|
15774
16289
|
} catch {
|
|
@@ -15821,11 +16336,11 @@ var init_listen = __esm({
|
|
|
15821
16336
|
return this._ready;
|
|
15822
16337
|
}
|
|
15823
16338
|
async start() {
|
|
15824
|
-
return new Promise((
|
|
16339
|
+
return new Promise((resolve27, reject) => {
|
|
15825
16340
|
const timeout = setTimeout(() => {
|
|
15826
16341
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
15827
16342
|
}, 3e5);
|
|
15828
|
-
this.process =
|
|
16343
|
+
this.process = spawn9("python3", [
|
|
15829
16344
|
this.scriptPath,
|
|
15830
16345
|
"--model",
|
|
15831
16346
|
this.model,
|
|
@@ -15849,7 +16364,7 @@ var init_listen = __esm({
|
|
|
15849
16364
|
this._ready = true;
|
|
15850
16365
|
clearTimeout(timeout);
|
|
15851
16366
|
this.emit("ready");
|
|
15852
|
-
|
|
16367
|
+
resolve27();
|
|
15853
16368
|
break;
|
|
15854
16369
|
case "transcript":
|
|
15855
16370
|
this.emit("transcript", {
|
|
@@ -15954,7 +16469,7 @@ var init_listen = __esm({
|
|
|
15954
16469
|
}
|
|
15955
16470
|
if (!this.transcribeCliAvailable) {
|
|
15956
16471
|
try {
|
|
15957
|
-
|
|
16472
|
+
execSync18("which transcribe-cli", { stdio: "pipe" });
|
|
15958
16473
|
this.transcribeCliAvailable = true;
|
|
15959
16474
|
} catch {
|
|
15960
16475
|
this.transcribeCliAvailable = false;
|
|
@@ -15971,29 +16486,29 @@ var init_listen = __esm({
|
|
|
15971
16486
|
} catch {
|
|
15972
16487
|
}
|
|
15973
16488
|
try {
|
|
15974
|
-
const globalRoot =
|
|
16489
|
+
const globalRoot = execSync18("npm root -g", {
|
|
15975
16490
|
encoding: "utf-8",
|
|
15976
16491
|
timeout: 5e3,
|
|
15977
16492
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15978
16493
|
}).trim();
|
|
15979
|
-
const tcPath =
|
|
15980
|
-
if (
|
|
16494
|
+
const tcPath = join28(globalRoot, "transcribe-cli");
|
|
16495
|
+
if (existsSync20(join28(tcPath, "dist", "index.js"))) {
|
|
15981
16496
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
15982
16497
|
const req = createRequire4(import.meta.url);
|
|
15983
|
-
return req(
|
|
16498
|
+
return req(join28(tcPath, "dist", "index.js"));
|
|
15984
16499
|
}
|
|
15985
16500
|
} catch {
|
|
15986
16501
|
}
|
|
15987
|
-
const nvmBase =
|
|
15988
|
-
if (
|
|
16502
|
+
const nvmBase = join28(homedir8(), ".nvm", "versions", "node");
|
|
16503
|
+
if (existsSync20(nvmBase)) {
|
|
15989
16504
|
try {
|
|
15990
16505
|
const { readdirSync: readdirSync14 } = await import("node:fs");
|
|
15991
16506
|
for (const ver of readdirSync14(nvmBase)) {
|
|
15992
|
-
const tcPath =
|
|
15993
|
-
if (
|
|
16507
|
+
const tcPath = join28(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
16508
|
+
if (existsSync20(join28(tcPath, "dist", "index.js"))) {
|
|
15994
16509
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
15995
16510
|
const req = createRequire4(import.meta.url);
|
|
15996
|
-
return req(
|
|
16511
|
+
return req(join28(tcPath, "dist", "index.js"));
|
|
15997
16512
|
}
|
|
15998
16513
|
}
|
|
15999
16514
|
} catch {
|
|
@@ -16021,7 +16536,7 @@ var init_listen = __esm({
|
|
|
16021
16536
|
}
|
|
16022
16537
|
if (!tc) {
|
|
16023
16538
|
try {
|
|
16024
|
-
|
|
16539
|
+
execSync18("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
16025
16540
|
this.transcribeCliAvailable = null;
|
|
16026
16541
|
tc = await this.loadTranscribeCli();
|
|
16027
16542
|
} catch {
|
|
@@ -16053,11 +16568,11 @@ var init_listen = __esm({
|
|
|
16053
16568
|
this.liveTranscriber.on("error", (err) => {
|
|
16054
16569
|
this.emit("error", err);
|
|
16055
16570
|
});
|
|
16056
|
-
await new Promise((
|
|
16571
|
+
await new Promise((resolve27, reject) => {
|
|
16057
16572
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
16058
16573
|
this.liveTranscriber.on("ready", () => {
|
|
16059
16574
|
clearTimeout(timeout);
|
|
16060
|
-
|
|
16575
|
+
resolve27();
|
|
16061
16576
|
});
|
|
16062
16577
|
this.liveTranscriber.on("error", (err) => {
|
|
16063
16578
|
clearTimeout(timeout);
|
|
@@ -16107,7 +16622,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
16107
16622
|
return `Failed to start live transcription: ${msg}${tcHint}`;
|
|
16108
16623
|
}
|
|
16109
16624
|
}
|
|
16110
|
-
this.micProcess =
|
|
16625
|
+
this.micProcess = spawn9(micCmd.cmd, micCmd.args, {
|
|
16111
16626
|
stdio: ["pipe", "pipe", "pipe"],
|
|
16112
16627
|
env: { ...process.env }
|
|
16113
16628
|
});
|
|
@@ -16202,7 +16717,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
16202
16717
|
}
|
|
16203
16718
|
if (!tc) {
|
|
16204
16719
|
try {
|
|
16205
|
-
|
|
16720
|
+
execSync18("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
|
|
16206
16721
|
this.transcribeCliAvailable = null;
|
|
16207
16722
|
tc = await this.loadTranscribeCli();
|
|
16208
16723
|
} catch {
|
|
@@ -16219,10 +16734,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
16219
16734
|
});
|
|
16220
16735
|
if (outputDir) {
|
|
16221
16736
|
const { basename: basename16 } = await import("node:path");
|
|
16222
|
-
const transcriptDir =
|
|
16223
|
-
|
|
16224
|
-
const outFile =
|
|
16225
|
-
|
|
16737
|
+
const transcriptDir = join28(outputDir, ".oa", "transcripts");
|
|
16738
|
+
mkdirSync6(transcriptDir, { recursive: true });
|
|
16739
|
+
const outFile = join28(transcriptDir, `${basename16(filePath)}.txt`);
|
|
16740
|
+
writeFileSync6(outFile, result.text, "utf-8");
|
|
16226
16741
|
}
|
|
16227
16742
|
return {
|
|
16228
16743
|
text: result.text,
|
|
@@ -17538,8 +18053,8 @@ Approach this task thoughtfully:
|
|
|
17538
18053
|
});
|
|
17539
18054
|
|
|
17540
18055
|
// packages/prompts/dist/index.js
|
|
17541
|
-
import { join as
|
|
17542
|
-
import { fileURLToPath as
|
|
18056
|
+
import { join as join29, dirname as dirname11 } from "node:path";
|
|
18057
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
17543
18058
|
var _dir, _packageRoot;
|
|
17544
18059
|
var init_dist6 = __esm({
|
|
17545
18060
|
"packages/prompts/dist/index.js"() {
|
|
@@ -17548,27 +18063,27 @@ var init_dist6 = __esm({
|
|
|
17548
18063
|
init_render2();
|
|
17549
18064
|
init_task_templates();
|
|
17550
18065
|
init_render2();
|
|
17551
|
-
_dir =
|
|
17552
|
-
_packageRoot =
|
|
18066
|
+
_dir = dirname11(fileURLToPath8(import.meta.url));
|
|
18067
|
+
_packageRoot = join29(_dir, "..");
|
|
17553
18068
|
}
|
|
17554
18069
|
});
|
|
17555
18070
|
|
|
17556
18071
|
// packages/cli/dist/tui/oa-directory.js
|
|
17557
|
-
import { existsSync as
|
|
17558
|
-
import { join as
|
|
18072
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync7, readdirSync as readdirSync7, statSync as statSync9, unlinkSync as unlinkSync3 } from "node:fs";
|
|
18073
|
+
import { join as join30, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
|
|
17559
18074
|
import { homedir as homedir9 } from "node:os";
|
|
17560
18075
|
function initOaDirectory(repoRoot) {
|
|
17561
|
-
const oaPath =
|
|
18076
|
+
const oaPath = join30(repoRoot, OA_DIR);
|
|
17562
18077
|
for (const sub of SUBDIRS) {
|
|
17563
|
-
|
|
18078
|
+
mkdirSync7(join30(oaPath, sub), { recursive: true });
|
|
17564
18079
|
}
|
|
17565
18080
|
try {
|
|
17566
|
-
const gitignorePath =
|
|
18081
|
+
const gitignorePath = join30(repoRoot, ".gitignore");
|
|
17567
18082
|
const settingsPattern = ".oa/settings.json";
|
|
17568
|
-
if (
|
|
17569
|
-
const content =
|
|
18083
|
+
if (existsSync21(gitignorePath)) {
|
|
18084
|
+
const content = readFileSync15(gitignorePath, "utf-8");
|
|
17570
18085
|
if (!content.includes(settingsPattern)) {
|
|
17571
|
-
|
|
18086
|
+
writeFileSync7(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
|
|
17572
18087
|
}
|
|
17573
18088
|
}
|
|
17574
18089
|
} catch {
|
|
@@ -17576,41 +18091,41 @@ function initOaDirectory(repoRoot) {
|
|
|
17576
18091
|
return oaPath;
|
|
17577
18092
|
}
|
|
17578
18093
|
function hasOaDirectory(repoRoot) {
|
|
17579
|
-
return
|
|
18094
|
+
return existsSync21(join30(repoRoot, OA_DIR, "index"));
|
|
17580
18095
|
}
|
|
17581
18096
|
function loadProjectSettings(repoRoot) {
|
|
17582
|
-
const settingsPath =
|
|
18097
|
+
const settingsPath = join30(repoRoot, OA_DIR, "settings.json");
|
|
17583
18098
|
try {
|
|
17584
|
-
if (
|
|
17585
|
-
return JSON.parse(
|
|
18099
|
+
if (existsSync21(settingsPath)) {
|
|
18100
|
+
return JSON.parse(readFileSync15(settingsPath, "utf-8"));
|
|
17586
18101
|
}
|
|
17587
18102
|
} catch {
|
|
17588
18103
|
}
|
|
17589
18104
|
return {};
|
|
17590
18105
|
}
|
|
17591
18106
|
function saveProjectSettings(repoRoot, settings) {
|
|
17592
|
-
const oaPath =
|
|
17593
|
-
|
|
18107
|
+
const oaPath = join30(repoRoot, OA_DIR);
|
|
18108
|
+
mkdirSync7(oaPath, { recursive: true });
|
|
17594
18109
|
const existing = loadProjectSettings(repoRoot);
|
|
17595
18110
|
const merged = { ...existing, ...settings };
|
|
17596
|
-
|
|
18111
|
+
writeFileSync7(join30(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
17597
18112
|
}
|
|
17598
18113
|
function loadGlobalSettings() {
|
|
17599
|
-
const settingsPath =
|
|
18114
|
+
const settingsPath = join30(homedir9(), ".open-agents", "settings.json");
|
|
17600
18115
|
try {
|
|
17601
|
-
if (
|
|
17602
|
-
return JSON.parse(
|
|
18116
|
+
if (existsSync21(settingsPath)) {
|
|
18117
|
+
return JSON.parse(readFileSync15(settingsPath, "utf-8"));
|
|
17603
18118
|
}
|
|
17604
18119
|
} catch {
|
|
17605
18120
|
}
|
|
17606
18121
|
return {};
|
|
17607
18122
|
}
|
|
17608
18123
|
function saveGlobalSettings(settings) {
|
|
17609
|
-
const dir =
|
|
17610
|
-
|
|
18124
|
+
const dir = join30(homedir9(), ".open-agents");
|
|
18125
|
+
mkdirSync7(dir, { recursive: true });
|
|
17611
18126
|
const existing = loadGlobalSettings();
|
|
17612
18127
|
const merged = { ...existing, ...settings };
|
|
17613
|
-
|
|
18128
|
+
writeFileSync7(join30(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
|
|
17614
18129
|
}
|
|
17615
18130
|
function resolveSettings(repoRoot) {
|
|
17616
18131
|
const global = loadGlobalSettings();
|
|
@@ -17625,12 +18140,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
17625
18140
|
while (dir && !visited.has(dir)) {
|
|
17626
18141
|
visited.add(dir);
|
|
17627
18142
|
for (const name of CONTEXT_FILES) {
|
|
17628
|
-
const filePath =
|
|
18143
|
+
const filePath = join30(dir, name);
|
|
17629
18144
|
const normalizedName = name.toLowerCase();
|
|
17630
|
-
if (
|
|
18145
|
+
if (existsSync21(filePath) && !seen.has(filePath)) {
|
|
17631
18146
|
seen.add(filePath);
|
|
17632
18147
|
try {
|
|
17633
|
-
let content =
|
|
18148
|
+
let content = readFileSync15(filePath, "utf-8");
|
|
17634
18149
|
if (content.length > maxContentLen) {
|
|
17635
18150
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
17636
18151
|
}
|
|
@@ -17644,11 +18159,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
17644
18159
|
}
|
|
17645
18160
|
}
|
|
17646
18161
|
}
|
|
17647
|
-
const projectMap =
|
|
17648
|
-
if (
|
|
18162
|
+
const projectMap = join30(dir, OA_DIR, "context", "project-map.md");
|
|
18163
|
+
if (existsSync21(projectMap) && !seen.has(projectMap)) {
|
|
17649
18164
|
seen.add(projectMap);
|
|
17650
18165
|
try {
|
|
17651
|
-
let content =
|
|
18166
|
+
let content = readFileSync15(projectMap, "utf-8");
|
|
17652
18167
|
if (content.length > maxContentLen) {
|
|
17653
18168
|
content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
|
|
17654
18169
|
}
|
|
@@ -17660,7 +18175,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
17660
18175
|
} catch {
|
|
17661
18176
|
}
|
|
17662
18177
|
}
|
|
17663
|
-
const parent =
|
|
18178
|
+
const parent = join30(dir, "..");
|
|
17664
18179
|
if (parent === dir)
|
|
17665
18180
|
break;
|
|
17666
18181
|
dir = parent;
|
|
@@ -17678,9 +18193,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
|
|
|
17678
18193
|
return found;
|
|
17679
18194
|
}
|
|
17680
18195
|
function readIndexMeta(repoRoot) {
|
|
17681
|
-
const metaPath =
|
|
18196
|
+
const metaPath = join30(repoRoot, OA_DIR, "index", "meta.json");
|
|
17682
18197
|
try {
|
|
17683
|
-
return JSON.parse(
|
|
18198
|
+
return JSON.parse(readFileSync15(metaPath, "utf-8"));
|
|
17684
18199
|
} catch {
|
|
17685
18200
|
return null;
|
|
17686
18201
|
}
|
|
@@ -17731,28 +18246,28 @@ ${tree}\`\`\`
|
|
|
17731
18246
|
sections.push("");
|
|
17732
18247
|
}
|
|
17733
18248
|
const content = sections.join("\n");
|
|
17734
|
-
const contextDir =
|
|
17735
|
-
|
|
17736
|
-
|
|
18249
|
+
const contextDir = join30(repoRoot, OA_DIR, "context");
|
|
18250
|
+
mkdirSync7(contextDir, { recursive: true });
|
|
18251
|
+
writeFileSync7(join30(contextDir, "project-map.md"), content, "utf-8");
|
|
17737
18252
|
return content;
|
|
17738
18253
|
}
|
|
17739
18254
|
function saveSession(repoRoot, session) {
|
|
17740
|
-
const historyDir =
|
|
17741
|
-
|
|
17742
|
-
|
|
18255
|
+
const historyDir = join30(repoRoot, OA_DIR, "history");
|
|
18256
|
+
mkdirSync7(historyDir, { recursive: true });
|
|
18257
|
+
writeFileSync7(join30(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
|
|
17743
18258
|
}
|
|
17744
18259
|
function loadRecentSessions(repoRoot, limit = 5) {
|
|
17745
|
-
const historyDir =
|
|
17746
|
-
if (!
|
|
18260
|
+
const historyDir = join30(repoRoot, OA_DIR, "history");
|
|
18261
|
+
if (!existsSync21(historyDir))
|
|
17747
18262
|
return [];
|
|
17748
18263
|
try {
|
|
17749
18264
|
const files = readdirSync7(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
|
|
17750
|
-
const stat5 = statSync9(
|
|
18265
|
+
const stat5 = statSync9(join30(historyDir, f));
|
|
17751
18266
|
return { file: f, mtime: stat5.mtimeMs };
|
|
17752
18267
|
}).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
|
|
17753
18268
|
return files.map((f) => {
|
|
17754
18269
|
try {
|
|
17755
|
-
return JSON.parse(
|
|
18270
|
+
return JSON.parse(readFileSync15(join30(historyDir, f.file), "utf-8"));
|
|
17756
18271
|
} catch {
|
|
17757
18272
|
return null;
|
|
17758
18273
|
}
|
|
@@ -17762,16 +18277,16 @@ function loadRecentSessions(repoRoot, limit = 5) {
|
|
|
17762
18277
|
}
|
|
17763
18278
|
}
|
|
17764
18279
|
function savePendingTask(repoRoot, task) {
|
|
17765
|
-
const historyDir =
|
|
17766
|
-
|
|
17767
|
-
|
|
18280
|
+
const historyDir = join30(repoRoot, OA_DIR, "history");
|
|
18281
|
+
mkdirSync7(historyDir, { recursive: true });
|
|
18282
|
+
writeFileSync7(join30(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
|
|
17768
18283
|
}
|
|
17769
18284
|
function loadPendingTask(repoRoot) {
|
|
17770
|
-
const filePath =
|
|
18285
|
+
const filePath = join30(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
|
|
17771
18286
|
try {
|
|
17772
|
-
if (!
|
|
18287
|
+
if (!existsSync21(filePath))
|
|
17773
18288
|
return null;
|
|
17774
|
-
const data = JSON.parse(
|
|
18289
|
+
const data = JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
17775
18290
|
try {
|
|
17776
18291
|
unlinkSync3(filePath);
|
|
17777
18292
|
} catch {
|
|
@@ -17782,13 +18297,13 @@ function loadPendingTask(repoRoot) {
|
|
|
17782
18297
|
}
|
|
17783
18298
|
}
|
|
17784
18299
|
function saveSessionContext(repoRoot, entry) {
|
|
17785
|
-
const contextDir =
|
|
17786
|
-
|
|
17787
|
-
const filePath =
|
|
18300
|
+
const contextDir = join30(repoRoot, OA_DIR, "context");
|
|
18301
|
+
mkdirSync7(contextDir, { recursive: true });
|
|
18302
|
+
const filePath = join30(contextDir, CONTEXT_SAVE_FILE);
|
|
17788
18303
|
let ctx;
|
|
17789
18304
|
try {
|
|
17790
|
-
if (
|
|
17791
|
-
ctx = JSON.parse(
|
|
18305
|
+
if (existsSync21(filePath)) {
|
|
18306
|
+
ctx = JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
17792
18307
|
} else {
|
|
17793
18308
|
ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
|
|
17794
18309
|
}
|
|
@@ -17800,14 +18315,14 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
17800
18315
|
ctx.entries = ctx.entries.slice(-ctx.maxEntries);
|
|
17801
18316
|
}
|
|
17802
18317
|
ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17803
|
-
|
|
18318
|
+
writeFileSync7(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
|
|
17804
18319
|
}
|
|
17805
18320
|
function loadSessionContext(repoRoot) {
|
|
17806
|
-
const filePath =
|
|
18321
|
+
const filePath = join30(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
|
|
17807
18322
|
try {
|
|
17808
|
-
if (!
|
|
18323
|
+
if (!existsSync21(filePath))
|
|
17809
18324
|
return null;
|
|
17810
|
-
return JSON.parse(
|
|
18325
|
+
return JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
17811
18326
|
} catch {
|
|
17812
18327
|
return null;
|
|
17813
18328
|
}
|
|
@@ -17854,12 +18369,12 @@ function detectManifests(repoRoot) {
|
|
|
17854
18369
|
{ file: "docker-compose.yaml", type: "Docker Compose" }
|
|
17855
18370
|
];
|
|
17856
18371
|
for (const check of checks) {
|
|
17857
|
-
const filePath =
|
|
17858
|
-
if (
|
|
18372
|
+
const filePath = join30(repoRoot, check.file);
|
|
18373
|
+
if (existsSync21(filePath)) {
|
|
17859
18374
|
let name;
|
|
17860
18375
|
if (check.nameField) {
|
|
17861
18376
|
try {
|
|
17862
|
-
const data = JSON.parse(
|
|
18377
|
+
const data = JSON.parse(readFileSync15(filePath, "utf-8"));
|
|
17863
18378
|
name = data[check.nameField];
|
|
17864
18379
|
} catch {
|
|
17865
18380
|
}
|
|
@@ -17888,7 +18403,7 @@ function findKeyFiles(repoRoot) {
|
|
|
17888
18403
|
{ pattern: "CLAUDE.md", description: "Claude Code context" }
|
|
17889
18404
|
];
|
|
17890
18405
|
for (const check of checks) {
|
|
17891
|
-
if (
|
|
18406
|
+
if (existsSync21(join30(repoRoot, check.pattern))) {
|
|
17892
18407
|
keyFiles.push({ path: check.pattern, description: check.description });
|
|
17893
18408
|
}
|
|
17894
18409
|
}
|
|
@@ -17914,12 +18429,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
|
|
|
17914
18429
|
if (entry.isDirectory()) {
|
|
17915
18430
|
let fileCount = 0;
|
|
17916
18431
|
try {
|
|
17917
|
-
fileCount = readdirSync7(
|
|
18432
|
+
fileCount = readdirSync7(join30(root, entry.name)).filter((f) => !f.startsWith(".")).length;
|
|
17918
18433
|
} catch {
|
|
17919
18434
|
}
|
|
17920
18435
|
result += `${prefix}${connector}${entry.name}/ (${fileCount})
|
|
17921
18436
|
`;
|
|
17922
|
-
result += buildDirTree(
|
|
18437
|
+
result += buildDirTree(join30(root, entry.name), maxDepth, childPrefix, depth + 1);
|
|
17923
18438
|
} else if (depth < maxDepth) {
|
|
17924
18439
|
result += `${prefix}${connector}${entry.name}
|
|
17925
18440
|
`;
|
|
@@ -17972,9 +18487,9 @@ var init_oa_directory = __esm({
|
|
|
17972
18487
|
|
|
17973
18488
|
// packages/cli/dist/tui/setup.js
|
|
17974
18489
|
import * as readline from "node:readline";
|
|
17975
|
-
import { execSync as
|
|
17976
|
-
import { existsSync as
|
|
17977
|
-
import { join as
|
|
18490
|
+
import { execSync as execSync19, spawn as spawn10 } from "node:child_process";
|
|
18491
|
+
import { existsSync as existsSync22, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "node:fs";
|
|
18492
|
+
import { join as join31 } from "node:path";
|
|
17978
18493
|
import { homedir as homedir10, platform } from "node:os";
|
|
17979
18494
|
function detectSystemSpecs() {
|
|
17980
18495
|
let totalRamGB = 0;
|
|
@@ -17982,7 +18497,7 @@ function detectSystemSpecs() {
|
|
|
17982
18497
|
let gpuVramGB = 0;
|
|
17983
18498
|
let gpuName = "";
|
|
17984
18499
|
try {
|
|
17985
|
-
const memInfo =
|
|
18500
|
+
const memInfo = execSync19("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
|
|
17986
18501
|
encoding: "utf8",
|
|
17987
18502
|
timeout: 5e3
|
|
17988
18503
|
});
|
|
@@ -18002,7 +18517,7 @@ function detectSystemSpecs() {
|
|
|
18002
18517
|
} catch {
|
|
18003
18518
|
}
|
|
18004
18519
|
try {
|
|
18005
|
-
const nvidiaSmi =
|
|
18520
|
+
const nvidiaSmi = execSync19("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
|
|
18006
18521
|
const lines = nvidiaSmi.trim().split("\n");
|
|
18007
18522
|
if (lines.length > 0) {
|
|
18008
18523
|
for (const line of lines) {
|
|
@@ -18058,12 +18573,12 @@ function modelSupportsToolCalling(modelName) {
|
|
|
18058
18573
|
return false;
|
|
18059
18574
|
}
|
|
18060
18575
|
function ask(rl, question) {
|
|
18061
|
-
return new Promise((
|
|
18062
|
-
rl.question(question, (answer) =>
|
|
18576
|
+
return new Promise((resolve27) => {
|
|
18577
|
+
rl.question(question, (answer) => resolve27(answer.trim()));
|
|
18063
18578
|
});
|
|
18064
18579
|
}
|
|
18065
18580
|
function askSecret(rl, question) {
|
|
18066
|
-
return new Promise((
|
|
18581
|
+
return new Promise((resolve27) => {
|
|
18067
18582
|
process.stdout.write(question);
|
|
18068
18583
|
let secret = "";
|
|
18069
18584
|
const stdin = process.stdin;
|
|
@@ -18081,7 +18596,7 @@ function askSecret(rl, question) {
|
|
|
18081
18596
|
stdin.setRawMode(hadRawMode ?? false);
|
|
18082
18597
|
}
|
|
18083
18598
|
process.stdout.write("\n");
|
|
18084
|
-
|
|
18599
|
+
resolve27(secret.trim());
|
|
18085
18600
|
return;
|
|
18086
18601
|
} else if (c3 === "") {
|
|
18087
18602
|
stdin.removeListener("data", onData);
|
|
@@ -18089,7 +18604,7 @@ function askSecret(rl, question) {
|
|
|
18089
18604
|
stdin.setRawMode(hadRawMode ?? false);
|
|
18090
18605
|
}
|
|
18091
18606
|
process.stdout.write("\n");
|
|
18092
|
-
|
|
18607
|
+
resolve27("");
|
|
18093
18608
|
return;
|
|
18094
18609
|
} else if (c3 === "\x7F" || c3 === "\b") {
|
|
18095
18610
|
if (secret.length > 0) {
|
|
@@ -18127,7 +18642,7 @@ function installOllamaLinux() {
|
|
|
18127
18642
|
|
|
18128
18643
|
`);
|
|
18129
18644
|
try {
|
|
18130
|
-
|
|
18645
|
+
execSync19("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
18131
18646
|
stdio: "inherit",
|
|
18132
18647
|
timeout: 3e5
|
|
18133
18648
|
});
|
|
@@ -18166,10 +18681,10 @@ async function installOllamaMac(rl) {
|
|
|
18166
18681
|
|
|
18167
18682
|
`);
|
|
18168
18683
|
try {
|
|
18169
|
-
|
|
18684
|
+
execSync19('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
18170
18685
|
if (!hasCmd("brew")) {
|
|
18171
18686
|
try {
|
|
18172
|
-
const brewPrefix =
|
|
18687
|
+
const brewPrefix = existsSync22("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
18173
18688
|
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
18174
18689
|
} catch {
|
|
18175
18690
|
}
|
|
@@ -18199,7 +18714,7 @@ async function installOllamaMac(rl) {
|
|
|
18199
18714
|
|
|
18200
18715
|
`);
|
|
18201
18716
|
try {
|
|
18202
|
-
|
|
18717
|
+
execSync19("brew install ollama", {
|
|
18203
18718
|
stdio: "inherit",
|
|
18204
18719
|
timeout: 3e5
|
|
18205
18720
|
});
|
|
@@ -18226,7 +18741,7 @@ function installOllamaWindows() {
|
|
|
18226
18741
|
|
|
18227
18742
|
`);
|
|
18228
18743
|
try {
|
|
18229
|
-
|
|
18744
|
+
execSync19('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
18230
18745
|
stdio: "inherit",
|
|
18231
18746
|
timeout: 3e5
|
|
18232
18747
|
});
|
|
@@ -18249,7 +18764,7 @@ function installOllamaWindows() {
|
|
|
18249
18764
|
}
|
|
18250
18765
|
function pullModelWithAutoUpdate(tag) {
|
|
18251
18766
|
try {
|
|
18252
|
-
|
|
18767
|
+
execSync19(`ollama pull ${tag}`, {
|
|
18253
18768
|
stdio: "inherit",
|
|
18254
18769
|
timeout: 36e5
|
|
18255
18770
|
// 1 hour max
|
|
@@ -18266,7 +18781,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
18266
18781
|
|
|
18267
18782
|
`);
|
|
18268
18783
|
try {
|
|
18269
|
-
|
|
18784
|
+
execSync19("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
18270
18785
|
stdio: "inherit",
|
|
18271
18786
|
timeout: 3e5
|
|
18272
18787
|
// 5 min max for install
|
|
@@ -18277,7 +18792,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
18277
18792
|
process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
|
|
18278
18793
|
|
|
18279
18794
|
`);
|
|
18280
|
-
|
|
18795
|
+
execSync19(`ollama pull ${tag}`, {
|
|
18281
18796
|
stdio: "inherit",
|
|
18282
18797
|
timeout: 36e5
|
|
18283
18798
|
});
|
|
@@ -18458,9 +18973,9 @@ async function doSetup(config, rl) {
|
|
|
18458
18973
|
${c2.cyan("\u25CF")} Starting ollama serve in background...
|
|
18459
18974
|
`);
|
|
18460
18975
|
try {
|
|
18461
|
-
const child =
|
|
18976
|
+
const child = spawn10("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
18462
18977
|
child.unref();
|
|
18463
|
-
await new Promise((
|
|
18978
|
+
await new Promise((resolve27) => setTimeout(resolve27, 3e3));
|
|
18464
18979
|
try {
|
|
18465
18980
|
models = await fetchOllamaModels(config.backendUrl);
|
|
18466
18981
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -18486,9 +19001,9 @@ async function doSetup(config, rl) {
|
|
|
18486
19001
|
${c2.cyan("\u25CF")} Starting ollama serve...
|
|
18487
19002
|
`);
|
|
18488
19003
|
try {
|
|
18489
|
-
const child =
|
|
19004
|
+
const child = spawn10("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
18490
19005
|
child.unref();
|
|
18491
|
-
await new Promise((
|
|
19006
|
+
await new Promise((resolve27) => setTimeout(resolve27, 3e3));
|
|
18492
19007
|
try {
|
|
18493
19008
|
models = await fetchOllamaModels(config.backendUrl);
|
|
18494
19009
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -18643,12 +19158,12 @@ async function doSetup(config, rl) {
|
|
|
18643
19158
|
`PARAMETER num_predict ${numPredict}`,
|
|
18644
19159
|
`PARAMETER stop "<|endoftext|>"`
|
|
18645
19160
|
].join("\n");
|
|
18646
|
-
const modelDir2 =
|
|
18647
|
-
|
|
18648
|
-
const modelfilePath =
|
|
18649
|
-
|
|
19161
|
+
const modelDir2 = join31(homedir10(), ".open-agents", "models");
|
|
19162
|
+
mkdirSync8(modelDir2, { recursive: true });
|
|
19163
|
+
const modelfilePath = join31(modelDir2, `Modelfile.${customName}`);
|
|
19164
|
+
writeFileSync8(modelfilePath, modelfileContent + "\n", "utf8");
|
|
18650
19165
|
process.stdout.write(` ${c2.dim("Creating model...")} `);
|
|
18651
|
-
|
|
19166
|
+
execSync19(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
18652
19167
|
stdio: "pipe",
|
|
18653
19168
|
timeout: 12e4
|
|
18654
19169
|
});
|
|
@@ -18691,7 +19206,7 @@ async function isModelAvailable(config) {
|
|
|
18691
19206
|
}
|
|
18692
19207
|
function isFirstRun() {
|
|
18693
19208
|
try {
|
|
18694
|
-
return !
|
|
19209
|
+
return !existsSync22(join31(homedir10(), ".open-agents", "config.json"));
|
|
18695
19210
|
} catch {
|
|
18696
19211
|
return true;
|
|
18697
19212
|
}
|
|
@@ -18699,7 +19214,7 @@ function isFirstRun() {
|
|
|
18699
19214
|
function hasCmd(cmd) {
|
|
18700
19215
|
try {
|
|
18701
19216
|
const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
18702
|
-
|
|
19217
|
+
execSync19(whichCmd, { stdio: "pipe", timeout: 3e3 });
|
|
18703
19218
|
return true;
|
|
18704
19219
|
} catch {
|
|
18705
19220
|
return false;
|
|
@@ -18728,11 +19243,11 @@ function detectPkgManager() {
|
|
|
18728
19243
|
return null;
|
|
18729
19244
|
}
|
|
18730
19245
|
function getVenvDir() {
|
|
18731
|
-
return
|
|
19246
|
+
return join31(homedir10(), ".open-agents", "venv");
|
|
18732
19247
|
}
|
|
18733
19248
|
function hasVenvModule() {
|
|
18734
19249
|
try {
|
|
18735
|
-
|
|
19250
|
+
execSync19("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
18736
19251
|
return true;
|
|
18737
19252
|
} catch {
|
|
18738
19253
|
return false;
|
|
@@ -18740,8 +19255,8 @@ function hasVenvModule() {
|
|
|
18740
19255
|
}
|
|
18741
19256
|
function ensureVenv(log) {
|
|
18742
19257
|
const venvDir = getVenvDir();
|
|
18743
|
-
const venvPip =
|
|
18744
|
-
if (
|
|
19258
|
+
const venvPip = join31(venvDir, "bin", "pip");
|
|
19259
|
+
if (existsSync22(venvPip))
|
|
18745
19260
|
return venvDir;
|
|
18746
19261
|
log("Creating Python venv for vision deps...");
|
|
18747
19262
|
if (!hasCmd("python3")) {
|
|
@@ -18753,9 +19268,9 @@ function ensureVenv(log) {
|
|
|
18753
19268
|
return null;
|
|
18754
19269
|
}
|
|
18755
19270
|
try {
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
19271
|
+
mkdirSync8(join31(homedir10(), ".open-agents"), { recursive: true });
|
|
19272
|
+
execSync19(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
19273
|
+
execSync19(`"${join31(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
18759
19274
|
stdio: "pipe",
|
|
18760
19275
|
timeout: 6e4
|
|
18761
19276
|
});
|
|
@@ -18768,7 +19283,7 @@ function ensureVenv(log) {
|
|
|
18768
19283
|
}
|
|
18769
19284
|
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
18770
19285
|
try {
|
|
18771
|
-
|
|
19286
|
+
execSync19(`sudo -n ${cmd}`, {
|
|
18772
19287
|
stdio: "pipe",
|
|
18773
19288
|
timeout: timeoutMs,
|
|
18774
19289
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
@@ -18780,7 +19295,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
|
18780
19295
|
}
|
|
18781
19296
|
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
18782
19297
|
try {
|
|
18783
|
-
|
|
19298
|
+
execSync19(`sudo -S ${cmd}`, {
|
|
18784
19299
|
input: password + "\n",
|
|
18785
19300
|
stdio: ["pipe", "pipe", "pipe"],
|
|
18786
19301
|
timeout: timeoutMs,
|
|
@@ -18840,7 +19355,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
18840
19355
|
} else {
|
|
18841
19356
|
log("Installing tesseract-ocr...");
|
|
18842
19357
|
try {
|
|
18843
|
-
|
|
19358
|
+
execSync19(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
|
|
18844
19359
|
if (hasCmd("tesseract")) {
|
|
18845
19360
|
log("tesseract-ocr installed successfully.");
|
|
18846
19361
|
} else {
|
|
@@ -18912,7 +19427,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
18912
19427
|
} else {
|
|
18913
19428
|
log(`Installing ${dep.label}...`);
|
|
18914
19429
|
try {
|
|
18915
|
-
|
|
19430
|
+
execSync19(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
|
|
18916
19431
|
if (hasCmd(dep.binary)) {
|
|
18917
19432
|
log(`${dep.label} installed successfully.`);
|
|
18918
19433
|
} else {
|
|
@@ -18943,7 +19458,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
18943
19458
|
const venvCmds = {
|
|
18944
19459
|
apt: () => {
|
|
18945
19460
|
try {
|
|
18946
|
-
const pyVer =
|
|
19461
|
+
const pyVer = execSync19(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
18947
19462
|
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
18948
19463
|
} catch {
|
|
18949
19464
|
return "apt-get install -y python3-venv";
|
|
@@ -18964,19 +19479,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
18964
19479
|
}
|
|
18965
19480
|
}
|
|
18966
19481
|
const venvDir = getVenvDir();
|
|
18967
|
-
const venvBin =
|
|
18968
|
-
const venvMoondream =
|
|
19482
|
+
const venvBin = join31(venvDir, "bin");
|
|
19483
|
+
const venvMoondream = join31(venvBin, "moondream-station");
|
|
18969
19484
|
const venv = ensureVenv(log);
|
|
18970
|
-
if (venv && !hasCmd("moondream-station") && !
|
|
18971
|
-
const venvPip =
|
|
19485
|
+
if (venv && !hasCmd("moondream-station") && !existsSync22(venvMoondream)) {
|
|
19486
|
+
const venvPip = join31(venvBin, "pip");
|
|
18972
19487
|
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
18973
19488
|
try {
|
|
18974
|
-
|
|
18975
|
-
if (
|
|
19489
|
+
execSync19(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
19490
|
+
if (existsSync22(venvMoondream)) {
|
|
18976
19491
|
log("moondream-station installed successfully.");
|
|
18977
19492
|
} else {
|
|
18978
19493
|
try {
|
|
18979
|
-
const check =
|
|
19494
|
+
const check = execSync19(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
18980
19495
|
if (check.includes("moondream")) {
|
|
18981
19496
|
log("moondream-station package installed.");
|
|
18982
19497
|
}
|
|
@@ -18989,11 +19504,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
18989
19504
|
}
|
|
18990
19505
|
}
|
|
18991
19506
|
if (venv) {
|
|
18992
|
-
const venvPython =
|
|
18993
|
-
const venvPip2 =
|
|
19507
|
+
const venvPython = join31(venvBin, "python");
|
|
19508
|
+
const venvPip2 = join31(venvBin, "pip");
|
|
18994
19509
|
let ocrStackInstalled = false;
|
|
18995
19510
|
try {
|
|
18996
|
-
|
|
19511
|
+
execSync19(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
18997
19512
|
ocrStackInstalled = true;
|
|
18998
19513
|
} catch {
|
|
18999
19514
|
}
|
|
@@ -19001,9 +19516,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
19001
19516
|
const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
|
|
19002
19517
|
log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
|
|
19003
19518
|
try {
|
|
19004
|
-
|
|
19519
|
+
execSync19(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
|
|
19005
19520
|
try {
|
|
19006
|
-
|
|
19521
|
+
execSync19(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
|
|
19007
19522
|
log("OCR Python stack installed successfully.");
|
|
19008
19523
|
} catch {
|
|
19009
19524
|
log("OCR Python stack install completed but import verification failed.");
|
|
@@ -19050,11 +19565,11 @@ function createExpandedVariant(baseModel, specs, sizeGB) {
|
|
|
19050
19565
|
`PARAMETER num_predict ${numPredict}`,
|
|
19051
19566
|
`PARAMETER stop "<|endoftext|>"`
|
|
19052
19567
|
].join("\n");
|
|
19053
|
-
const modelDir2 =
|
|
19054
|
-
|
|
19055
|
-
const modelfilePath =
|
|
19056
|
-
|
|
19057
|
-
|
|
19568
|
+
const modelDir2 = join31(homedir10(), ".open-agents", "models");
|
|
19569
|
+
mkdirSync8(modelDir2, { recursive: true });
|
|
19570
|
+
const modelfilePath = join31(modelDir2, `Modelfile.${customName}`);
|
|
19571
|
+
writeFileSync8(modelfilePath, modelfileContent + "\n", "utf8");
|
|
19572
|
+
execSync19(`ollama create ${customName} -f ${modelfilePath}`, {
|
|
19058
19573
|
stdio: "pipe",
|
|
19059
19574
|
timeout: 12e4
|
|
19060
19575
|
});
|
|
@@ -19941,18 +20456,18 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
19941
20456
|
let currentVersion = "0.0.0";
|
|
19942
20457
|
try {
|
|
19943
20458
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
19944
|
-
const { fileURLToPath:
|
|
19945
|
-
const { dirname:
|
|
19946
|
-
const { existsSync:
|
|
20459
|
+
const { fileURLToPath: fileURLToPath11 } = await import("node:url");
|
|
20460
|
+
const { dirname: dirname14, join: join44 } = await import("node:path");
|
|
20461
|
+
const { existsSync: existsSync31 } = await import("node:fs");
|
|
19947
20462
|
const req = createRequire4(import.meta.url);
|
|
19948
|
-
const thisDir =
|
|
20463
|
+
const thisDir = dirname14(fileURLToPath11(import.meta.url));
|
|
19949
20464
|
const candidates = [
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
|
|
20465
|
+
join44(thisDir, "..", "package.json"),
|
|
20466
|
+
join44(thisDir, "..", "..", "package.json"),
|
|
20467
|
+
join44(thisDir, "..", "..", "..", "package.json")
|
|
19953
20468
|
];
|
|
19954
20469
|
for (const pkgPath of candidates) {
|
|
19955
|
-
if (
|
|
20470
|
+
if (existsSync31(pkgPath)) {
|
|
19956
20471
|
const pkg = req(pkgPath);
|
|
19957
20472
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
19958
20473
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -19990,8 +20505,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
19990
20505
|
checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
|
|
19991
20506
|
const installSpinner = startInlineSpinner("Installing update");
|
|
19992
20507
|
const { exec } = await import("node:child_process");
|
|
19993
|
-
const installOk = await new Promise((
|
|
19994
|
-
const child = exec(`npm cache clean --force open-agents-ai 2>/dev/null; npm install -g open-agents-ai@latest --force`, { timeout: 18e4 }, (err) =>
|
|
20508
|
+
const installOk = await new Promise((resolve27) => {
|
|
20509
|
+
const child = exec(`npm cache clean --force open-agents-ai 2>/dev/null; npm install -g open-agents-ai@latest --force`, { timeout: 18e4 }, (err) => resolve27(!err));
|
|
19995
20510
|
child.stdout?.resume();
|
|
19996
20511
|
child.stderr?.resume();
|
|
19997
20512
|
});
|
|
@@ -20084,9 +20599,9 @@ var init_commands = __esm({
|
|
|
20084
20599
|
});
|
|
20085
20600
|
|
|
20086
20601
|
// packages/cli/dist/tui/project-context.js
|
|
20087
|
-
import { existsSync as
|
|
20088
|
-
import { join as
|
|
20089
|
-
import { execSync as
|
|
20602
|
+
import { existsSync as existsSync23, readFileSync as readFileSync16, readdirSync as readdirSync8 } from "node:fs";
|
|
20603
|
+
import { join as join32, basename as basename10 } from "node:path";
|
|
20604
|
+
import { execSync as execSync20 } from "node:child_process";
|
|
20090
20605
|
import { homedir as homedir11, platform as platform2, release } from "node:os";
|
|
20091
20606
|
function getModelTier(modelName) {
|
|
20092
20607
|
const m = modelName.toLowerCase();
|
|
@@ -20120,10 +20635,10 @@ function loadProjectMap(repoRoot) {
|
|
|
20120
20635
|
if (!hasOaDirectory(repoRoot)) {
|
|
20121
20636
|
initOaDirectory(repoRoot);
|
|
20122
20637
|
}
|
|
20123
|
-
const mapPath =
|
|
20124
|
-
if (
|
|
20638
|
+
const mapPath = join32(repoRoot, OA_DIR, "context", "project-map.md");
|
|
20639
|
+
if (existsSync23(mapPath)) {
|
|
20125
20640
|
try {
|
|
20126
|
-
const content =
|
|
20641
|
+
const content = readFileSync16(mapPath, "utf-8");
|
|
20127
20642
|
return content;
|
|
20128
20643
|
} catch {
|
|
20129
20644
|
}
|
|
@@ -20132,19 +20647,19 @@ function loadProjectMap(repoRoot) {
|
|
|
20132
20647
|
}
|
|
20133
20648
|
function getGitInfo(repoRoot) {
|
|
20134
20649
|
try {
|
|
20135
|
-
|
|
20650
|
+
execSync20("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
|
|
20136
20651
|
} catch {
|
|
20137
20652
|
return "";
|
|
20138
20653
|
}
|
|
20139
20654
|
const lines = [];
|
|
20140
20655
|
try {
|
|
20141
|
-
const branch =
|
|
20656
|
+
const branch = execSync20("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
20142
20657
|
if (branch)
|
|
20143
20658
|
lines.push(`Branch: ${branch}`);
|
|
20144
20659
|
} catch {
|
|
20145
20660
|
}
|
|
20146
20661
|
try {
|
|
20147
|
-
const status =
|
|
20662
|
+
const status = execSync20("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
20148
20663
|
if (status) {
|
|
20149
20664
|
const changed = status.split("\n").length;
|
|
20150
20665
|
lines.push(`Working tree: ${changed} changed file(s)`);
|
|
@@ -20154,7 +20669,7 @@ function getGitInfo(repoRoot) {
|
|
|
20154
20669
|
} catch {
|
|
20155
20670
|
}
|
|
20156
20671
|
try {
|
|
20157
|
-
const log =
|
|
20672
|
+
const log = execSync20("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
|
|
20158
20673
|
if (log)
|
|
20159
20674
|
lines.push(`Recent commits:
|
|
20160
20675
|
${log}`);
|
|
@@ -20164,31 +20679,31 @@ ${log}`);
|
|
|
20164
20679
|
}
|
|
20165
20680
|
function loadMemoryContext(repoRoot) {
|
|
20166
20681
|
const sections = [];
|
|
20167
|
-
const oaMemDir =
|
|
20682
|
+
const oaMemDir = join32(repoRoot, OA_DIR, "memory");
|
|
20168
20683
|
const oaEntries = loadMemoryDir(oaMemDir, "project");
|
|
20169
20684
|
if (oaEntries)
|
|
20170
20685
|
sections.push(oaEntries);
|
|
20171
|
-
const legacyMemDir =
|
|
20172
|
-
if (legacyMemDir !== oaMemDir &&
|
|
20686
|
+
const legacyMemDir = join32(repoRoot, ".open-agents", "memory");
|
|
20687
|
+
if (legacyMemDir !== oaMemDir && existsSync23(legacyMemDir)) {
|
|
20173
20688
|
const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
|
|
20174
20689
|
if (legacyEntries)
|
|
20175
20690
|
sections.push(legacyEntries);
|
|
20176
20691
|
}
|
|
20177
|
-
const globalMemDir =
|
|
20692
|
+
const globalMemDir = join32(homedir11(), ".open-agents", "memory");
|
|
20178
20693
|
const globalEntries = loadMemoryDir(globalMemDir, "global");
|
|
20179
20694
|
if (globalEntries)
|
|
20180
20695
|
sections.push(globalEntries);
|
|
20181
20696
|
return sections.join("\n\n");
|
|
20182
20697
|
}
|
|
20183
20698
|
function loadMemoryDir(memDir, scope) {
|
|
20184
|
-
if (!
|
|
20699
|
+
if (!existsSync23(memDir))
|
|
20185
20700
|
return "";
|
|
20186
20701
|
const lines = [];
|
|
20187
20702
|
try {
|
|
20188
20703
|
const files = readdirSync8(memDir).filter((f) => f.endsWith(".json"));
|
|
20189
20704
|
for (const file of files.slice(0, 10)) {
|
|
20190
20705
|
try {
|
|
20191
|
-
const raw =
|
|
20706
|
+
const raw = readFileSync16(join32(memDir, file), "utf-8");
|
|
20192
20707
|
const entries = JSON.parse(raw);
|
|
20193
20708
|
const topic = basename10(file, ".json");
|
|
20194
20709
|
const keys = Object.keys(entries);
|
|
@@ -21215,22 +21730,22 @@ var init_carousel = __esm({
|
|
|
21215
21730
|
});
|
|
21216
21731
|
|
|
21217
21732
|
// packages/cli/dist/tui/carousel-descriptors.js
|
|
21218
|
-
import { existsSync as
|
|
21219
|
-
import { join as
|
|
21733
|
+
import { existsSync as existsSync24, readFileSync as readFileSync17, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, readdirSync as readdirSync9 } from "node:fs";
|
|
21734
|
+
import { join as join33, basename as basename11 } from "node:path";
|
|
21220
21735
|
function loadToolProfile(repoRoot) {
|
|
21221
|
-
const filePath =
|
|
21736
|
+
const filePath = join33(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
|
|
21222
21737
|
try {
|
|
21223
|
-
if (!
|
|
21738
|
+
if (!existsSync24(filePath))
|
|
21224
21739
|
return null;
|
|
21225
|
-
return JSON.parse(
|
|
21740
|
+
return JSON.parse(readFileSync17(filePath, "utf-8"));
|
|
21226
21741
|
} catch {
|
|
21227
21742
|
return null;
|
|
21228
21743
|
}
|
|
21229
21744
|
}
|
|
21230
21745
|
function saveToolProfile(repoRoot, profile) {
|
|
21231
|
-
const contextDir =
|
|
21232
|
-
|
|
21233
|
-
|
|
21746
|
+
const contextDir = join33(repoRoot, OA_DIR, "context");
|
|
21747
|
+
mkdirSync9(contextDir, { recursive: true });
|
|
21748
|
+
writeFileSync9(join33(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
|
|
21234
21749
|
}
|
|
21235
21750
|
function categorizeToolCall(toolName) {
|
|
21236
21751
|
for (const cat of TOOL_CATEGORIES) {
|
|
@@ -21288,25 +21803,25 @@ function weightedColor(profile) {
|
|
|
21288
21803
|
return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
|
|
21289
21804
|
}
|
|
21290
21805
|
function loadCachedDescriptors(repoRoot) {
|
|
21291
|
-
const filePath =
|
|
21806
|
+
const filePath = join33(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
|
|
21292
21807
|
try {
|
|
21293
|
-
if (!
|
|
21808
|
+
if (!existsSync24(filePath))
|
|
21294
21809
|
return null;
|
|
21295
|
-
const cached = JSON.parse(
|
|
21810
|
+
const cached = JSON.parse(readFileSync17(filePath, "utf-8"));
|
|
21296
21811
|
return cached.phrases.length > 0 ? cached.phrases : null;
|
|
21297
21812
|
} catch {
|
|
21298
21813
|
return null;
|
|
21299
21814
|
}
|
|
21300
21815
|
}
|
|
21301
21816
|
function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
|
|
21302
|
-
const contextDir =
|
|
21303
|
-
|
|
21817
|
+
const contextDir = join33(repoRoot, OA_DIR, "context");
|
|
21818
|
+
mkdirSync9(contextDir, { recursive: true });
|
|
21304
21819
|
const cached = {
|
|
21305
21820
|
phrases,
|
|
21306
21821
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21307
21822
|
sourceHash
|
|
21308
21823
|
};
|
|
21309
|
-
|
|
21824
|
+
writeFileSync9(join33(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
|
|
21310
21825
|
}
|
|
21311
21826
|
function generateDescriptors(repoRoot) {
|
|
21312
21827
|
const profile = loadToolProfile(repoRoot);
|
|
@@ -21354,11 +21869,11 @@ function generateDescriptors(repoRoot) {
|
|
|
21354
21869
|
return phrases;
|
|
21355
21870
|
}
|
|
21356
21871
|
function extractFromPackageJson(repoRoot, tags) {
|
|
21357
|
-
const pkgPath =
|
|
21872
|
+
const pkgPath = join33(repoRoot, "package.json");
|
|
21358
21873
|
try {
|
|
21359
|
-
if (!
|
|
21874
|
+
if (!existsSync24(pkgPath))
|
|
21360
21875
|
return;
|
|
21361
|
-
const pkg = JSON.parse(
|
|
21876
|
+
const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
|
|
21362
21877
|
if (pkg.name && typeof pkg.name === "string") {
|
|
21363
21878
|
const parts = pkg.name.replace(/^@/, "").split("/");
|
|
21364
21879
|
for (const p of parts)
|
|
@@ -21402,7 +21917,7 @@ function extractFromManifests(repoRoot, tags) {
|
|
|
21402
21917
|
{ file: ".github/workflows", tag: "ci/cd" }
|
|
21403
21918
|
];
|
|
21404
21919
|
for (const check of manifestChecks) {
|
|
21405
|
-
if (
|
|
21920
|
+
if (existsSync24(join33(repoRoot, check.file))) {
|
|
21406
21921
|
tags.push(check.tag);
|
|
21407
21922
|
}
|
|
21408
21923
|
}
|
|
@@ -21424,16 +21939,16 @@ function extractFromSessions(repoRoot, tags) {
|
|
|
21424
21939
|
}
|
|
21425
21940
|
}
|
|
21426
21941
|
function extractFromMemory(repoRoot, tags) {
|
|
21427
|
-
const memoryDir =
|
|
21942
|
+
const memoryDir = join33(repoRoot, OA_DIR, "memory");
|
|
21428
21943
|
try {
|
|
21429
|
-
if (!
|
|
21944
|
+
if (!existsSync24(memoryDir))
|
|
21430
21945
|
return;
|
|
21431
21946
|
const files = readdirSync9(memoryDir).filter((f) => f.endsWith(".json"));
|
|
21432
21947
|
for (const file of files) {
|
|
21433
21948
|
const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
|
|
21434
21949
|
tags.push(topic);
|
|
21435
21950
|
try {
|
|
21436
|
-
const data = JSON.parse(
|
|
21951
|
+
const data = JSON.parse(readFileSync17(join33(memoryDir, file), "utf-8"));
|
|
21437
21952
|
if (data && typeof data === "object") {
|
|
21438
21953
|
const keys = Object.keys(data).slice(0, 3);
|
|
21439
21954
|
for (const key of keys) {
|
|
@@ -21568,25 +22083,25 @@ var init_carousel_descriptors = __esm({
|
|
|
21568
22083
|
});
|
|
21569
22084
|
|
|
21570
22085
|
// packages/cli/dist/tui/voice.js
|
|
21571
|
-
import { existsSync as
|
|
21572
|
-
import { join as
|
|
22086
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10, readFileSync as readFileSync18, unlinkSync as unlinkSync4 } from "node:fs";
|
|
22087
|
+
import { join as join34 } from "node:path";
|
|
21573
22088
|
import { homedir as homedir12, tmpdir as tmpdir6, platform as platform3 } from "node:os";
|
|
21574
|
-
import { execSync as
|
|
22089
|
+
import { execSync as execSync21, spawn as nodeSpawn } from "node:child_process";
|
|
21575
22090
|
import { createRequire } from "node:module";
|
|
21576
22091
|
function voiceDir() {
|
|
21577
|
-
return
|
|
22092
|
+
return join34(homedir12(), ".open-agents", "voice");
|
|
21578
22093
|
}
|
|
21579
22094
|
function modelsDir() {
|
|
21580
|
-
return
|
|
22095
|
+
return join34(voiceDir(), "models");
|
|
21581
22096
|
}
|
|
21582
22097
|
function modelDir(id) {
|
|
21583
|
-
return
|
|
22098
|
+
return join34(modelsDir(), id);
|
|
21584
22099
|
}
|
|
21585
22100
|
function modelOnnxPath(id) {
|
|
21586
|
-
return
|
|
22101
|
+
return join34(modelDir(id), "model.onnx");
|
|
21587
22102
|
}
|
|
21588
22103
|
function modelConfigPath(id) {
|
|
21589
|
-
return
|
|
22104
|
+
return join34(modelDir(id), "config.json");
|
|
21590
22105
|
}
|
|
21591
22106
|
function describeToolCall(toolName, args, personality = 2) {
|
|
21592
22107
|
const path = args["path"];
|
|
@@ -22032,7 +22547,7 @@ var init_voice = __esm({
|
|
|
22032
22547
|
const audioData = result["output"].data;
|
|
22033
22548
|
if (audioData.length === 0)
|
|
22034
22549
|
return;
|
|
22035
|
-
const wavPath =
|
|
22550
|
+
const wavPath = join34(tmpdir6(), `oa-voice-${Date.now()}.wav`);
|
|
22036
22551
|
this.writeWav(audioData, this.config.audio.sample_rate, wavPath);
|
|
22037
22552
|
await this.playWav(wavPath);
|
|
22038
22553
|
try {
|
|
@@ -22112,7 +22627,7 @@ var init_voice = __esm({
|
|
|
22112
22627
|
buffer.write("data", 36);
|
|
22113
22628
|
buffer.writeUInt32LE(dataSize, 40);
|
|
22114
22629
|
Buffer.from(int16.buffer, int16.byteOffset, int16.byteLength).copy(buffer, 44);
|
|
22115
|
-
|
|
22630
|
+
writeFileSync10(path, buffer);
|
|
22116
22631
|
}
|
|
22117
22632
|
// -------------------------------------------------------------------------
|
|
22118
22633
|
// Audio playback (system default speakers)
|
|
@@ -22121,7 +22636,7 @@ var init_voice = __esm({
|
|
|
22121
22636
|
const cmd = this.getPlayCommand(path);
|
|
22122
22637
|
if (!cmd)
|
|
22123
22638
|
return;
|
|
22124
|
-
return new Promise((
|
|
22639
|
+
return new Promise((resolve27) => {
|
|
22125
22640
|
const child = nodeSpawn(cmd[0], cmd.slice(1), {
|
|
22126
22641
|
stdio: "ignore",
|
|
22127
22642
|
detached: false
|
|
@@ -22130,12 +22645,12 @@ var init_voice = __esm({
|
|
|
22130
22645
|
child.on("close", () => {
|
|
22131
22646
|
if (this.currentPlayback === child)
|
|
22132
22647
|
this.currentPlayback = null;
|
|
22133
|
-
|
|
22648
|
+
resolve27();
|
|
22134
22649
|
});
|
|
22135
22650
|
child.on("error", () => {
|
|
22136
22651
|
if (this.currentPlayback === child)
|
|
22137
22652
|
this.currentPlayback = null;
|
|
22138
|
-
|
|
22653
|
+
resolve27();
|
|
22139
22654
|
});
|
|
22140
22655
|
setTimeout(() => {
|
|
22141
22656
|
if (this.currentPlayback === child) {
|
|
@@ -22145,7 +22660,7 @@ var init_voice = __esm({
|
|
|
22145
22660
|
}
|
|
22146
22661
|
this.currentPlayback = null;
|
|
22147
22662
|
}
|
|
22148
|
-
|
|
22663
|
+
resolve27();
|
|
22149
22664
|
}, 15e3);
|
|
22150
22665
|
});
|
|
22151
22666
|
}
|
|
@@ -22162,7 +22677,7 @@ var init_voice = __esm({
|
|
|
22162
22677
|
}
|
|
22163
22678
|
for (const player of ["paplay", "pw-play", "aplay"]) {
|
|
22164
22679
|
try {
|
|
22165
|
-
|
|
22680
|
+
execSync21(`which ${player}`, { stdio: "pipe" });
|
|
22166
22681
|
return [player, path];
|
|
22167
22682
|
} catch {
|
|
22168
22683
|
}
|
|
@@ -22186,30 +22701,30 @@ var init_voice = __esm({
|
|
|
22186
22701
|
return;
|
|
22187
22702
|
const arch = process.arch;
|
|
22188
22703
|
const isArmLinux = (arch === "arm64" || arch === "arm") && process.platform === "linux";
|
|
22189
|
-
|
|
22190
|
-
const pkgPath =
|
|
22704
|
+
mkdirSync10(voiceDir(), { recursive: true });
|
|
22705
|
+
const pkgPath = join34(voiceDir(), "package.json");
|
|
22191
22706
|
const expectedDeps = {
|
|
22192
22707
|
"onnxruntime-node": "^1.21.0",
|
|
22193
22708
|
"phonemizer": "^1.2.1"
|
|
22194
22709
|
};
|
|
22195
|
-
if (
|
|
22710
|
+
if (existsSync25(pkgPath)) {
|
|
22196
22711
|
try {
|
|
22197
|
-
const existing = JSON.parse(
|
|
22712
|
+
const existing = JSON.parse(readFileSync18(pkgPath, "utf8"));
|
|
22198
22713
|
if (!existing.dependencies?.["phonemizer"]) {
|
|
22199
22714
|
existing.dependencies = { ...existing.dependencies, ...expectedDeps };
|
|
22200
|
-
|
|
22715
|
+
writeFileSync10(pkgPath, JSON.stringify(existing, null, 2));
|
|
22201
22716
|
}
|
|
22202
22717
|
} catch {
|
|
22203
22718
|
}
|
|
22204
22719
|
}
|
|
22205
|
-
if (!
|
|
22206
|
-
|
|
22720
|
+
if (!existsSync25(pkgPath)) {
|
|
22721
|
+
writeFileSync10(pkgPath, JSON.stringify({
|
|
22207
22722
|
name: "open-agents-voice",
|
|
22208
22723
|
private: true,
|
|
22209
22724
|
dependencies: expectedDeps
|
|
22210
22725
|
}, null, 2));
|
|
22211
22726
|
}
|
|
22212
|
-
const voiceRequire = createRequire(
|
|
22727
|
+
const voiceRequire = createRequire(join34(voiceDir(), "index.js"));
|
|
22213
22728
|
try {
|
|
22214
22729
|
this.ort = voiceRequire("onnxruntime-node");
|
|
22215
22730
|
} catch {
|
|
@@ -22218,7 +22733,7 @@ var init_voice = __esm({
|
|
|
22218
22733
|
}
|
|
22219
22734
|
renderInfo("Installing ONNX runtime for voice synthesis...");
|
|
22220
22735
|
try {
|
|
22221
|
-
|
|
22736
|
+
execSync21("npm install --no-audit --no-fund", {
|
|
22222
22737
|
cwd: voiceDir(),
|
|
22223
22738
|
stdio: "pipe",
|
|
22224
22739
|
timeout: 12e4
|
|
@@ -22239,7 +22754,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
22239
22754
|
}
|
|
22240
22755
|
renderInfo("Installing phonemizer for voice synthesis...");
|
|
22241
22756
|
try {
|
|
22242
|
-
|
|
22757
|
+
execSync21("npm install --no-audit --no-fund", {
|
|
22243
22758
|
cwd: voiceDir(),
|
|
22244
22759
|
stdio: "pipe",
|
|
22245
22760
|
timeout: 12e4
|
|
@@ -22263,18 +22778,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
22263
22778
|
const dir = modelDir(id);
|
|
22264
22779
|
const onnxPath = modelOnnxPath(id);
|
|
22265
22780
|
const configPath = modelConfigPath(id);
|
|
22266
|
-
if (
|
|
22781
|
+
if (existsSync25(onnxPath) && existsSync25(configPath))
|
|
22267
22782
|
return;
|
|
22268
|
-
|
|
22269
|
-
if (!
|
|
22783
|
+
mkdirSync10(dir, { recursive: true });
|
|
22784
|
+
if (!existsSync25(configPath)) {
|
|
22270
22785
|
renderInfo(`Downloading ${model.label} voice config...`);
|
|
22271
22786
|
const configResp = await fetch(model.configUrl);
|
|
22272
22787
|
if (!configResp.ok)
|
|
22273
22788
|
throw new Error(`Failed to download config: HTTP ${configResp.status}`);
|
|
22274
22789
|
const configText = await configResp.text();
|
|
22275
|
-
|
|
22790
|
+
writeFileSync10(configPath, configText);
|
|
22276
22791
|
}
|
|
22277
|
-
if (!
|
|
22792
|
+
if (!existsSync25(onnxPath)) {
|
|
22278
22793
|
renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
|
|
22279
22794
|
const onnxResp = await fetch(model.onnxUrl);
|
|
22280
22795
|
if (!onnxResp.ok)
|
|
@@ -22298,7 +22813,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
22298
22813
|
}
|
|
22299
22814
|
process.stdout.write("\r" + " ".repeat(60) + "\r");
|
|
22300
22815
|
const fullBuffer = Buffer.concat(chunks);
|
|
22301
|
-
|
|
22816
|
+
writeFileSync10(onnxPath, fullBuffer);
|
|
22302
22817
|
renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
|
|
22303
22818
|
}
|
|
22304
22819
|
}
|
|
@@ -22310,10 +22825,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
22310
22825
|
throw new Error("ONNX runtime not loaded");
|
|
22311
22826
|
const onnxPath = modelOnnxPath(this.modelId);
|
|
22312
22827
|
const configPath = modelConfigPath(this.modelId);
|
|
22313
|
-
if (!
|
|
22828
|
+
if (!existsSync25(onnxPath) || !existsSync25(configPath)) {
|
|
22314
22829
|
throw new Error(`Model files not found for ${this.modelId}`);
|
|
22315
22830
|
}
|
|
22316
|
-
this.config = JSON.parse(
|
|
22831
|
+
this.config = JSON.parse(readFileSync18(configPath, "utf8"));
|
|
22317
22832
|
renderInfo("Loading voice model...");
|
|
22318
22833
|
this.session = await this.ort.InferenceSession.create(onnxPath, {
|
|
22319
22834
|
executionProviders: ["cpu"],
|
|
@@ -22813,13 +23328,13 @@ var init_stream_renderer = __esm({
|
|
|
22813
23328
|
});
|
|
22814
23329
|
|
|
22815
23330
|
// packages/cli/dist/tui/edit-history.js
|
|
22816
|
-
import { appendFileSync, mkdirSync as
|
|
22817
|
-
import { join as
|
|
23331
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync11 } from "node:fs";
|
|
23332
|
+
import { join as join35 } from "node:path";
|
|
22818
23333
|
function createEditHistoryLogger(repoRoot, sessionId) {
|
|
22819
|
-
const historyDir =
|
|
22820
|
-
const logPath =
|
|
23334
|
+
const historyDir = join35(repoRoot, ".oa", "history");
|
|
23335
|
+
const logPath = join35(historyDir, "edits.jsonl");
|
|
22821
23336
|
try {
|
|
22822
|
-
|
|
23337
|
+
mkdirSync11(historyDir, { recursive: true });
|
|
22823
23338
|
} catch {
|
|
22824
23339
|
}
|
|
22825
23340
|
function logToolCall(toolName, toolArgs, success) {
|
|
@@ -22835,7 +23350,7 @@ function createEditHistoryLogger(repoRoot, sessionId) {
|
|
|
22835
23350
|
args: sanitizeArgs(toolName, toolArgs)
|
|
22836
23351
|
};
|
|
22837
23352
|
try {
|
|
22838
|
-
|
|
23353
|
+
appendFileSync2(logPath, JSON.stringify(entry) + "\n", "utf-8");
|
|
22839
23354
|
} catch {
|
|
22840
23355
|
}
|
|
22841
23356
|
}
|
|
@@ -22928,9 +23443,9 @@ var init_edit_history = __esm({
|
|
|
22928
23443
|
});
|
|
22929
23444
|
|
|
22930
23445
|
// packages/cli/dist/tui/dream-engine.js
|
|
22931
|
-
import { mkdirSync as
|
|
22932
|
-
import { join as
|
|
22933
|
-
import { execSync as
|
|
23446
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync11, readFileSync as readFileSync19, existsSync as existsSync26, cpSync, rmSync, readdirSync as readdirSync10 } from "node:fs";
|
|
23447
|
+
import { join as join36, basename as basename12 } from "node:path";
|
|
23448
|
+
import { execSync as execSync22 } from "node:child_process";
|
|
22934
23449
|
function adaptTool(tool) {
|
|
22935
23450
|
return {
|
|
22936
23451
|
name: tool.name,
|
|
@@ -23104,14 +23619,14 @@ var init_dream_engine = __esm({
|
|
|
23104
23619
|
const content = String(args["content"] ?? "");
|
|
23105
23620
|
if (!rawPath)
|
|
23106
23621
|
return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
|
|
23107
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
23622
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join36(this.dreamsDir, basename12(rawPath)) : join36(this.dreamsDir, rawPath);
|
|
23108
23623
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
23109
23624
|
return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
23110
23625
|
}
|
|
23111
23626
|
try {
|
|
23112
|
-
const dir =
|
|
23113
|
-
|
|
23114
|
-
|
|
23627
|
+
const dir = join36(targetPath, "..");
|
|
23628
|
+
mkdirSync12(dir, { recursive: true });
|
|
23629
|
+
writeFileSync11(targetPath, content, "utf-8");
|
|
23115
23630
|
return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
|
|
23116
23631
|
} catch (err) {
|
|
23117
23632
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -23139,20 +23654,20 @@ var init_dream_engine = __esm({
|
|
|
23139
23654
|
const rawPath = String(args["path"] ?? "");
|
|
23140
23655
|
const oldStr = String(args["old_string"] ?? "");
|
|
23141
23656
|
const newStr = String(args["new_string"] ?? "");
|
|
23142
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ?
|
|
23657
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join36(this.dreamsDir, basename12(rawPath)) : join36(this.dreamsDir, rawPath);
|
|
23143
23658
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
23144
23659
|
return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
|
|
23145
23660
|
}
|
|
23146
23661
|
try {
|
|
23147
|
-
if (!
|
|
23662
|
+
if (!existsSync26(targetPath)) {
|
|
23148
23663
|
return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
|
|
23149
23664
|
}
|
|
23150
|
-
let content =
|
|
23665
|
+
let content = readFileSync19(targetPath, "utf-8");
|
|
23151
23666
|
if (!content.includes(oldStr)) {
|
|
23152
23667
|
return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
|
|
23153
23668
|
}
|
|
23154
23669
|
content = content.replace(oldStr, newStr);
|
|
23155
|
-
|
|
23670
|
+
writeFileSync11(targetPath, content, "utf-8");
|
|
23156
23671
|
return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
|
|
23157
23672
|
} catch (err) {
|
|
23158
23673
|
return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
|
|
@@ -23183,7 +23698,7 @@ var init_dream_engine = __esm({
|
|
|
23183
23698
|
}
|
|
23184
23699
|
}
|
|
23185
23700
|
try {
|
|
23186
|
-
const output =
|
|
23701
|
+
const output = execSync22(cmd, {
|
|
23187
23702
|
cwd: this.repoRoot,
|
|
23188
23703
|
timeout: 3e4,
|
|
23189
23704
|
encoding: "utf-8",
|
|
@@ -23206,7 +23721,7 @@ var init_dream_engine = __esm({
|
|
|
23206
23721
|
constructor(config, repoRoot) {
|
|
23207
23722
|
this.config = config;
|
|
23208
23723
|
this.repoRoot = repoRoot;
|
|
23209
|
-
this.dreamsDir =
|
|
23724
|
+
this.dreamsDir = join36(repoRoot, ".oa", "dreams");
|
|
23210
23725
|
this.state = {
|
|
23211
23726
|
mode: "default",
|
|
23212
23727
|
active: false,
|
|
@@ -23237,7 +23752,7 @@ var init_dream_engine = __esm({
|
|
|
23237
23752
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23238
23753
|
results: []
|
|
23239
23754
|
};
|
|
23240
|
-
|
|
23755
|
+
mkdirSync12(this.dreamsDir, { recursive: true });
|
|
23241
23756
|
this.saveDreamState();
|
|
23242
23757
|
try {
|
|
23243
23758
|
for (let cycle = 1; cycle <= totalCycles; cycle++) {
|
|
@@ -23286,8 +23801,8 @@ ${result.summary}`;
|
|
|
23286
23801
|
if (mode !== "default" || cycle === totalCycles) {
|
|
23287
23802
|
renderDreamContraction(cycle);
|
|
23288
23803
|
const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
|
|
23289
|
-
const summaryPath =
|
|
23290
|
-
|
|
23804
|
+
const summaryPath = join36(this.dreamsDir, `cycle-${cycle}-summary.md`);
|
|
23805
|
+
writeFileSync11(summaryPath, cycleSummary, "utf-8");
|
|
23291
23806
|
}
|
|
23292
23807
|
if (mode === "lucid" && !this.abortController.signal.aborted) {
|
|
23293
23808
|
this.saveVersionCheckpoint(cycle);
|
|
@@ -23525,29 +24040,29 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
23525
24040
|
}
|
|
23526
24041
|
/** Save workspace backup for lucid mode */
|
|
23527
24042
|
saveVersionCheckpoint(cycle) {
|
|
23528
|
-
const checkpointDir =
|
|
24043
|
+
const checkpointDir = join36(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
|
|
23529
24044
|
try {
|
|
23530
|
-
|
|
24045
|
+
mkdirSync12(checkpointDir, { recursive: true });
|
|
23531
24046
|
try {
|
|
23532
|
-
const gitStatus =
|
|
24047
|
+
const gitStatus = execSync22("git status --porcelain", {
|
|
23533
24048
|
cwd: this.repoRoot,
|
|
23534
24049
|
encoding: "utf-8",
|
|
23535
24050
|
timeout: 1e4
|
|
23536
24051
|
});
|
|
23537
|
-
const gitDiff =
|
|
24052
|
+
const gitDiff = execSync22("git diff", {
|
|
23538
24053
|
cwd: this.repoRoot,
|
|
23539
24054
|
encoding: "utf-8",
|
|
23540
24055
|
timeout: 1e4
|
|
23541
24056
|
});
|
|
23542
|
-
const gitHash =
|
|
24057
|
+
const gitHash = execSync22("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
|
|
23543
24058
|
cwd: this.repoRoot,
|
|
23544
24059
|
encoding: "utf-8",
|
|
23545
24060
|
timeout: 5e3
|
|
23546
24061
|
}).trim();
|
|
23547
|
-
|
|
23548
|
-
|
|
23549
|
-
|
|
23550
|
-
|
|
24062
|
+
writeFileSync11(join36(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
|
|
24063
|
+
writeFileSync11(join36(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
|
|
24064
|
+
writeFileSync11(join36(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
|
|
24065
|
+
writeFileSync11(join36(checkpointDir, "checkpoint.json"), JSON.stringify({
|
|
23551
24066
|
cycle,
|
|
23552
24067
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23553
24068
|
gitHash,
|
|
@@ -23555,7 +24070,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
|
|
|
23555
24070
|
}, null, 2), "utf-8");
|
|
23556
24071
|
renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
|
|
23557
24072
|
} catch {
|
|
23558
|
-
|
|
24073
|
+
writeFileSync11(join36(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
|
|
23559
24074
|
renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
|
|
23560
24075
|
}
|
|
23561
24076
|
} catch (err) {
|
|
@@ -23613,14 +24128,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
|
|
|
23613
24128
|
---
|
|
23614
24129
|
*Auto-generated by open-agents dream engine*
|
|
23615
24130
|
`;
|
|
23616
|
-
|
|
24131
|
+
writeFileSync11(join36(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
|
|
23617
24132
|
} catch {
|
|
23618
24133
|
}
|
|
23619
24134
|
}
|
|
23620
24135
|
/** Save dream state for resume/inspection */
|
|
23621
24136
|
saveDreamState() {
|
|
23622
24137
|
try {
|
|
23623
|
-
|
|
24138
|
+
writeFileSync11(join36(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
23624
24139
|
} catch {
|
|
23625
24140
|
}
|
|
23626
24141
|
}
|
|
@@ -23773,8 +24288,8 @@ var init_bless_engine = __esm({
|
|
|
23773
24288
|
});
|
|
23774
24289
|
|
|
23775
24290
|
// packages/cli/dist/tui/dmn-engine.js
|
|
23776
|
-
import { existsSync as
|
|
23777
|
-
import { join as
|
|
24291
|
+
import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync12, mkdirSync as mkdirSync13, readdirSync as readdirSync11, unlinkSync as unlinkSync5 } from "node:fs";
|
|
24292
|
+
import { join as join37, basename as basename13 } from "node:path";
|
|
23778
24293
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
23779
24294
|
const competenceReport = competence.length > 0 ? competence.map((c3) => {
|
|
23780
24295
|
const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
|
|
@@ -24006,9 +24521,9 @@ var init_dmn_engine = __esm({
|
|
|
24006
24521
|
constructor(config, repoRoot) {
|
|
24007
24522
|
this.config = config;
|
|
24008
24523
|
this.repoRoot = repoRoot;
|
|
24009
|
-
this.stateDir =
|
|
24010
|
-
this.historyDir =
|
|
24011
|
-
|
|
24524
|
+
this.stateDir = join37(repoRoot, ".oa", "dmn");
|
|
24525
|
+
this.historyDir = join37(repoRoot, ".oa", "dmn", "cycles");
|
|
24526
|
+
mkdirSync13(this.historyDir, { recursive: true });
|
|
24012
24527
|
this.loadState();
|
|
24013
24528
|
}
|
|
24014
24529
|
get stats() {
|
|
@@ -24596,11 +25111,11 @@ OUTPUT: Call task_complete with JSON:
|
|
|
24596
25111
|
async gatherMemoryTopics() {
|
|
24597
25112
|
const topics = [];
|
|
24598
25113
|
const dirs = [
|
|
24599
|
-
|
|
24600
|
-
|
|
25114
|
+
join37(this.repoRoot, ".oa", "memory"),
|
|
25115
|
+
join37(this.repoRoot, ".open-agents", "memory")
|
|
24601
25116
|
];
|
|
24602
25117
|
for (const dir of dirs) {
|
|
24603
|
-
if (!
|
|
25118
|
+
if (!existsSync27(dir))
|
|
24604
25119
|
continue;
|
|
24605
25120
|
try {
|
|
24606
25121
|
const files = readdirSync11(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -24616,29 +25131,29 @@ OUTPUT: Call task_complete with JSON:
|
|
|
24616
25131
|
}
|
|
24617
25132
|
// ── State persistence ─────────────────────────────────────────────────
|
|
24618
25133
|
loadState() {
|
|
24619
|
-
const path =
|
|
24620
|
-
if (
|
|
25134
|
+
const path = join37(this.stateDir, "state.json");
|
|
25135
|
+
if (existsSync27(path)) {
|
|
24621
25136
|
try {
|
|
24622
|
-
this.state = JSON.parse(
|
|
25137
|
+
this.state = JSON.parse(readFileSync20(path, "utf-8"));
|
|
24623
25138
|
} catch {
|
|
24624
25139
|
}
|
|
24625
25140
|
}
|
|
24626
25141
|
}
|
|
24627
25142
|
saveState() {
|
|
24628
25143
|
try {
|
|
24629
|
-
|
|
25144
|
+
writeFileSync12(join37(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
|
|
24630
25145
|
} catch {
|
|
24631
25146
|
}
|
|
24632
25147
|
}
|
|
24633
25148
|
saveCycleResult(result) {
|
|
24634
25149
|
try {
|
|
24635
25150
|
const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
|
|
24636
|
-
|
|
25151
|
+
writeFileSync12(join37(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
24637
25152
|
const files = readdirSync11(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
|
|
24638
25153
|
if (files.length > 50) {
|
|
24639
25154
|
for (const old of files.slice(0, files.length - 50)) {
|
|
24640
25155
|
try {
|
|
24641
|
-
unlinkSync5(
|
|
25156
|
+
unlinkSync5(join37(this.historyDir, old));
|
|
24642
25157
|
} catch {
|
|
24643
25158
|
}
|
|
24644
25159
|
}
|
|
@@ -24651,8 +25166,8 @@ OUTPUT: Call task_complete with JSON:
|
|
|
24651
25166
|
});
|
|
24652
25167
|
|
|
24653
25168
|
// packages/cli/dist/tui/snr-engine.js
|
|
24654
|
-
import { existsSync as
|
|
24655
|
-
import { join as
|
|
25169
|
+
import { existsSync as existsSync28, readdirSync as readdirSync12, readFileSync as readFileSync21 } from "node:fs";
|
|
25170
|
+
import { join as join38, basename as basename14 } from "node:path";
|
|
24656
25171
|
function computeDPrime(signalScores, noiseScores) {
|
|
24657
25172
|
if (signalScores.length === 0 || noiseScores.length === 0)
|
|
24658
25173
|
return 0;
|
|
@@ -24899,11 +25414,11 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
24899
25414
|
loadMemoryEntries(topics) {
|
|
24900
25415
|
const entries = [];
|
|
24901
25416
|
const dirs = [
|
|
24902
|
-
|
|
24903
|
-
|
|
25417
|
+
join38(this.repoRoot, ".oa", "memory"),
|
|
25418
|
+
join38(this.repoRoot, ".open-agents", "memory")
|
|
24904
25419
|
];
|
|
24905
25420
|
for (const dir of dirs) {
|
|
24906
|
-
if (!
|
|
25421
|
+
if (!existsSync28(dir))
|
|
24907
25422
|
continue;
|
|
24908
25423
|
try {
|
|
24909
25424
|
const files = readdirSync12(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -24912,7 +25427,7 @@ Call task_complete with the JSON array when done.`, onEvent)
|
|
|
24912
25427
|
if (topics.length > 0 && !topics.includes(topic))
|
|
24913
25428
|
continue;
|
|
24914
25429
|
try {
|
|
24915
|
-
const data = JSON.parse(
|
|
25430
|
+
const data = JSON.parse(readFileSync21(join38(dir, f), "utf-8"));
|
|
24916
25431
|
for (const [key, val] of Object.entries(data)) {
|
|
24917
25432
|
const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
24918
25433
|
entries.push({ topic, key, value });
|
|
@@ -26309,11 +26824,11 @@ var init_status_bar = __esm({
|
|
|
26309
26824
|
import * as readline2 from "node:readline";
|
|
26310
26825
|
import { Writable } from "node:stream";
|
|
26311
26826
|
import { cwd } from "node:process";
|
|
26312
|
-
import { resolve as
|
|
26827
|
+
import { resolve as resolve24, join as join39, dirname as dirname12, extname as extname9 } from "node:path";
|
|
26313
26828
|
import { createRequire as createRequire2 } from "node:module";
|
|
26314
|
-
import { fileURLToPath as
|
|
26315
|
-
import { readFileSync as
|
|
26316
|
-
import { existsSync as
|
|
26829
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
26830
|
+
import { readFileSync as readFileSync22, rmSync as rmSync2, readdirSync as readdirSync13 } from "node:fs";
|
|
26831
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
26317
26832
|
function formatTimeAgo(date) {
|
|
26318
26833
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
26319
26834
|
if (seconds < 60)
|
|
@@ -26330,14 +26845,14 @@ function formatTimeAgo(date) {
|
|
|
26330
26845
|
function getVersion() {
|
|
26331
26846
|
try {
|
|
26332
26847
|
const require2 = createRequire2(import.meta.url);
|
|
26333
|
-
const thisDir =
|
|
26848
|
+
const thisDir = dirname12(fileURLToPath9(import.meta.url));
|
|
26334
26849
|
const candidates = [
|
|
26335
|
-
|
|
26336
|
-
|
|
26337
|
-
|
|
26850
|
+
join39(thisDir, "..", "package.json"),
|
|
26851
|
+
join39(thisDir, "..", "..", "package.json"),
|
|
26852
|
+
join39(thisDir, "..", "..", "..", "package.json")
|
|
26338
26853
|
];
|
|
26339
26854
|
for (const pkgPath of candidates) {
|
|
26340
|
-
if (
|
|
26855
|
+
if (existsSync29(pkgPath)) {
|
|
26341
26856
|
const pkg = require2(pkgPath);
|
|
26342
26857
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
26343
26858
|
return pkg.version ?? "0.0.0";
|
|
@@ -26438,6 +26953,8 @@ function buildTools(repoRoot, config, contextWindowSize) {
|
|
|
26438
26953
|
new OcrImageAdvancedTool(repoRoot),
|
|
26439
26954
|
// Browser automation (headless Chrome via Hydra scrape service)
|
|
26440
26955
|
new BrowserActionTool(),
|
|
26956
|
+
// Autoresearch (autonomous ML experiment loop)
|
|
26957
|
+
new AutoresearchTool(repoRoot),
|
|
26441
26958
|
// Temporal agency (scheduling, reminders, attention steering)
|
|
26442
26959
|
new SchedulerTool(repoRoot),
|
|
26443
26960
|
new ReminderTool(repoRoot),
|
|
@@ -26529,15 +27046,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
26529
27046
|
function gatherMemorySnippets(root) {
|
|
26530
27047
|
const snippets = [];
|
|
26531
27048
|
const dirs = [
|
|
26532
|
-
|
|
26533
|
-
|
|
27049
|
+
join39(root, ".oa", "memory"),
|
|
27050
|
+
join39(root, ".open-agents", "memory")
|
|
26534
27051
|
];
|
|
26535
27052
|
for (const dir of dirs) {
|
|
26536
|
-
if (!
|
|
27053
|
+
if (!existsSync29(dir))
|
|
26537
27054
|
continue;
|
|
26538
27055
|
try {
|
|
26539
27056
|
for (const f of readdirSync13(dir).filter((f2) => f2.endsWith(".json"))) {
|
|
26540
|
-
const data = JSON.parse(
|
|
27057
|
+
const data = JSON.parse(readFileSync22(join39(dir, f), "utf-8"));
|
|
26541
27058
|
for (const val of Object.values(data)) {
|
|
26542
27059
|
const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
|
|
26543
27060
|
if (v.length > 10)
|
|
@@ -26937,7 +27454,7 @@ ${entry.fullContent}`
|
|
|
26937
27454
|
} };
|
|
26938
27455
|
}
|
|
26939
27456
|
async function startInteractive(config, repoPath) {
|
|
26940
|
-
const repoRoot =
|
|
27457
|
+
const repoRoot = resolve24(repoPath ?? cwd());
|
|
26941
27458
|
const resumeFlag = process.env.__OA_RESUMED ?? "";
|
|
26942
27459
|
const isResumed = resumeFlag !== "";
|
|
26943
27460
|
const hasTaskToResume = resumeFlag === "1";
|
|
@@ -27091,14 +27608,14 @@ async function startInteractive(config, repoPath) {
|
|
|
27091
27608
|
renderInfo(msg);
|
|
27092
27609
|
statusBar.endContentWrite();
|
|
27093
27610
|
}
|
|
27094
|
-
}, () => new Promise((
|
|
27611
|
+
}, () => new Promise((resolve27) => {
|
|
27095
27612
|
depSudoPromptPending = true;
|
|
27096
27613
|
depSudoResolver = (pw) => {
|
|
27097
27614
|
depSudoPromptPending = false;
|
|
27098
27615
|
depSudoResolver = null;
|
|
27099
27616
|
if (pw)
|
|
27100
27617
|
sessionSudoPassword = pw;
|
|
27101
|
-
|
|
27618
|
+
resolve27(pw);
|
|
27102
27619
|
};
|
|
27103
27620
|
if (statusBar?.isActive) {
|
|
27104
27621
|
statusBar.beginContentWrite();
|
|
@@ -27723,8 +28240,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
27723
28240
|
return true;
|
|
27724
28241
|
},
|
|
27725
28242
|
destroyProject() {
|
|
27726
|
-
const oaPath =
|
|
27727
|
-
if (
|
|
28243
|
+
const oaPath = join39(repoRoot, OA_DIR);
|
|
28244
|
+
if (existsSync29(oaPath)) {
|
|
27728
28245
|
try {
|
|
27729
28246
|
rmSync2(oaPath, { recursive: true, force: true });
|
|
27730
28247
|
writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
|
|
@@ -27998,13 +28515,13 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
27998
28515
|
}
|
|
27999
28516
|
}
|
|
28000
28517
|
const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
|
|
28001
|
-
const isImage = isImagePath(cleanPath) &&
|
|
28002
|
-
const isMedia = !isImage && isTranscribablePath(cleanPath) &&
|
|
28518
|
+
const isImage = isImagePath(cleanPath) && existsSync29(resolve24(repoRoot, cleanPath));
|
|
28519
|
+
const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync29(resolve24(repoRoot, cleanPath));
|
|
28003
28520
|
if (activeTask) {
|
|
28004
28521
|
if (isImage) {
|
|
28005
28522
|
try {
|
|
28006
|
-
const imgPath =
|
|
28007
|
-
const imgBuffer =
|
|
28523
|
+
const imgPath = resolve24(repoRoot, cleanPath);
|
|
28524
|
+
const imgBuffer = readFileSync22(imgPath);
|
|
28008
28525
|
const base64 = imgBuffer.toString("base64");
|
|
28009
28526
|
const ext = extname9(cleanPath).toLowerCase();
|
|
28010
28527
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
@@ -28017,7 +28534,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
28017
28534
|
} else if (isMedia) {
|
|
28018
28535
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
28019
28536
|
const engine = getListenEngine();
|
|
28020
|
-
const result = await engine.transcribeFile(
|
|
28537
|
+
const result = await engine.transcribeFile(resolve24(repoRoot, cleanPath), repoRoot);
|
|
28021
28538
|
if (result) {
|
|
28022
28539
|
const transcript = `[Transcription of ${cleanPath}]
|
|
28023
28540
|
${result.text}`;
|
|
@@ -28050,7 +28567,7 @@ ${result.text}`;
|
|
|
28050
28567
|
if (isMedia && fullInput === input) {
|
|
28051
28568
|
writeContent(() => renderInfo(`Transcribing: ${cleanPath}...`));
|
|
28052
28569
|
const engine = getListenEngine();
|
|
28053
|
-
const result = await engine.transcribeFile(
|
|
28570
|
+
const result = await engine.transcribeFile(resolve24(repoRoot, cleanPath), repoRoot);
|
|
28054
28571
|
if (result) {
|
|
28055
28572
|
fullInput = `The user has provided an audio/video file: ${cleanPath}.
|
|
28056
28573
|
|
|
@@ -28268,7 +28785,7 @@ ${c2.dim("(Use /quit to exit)")}
|
|
|
28268
28785
|
});
|
|
28269
28786
|
}
|
|
28270
28787
|
async function runWithTUI(task, config, repoPath) {
|
|
28271
|
-
const repoRoot =
|
|
28788
|
+
const repoRoot = resolve24(repoPath ?? cwd());
|
|
28272
28789
|
const needsSetup = isFirstRun() || !await isModelAvailable(config);
|
|
28273
28790
|
if (needsSetup && config.backendType === "ollama") {
|
|
28274
28791
|
const setupModel = await runSetupWizard(config);
|
|
@@ -28378,7 +28895,7 @@ import { glob } from "glob";
|
|
|
28378
28895
|
import ignore from "ignore";
|
|
28379
28896
|
import { readFile as readFile14, stat as stat4 } from "node:fs/promises";
|
|
28380
28897
|
import { createHash } from "node:crypto";
|
|
28381
|
-
import { join as
|
|
28898
|
+
import { join as join40, relative as relative3, extname as extname10, basename as basename15 } from "node:path";
|
|
28382
28899
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
28383
28900
|
var init_codebase_indexer = __esm({
|
|
28384
28901
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -28422,7 +28939,7 @@ var init_codebase_indexer = __esm({
|
|
|
28422
28939
|
const ig = ignore.default();
|
|
28423
28940
|
if (this.config.respectGitignore) {
|
|
28424
28941
|
try {
|
|
28425
|
-
const gitignoreContent = await readFile14(
|
|
28942
|
+
const gitignoreContent = await readFile14(join40(this.config.rootDir, ".gitignore"), "utf-8");
|
|
28426
28943
|
ig.add(gitignoreContent);
|
|
28427
28944
|
} catch {
|
|
28428
28945
|
}
|
|
@@ -28437,7 +28954,7 @@ var init_codebase_indexer = __esm({
|
|
|
28437
28954
|
for (const relativePath of files) {
|
|
28438
28955
|
if (ig.ignores(relativePath))
|
|
28439
28956
|
continue;
|
|
28440
|
-
const fullPath =
|
|
28957
|
+
const fullPath = join40(this.config.rootDir, relativePath);
|
|
28441
28958
|
try {
|
|
28442
28959
|
const fileStat = await stat4(fullPath);
|
|
28443
28960
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -28483,7 +29000,7 @@ var init_codebase_indexer = __esm({
|
|
|
28483
29000
|
if (!child) {
|
|
28484
29001
|
child = {
|
|
28485
29002
|
name: part,
|
|
28486
|
-
path:
|
|
29003
|
+
path: join40(current.path, part),
|
|
28487
29004
|
type: "directory",
|
|
28488
29005
|
children: []
|
|
28489
29006
|
};
|
|
@@ -28565,14 +29082,14 @@ var index_repo_exports = {};
|
|
|
28565
29082
|
__export(index_repo_exports, {
|
|
28566
29083
|
indexRepoCommand: () => indexRepoCommand
|
|
28567
29084
|
});
|
|
28568
|
-
import { resolve as
|
|
28569
|
-
import { existsSync as
|
|
29085
|
+
import { resolve as resolve25 } from "node:path";
|
|
29086
|
+
import { existsSync as existsSync30, statSync as statSync10 } from "node:fs";
|
|
28570
29087
|
import { cwd as cwd2 } from "node:process";
|
|
28571
29088
|
async function indexRepoCommand(opts, _config) {
|
|
28572
|
-
const repoRoot =
|
|
29089
|
+
const repoRoot = resolve25(opts.repoPath ?? cwd2());
|
|
28573
29090
|
printHeader("Index Repository");
|
|
28574
29091
|
printInfo(`Indexing: ${repoRoot}`);
|
|
28575
|
-
if (!
|
|
29092
|
+
if (!existsSync30(repoRoot)) {
|
|
28576
29093
|
printError(`Path does not exist: ${repoRoot}`);
|
|
28577
29094
|
process.exit(1);
|
|
28578
29095
|
}
|
|
@@ -28824,7 +29341,7 @@ var config_exports = {};
|
|
|
28824
29341
|
__export(config_exports, {
|
|
28825
29342
|
configCommand: () => configCommand
|
|
28826
29343
|
});
|
|
28827
|
-
import { join as
|
|
29344
|
+
import { join as join41, resolve as resolve26 } from "node:path";
|
|
28828
29345
|
import { homedir as homedir13 } from "node:os";
|
|
28829
29346
|
import { cwd as cwd3 } from "node:process";
|
|
28830
29347
|
function redactIfSensitive(key, value) {
|
|
@@ -28851,7 +29368,7 @@ async function configCommand(opts, config) {
|
|
|
28851
29368
|
return handleShow(opts, config);
|
|
28852
29369
|
}
|
|
28853
29370
|
function handleShow(opts, config) {
|
|
28854
|
-
const repoRoot =
|
|
29371
|
+
const repoRoot = resolve26(opts.repoPath ?? cwd3());
|
|
28855
29372
|
printHeader("Configuration");
|
|
28856
29373
|
printSection("Active Settings (merged)");
|
|
28857
29374
|
printKeyValue("backendUrl", config.backendUrl, 2);
|
|
@@ -28883,7 +29400,7 @@ function handleShow(opts, config) {
|
|
|
28883
29400
|
}
|
|
28884
29401
|
}
|
|
28885
29402
|
printSection("Config File");
|
|
28886
|
-
printInfo(`~/.open-agents/config.json (${
|
|
29403
|
+
printInfo(`~/.open-agents/config.json (${join41(homedir13(), ".open-agents", "config.json")})`);
|
|
28887
29404
|
printSection("Priority Chain");
|
|
28888
29405
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
28889
29406
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -28916,13 +29433,13 @@ function handleSet(opts, _config) {
|
|
|
28916
29433
|
process.exit(1);
|
|
28917
29434
|
}
|
|
28918
29435
|
if (opts.local) {
|
|
28919
|
-
const repoRoot =
|
|
29436
|
+
const repoRoot = resolve26(opts.repoPath ?? cwd3());
|
|
28920
29437
|
try {
|
|
28921
29438
|
initOaDirectory(repoRoot);
|
|
28922
29439
|
const coerced = coerceForSettings(key, value);
|
|
28923
29440
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
28924
29441
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
28925
|
-
printInfo(`Saved to ${
|
|
29442
|
+
printInfo(`Saved to ${join41(repoRoot, ".oa", "settings.json")}`);
|
|
28926
29443
|
printInfo("This override applies only when running in this workspace.");
|
|
28927
29444
|
} catch (err) {
|
|
28928
29445
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -28983,7 +29500,7 @@ var serve_exports = {};
|
|
|
28983
29500
|
__export(serve_exports, {
|
|
28984
29501
|
serveCommand: () => serveCommand
|
|
28985
29502
|
});
|
|
28986
|
-
import { spawn as
|
|
29503
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
28987
29504
|
async function serveCommand(opts, config) {
|
|
28988
29505
|
const backendType = config.backendType;
|
|
28989
29506
|
if (backendType === "ollama") {
|
|
@@ -29075,8 +29592,8 @@ async function serveVllm(opts, config) {
|
|
|
29075
29592
|
await runVllmServer(args, opts.verbose ?? false);
|
|
29076
29593
|
}
|
|
29077
29594
|
async function runVllmServer(args, verbose) {
|
|
29078
|
-
return new Promise((
|
|
29079
|
-
const child =
|
|
29595
|
+
return new Promise((resolve27, reject) => {
|
|
29596
|
+
const child = spawn11("python", args, {
|
|
29080
29597
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
29081
29598
|
env: { ...process.env }
|
|
29082
29599
|
});
|
|
@@ -29110,10 +29627,10 @@ async function runVllmServer(args, verbose) {
|
|
|
29110
29627
|
child.once("exit", (code, signal) => {
|
|
29111
29628
|
if (signal) {
|
|
29112
29629
|
printInfo(`vLLM server stopped by signal ${signal}`);
|
|
29113
|
-
|
|
29630
|
+
resolve27();
|
|
29114
29631
|
} else if (code === 0) {
|
|
29115
29632
|
printSuccess("vLLM server exited cleanly");
|
|
29116
|
-
|
|
29633
|
+
resolve27();
|
|
29117
29634
|
} else {
|
|
29118
29635
|
printError(`vLLM server exited with code ${code}`);
|
|
29119
29636
|
reject(new Error(`vLLM exited with code ${code}`));
|
|
@@ -29141,8 +29658,8 @@ __export(eval_exports, {
|
|
|
29141
29658
|
evalCommand: () => evalCommand
|
|
29142
29659
|
});
|
|
29143
29660
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
29144
|
-
import { mkdirSync as
|
|
29145
|
-
import { join as
|
|
29661
|
+
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync13 } from "node:fs";
|
|
29662
|
+
import { join as join42 } from "node:path";
|
|
29146
29663
|
async function evalCommand(opts, config) {
|
|
29147
29664
|
const suiteName = opts.suite ?? "basic";
|
|
29148
29665
|
const suite = SUITES[suiteName];
|
|
@@ -29263,9 +29780,9 @@ async function evalCommand(opts, config) {
|
|
|
29263
29780
|
process.exit(failed > 0 ? 1 : 0);
|
|
29264
29781
|
}
|
|
29265
29782
|
function createTempEvalRepo() {
|
|
29266
|
-
const dir =
|
|
29267
|
-
|
|
29268
|
-
|
|
29783
|
+
const dir = join42(tmpdir7(), `open-agents-eval-${Date.now()}`);
|
|
29784
|
+
mkdirSync14(dir, { recursive: true });
|
|
29785
|
+
writeFileSync13(join42(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
29269
29786
|
return dir;
|
|
29270
29787
|
}
|
|
29271
29788
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -29324,8 +29841,8 @@ init_output();
|
|
|
29324
29841
|
init_updater();
|
|
29325
29842
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
29326
29843
|
import { createRequire as createRequire3 } from "node:module";
|
|
29327
|
-
import { fileURLToPath as
|
|
29328
|
-
import { dirname as
|
|
29844
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
29845
|
+
import { dirname as dirname13, join as join43 } from "node:path";
|
|
29329
29846
|
|
|
29330
29847
|
// packages/cli/dist/cli.js
|
|
29331
29848
|
import { createInterface } from "node:readline";
|
|
@@ -29432,7 +29949,7 @@ init_output();
|
|
|
29432
29949
|
function getVersion2() {
|
|
29433
29950
|
try {
|
|
29434
29951
|
const require2 = createRequire3(import.meta.url);
|
|
29435
|
-
const pkgPath =
|
|
29952
|
+
const pkgPath = join43(dirname13(fileURLToPath10(import.meta.url)), "..", "package.json");
|
|
29436
29953
|
const pkg = require2(pkgPath);
|
|
29437
29954
|
return pkg.version;
|
|
29438
29955
|
} catch {
|