open-agents-ai 0.172.0 → 0.174.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 +470 -251
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1374,7 +1374,7 @@ ${stdinInput ?? ""}`);
|
|
|
1374
1374
|
}
|
|
1375
1375
|
runCommand(command, timeout, stdinInput) {
|
|
1376
1376
|
const start = performance.now();
|
|
1377
|
-
return new Promise((
|
|
1377
|
+
return new Promise((resolve35) => {
|
|
1378
1378
|
const child = spawn("bash", ["-c", command], {
|
|
1379
1379
|
cwd: this.workingDir,
|
|
1380
1380
|
env: {
|
|
@@ -1405,7 +1405,7 @@ ${stdinInput ?? ""}`);
|
|
|
1405
1405
|
clearTimeout(timer);
|
|
1406
1406
|
if (exitFlushTimer)
|
|
1407
1407
|
clearTimeout(exitFlushTimer);
|
|
1408
|
-
|
|
1408
|
+
resolve35(result);
|
|
1409
1409
|
};
|
|
1410
1410
|
const timer = setTimeout(() => {
|
|
1411
1411
|
killed = true;
|
|
@@ -3161,7 +3161,7 @@ ${JSON.stringify(extracted, null, 2)}`);
|
|
|
3161
3161
|
return null;
|
|
3162
3162
|
}
|
|
3163
3163
|
runProcess(cmd, args, timeoutMs) {
|
|
3164
|
-
return new Promise((
|
|
3164
|
+
return new Promise((resolve35, reject) => {
|
|
3165
3165
|
const proc = execFile3(cmd, args, {
|
|
3166
3166
|
timeout: timeoutMs,
|
|
3167
3167
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -3171,7 +3171,7 @@ ${JSON.stringify(extracted, null, 2)}`);
|
|
|
3171
3171
|
reject(new Error(`Process timeout after ${timeoutMs}ms`));
|
|
3172
3172
|
return;
|
|
3173
3173
|
}
|
|
3174
|
-
|
|
3174
|
+
resolve35({
|
|
3175
3175
|
stdout: String(stdout),
|
|
3176
3176
|
stderr: String(stderr),
|
|
3177
3177
|
exitCode: error ? error.code ?? 1 : 0
|
|
@@ -10602,7 +10602,7 @@ var init_custom_tool = __esm({
|
|
|
10602
10602
|
}
|
|
10603
10603
|
/** Execute a single shell command and return output */
|
|
10604
10604
|
runCommand(command) {
|
|
10605
|
-
return new Promise((
|
|
10605
|
+
return new Promise((resolve35) => {
|
|
10606
10606
|
const child = spawn4("bash", ["-c", command], {
|
|
10607
10607
|
cwd: this.workingDir,
|
|
10608
10608
|
env: { ...process.env, CI: "true", NO_COLOR: "1" },
|
|
@@ -10627,11 +10627,11 @@ var init_custom_tool = __esm({
|
|
|
10627
10627
|
child.kill("SIGTERM");
|
|
10628
10628
|
} catch {
|
|
10629
10629
|
}
|
|
10630
|
-
|
|
10630
|
+
resolve35({ success: false, output: stdout, error: "Command timed out after 60s" });
|
|
10631
10631
|
}, 6e4);
|
|
10632
10632
|
child.on("close", (code) => {
|
|
10633
10633
|
clearTimeout(timer);
|
|
10634
|
-
|
|
10634
|
+
resolve35({
|
|
10635
10635
|
success: code === 0,
|
|
10636
10636
|
output: stdout + (stderr && code === 0 ? `
|
|
10637
10637
|
STDERR:
|
|
@@ -10641,7 +10641,7 @@ ${stderr}` : ""),
|
|
|
10641
10641
|
});
|
|
10642
10642
|
child.on("error", (err) => {
|
|
10643
10643
|
clearTimeout(timer);
|
|
10644
|
-
|
|
10644
|
+
resolve35({ success: false, output: stdout, error: err.message });
|
|
10645
10645
|
});
|
|
10646
10646
|
});
|
|
10647
10647
|
}
|
|
@@ -11659,8 +11659,8 @@ async function loadTranscribeCli() {
|
|
|
11659
11659
|
const nvmBase = join19(homedir6(), ".nvm", "versions", "node");
|
|
11660
11660
|
if (existsSync16(nvmBase)) {
|
|
11661
11661
|
try {
|
|
11662
|
-
const { readdirSync:
|
|
11663
|
-
for (const ver of
|
|
11662
|
+
const { readdirSync: readdirSync21 } = await import("node:fs");
|
|
11663
|
+
for (const ver of readdirSync21(nvmBase)) {
|
|
11664
11664
|
const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
11665
11665
|
if (existsSync16(join19(tcPath, "dist", "index.js"))) {
|
|
11666
11666
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -12205,7 +12205,7 @@ import { writeFile as writeFile8, mkdtemp, rm, readdir as readdir3, stat } from
|
|
|
12205
12205
|
import { join as join20 } from "node:path";
|
|
12206
12206
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
12207
12207
|
function runProcess(cmd, args, options) {
|
|
12208
|
-
return new Promise((
|
|
12208
|
+
return new Promise((resolve35) => {
|
|
12209
12209
|
const proc = spawn6(cmd, args, {
|
|
12210
12210
|
cwd: options.cwd,
|
|
12211
12211
|
timeout: options.timeout,
|
|
@@ -12235,7 +12235,7 @@ function runProcess(cmd, args, options) {
|
|
|
12235
12235
|
}
|
|
12236
12236
|
});
|
|
12237
12237
|
proc.on("error", (err) => {
|
|
12238
|
-
|
|
12238
|
+
resolve35({
|
|
12239
12239
|
stdout,
|
|
12240
12240
|
stderr: stderr || err.message,
|
|
12241
12241
|
exitCode: 1,
|
|
@@ -12247,7 +12247,7 @@ function runProcess(cmd, args, options) {
|
|
|
12247
12247
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
12248
12248
|
timedOut = true;
|
|
12249
12249
|
}
|
|
12250
|
-
|
|
12250
|
+
resolve35({
|
|
12251
12251
|
stdout,
|
|
12252
12252
|
stderr,
|
|
12253
12253
|
exitCode: code ?? (timedOut ? 124 : 1),
|
|
@@ -12730,7 +12730,7 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
12730
12730
|
})();
|
|
12731
12731
|
const ipfsResult = await Promise.race([
|
|
12732
12732
|
ipfsPromise,
|
|
12733
|
-
new Promise((
|
|
12733
|
+
new Promise((resolve35) => setTimeout(() => resolve35(null), 2e3))
|
|
12734
12734
|
]);
|
|
12735
12735
|
if (ipfsResult && ipfsResult.success) {
|
|
12736
12736
|
const cidData = JSON.parse(ipfsResult.output);
|
|
@@ -13177,7 +13177,7 @@ print("__OA_REPL_READY__")
|
|
|
13177
13177
|
return;
|
|
13178
13178
|
const sockId = randomBytes5(8).toString("hex");
|
|
13179
13179
|
this.ipcPath = join22(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
|
|
13180
|
-
return new Promise((
|
|
13180
|
+
return new Promise((resolve35, reject) => {
|
|
13181
13181
|
this.ipcServer = createServer((conn) => {
|
|
13182
13182
|
let buffer = new Uint8Array(0);
|
|
13183
13183
|
conn.on("data", (chunk) => {
|
|
@@ -13193,7 +13193,7 @@ print("__OA_REPL_READY__")
|
|
|
13193
13193
|
});
|
|
13194
13194
|
});
|
|
13195
13195
|
this.ipcServer.on("error", reject);
|
|
13196
|
-
this.ipcServer.listen(this.ipcPath, () =>
|
|
13196
|
+
this.ipcServer.listen(this.ipcPath, () => resolve35());
|
|
13197
13197
|
});
|
|
13198
13198
|
}
|
|
13199
13199
|
async processIpcBuffer(conn, input) {
|
|
@@ -13256,9 +13256,9 @@ print("__OA_REPL_READY__")
|
|
|
13256
13256
|
}
|
|
13257
13257
|
// ── Code execution ─────────────────────────────────────────────────────
|
|
13258
13258
|
executeCode(code, isInit = false) {
|
|
13259
|
-
return new Promise((
|
|
13259
|
+
return new Promise((resolve35) => {
|
|
13260
13260
|
if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
|
|
13261
|
-
|
|
13261
|
+
resolve35({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
|
|
13262
13262
|
return;
|
|
13263
13263
|
}
|
|
13264
13264
|
const sentinel = `__OA_SENTINEL_${randomBytes5(6).toString("hex")}__`;
|
|
@@ -13268,7 +13268,7 @@ print("__OA_REPL_READY__")
|
|
|
13268
13268
|
const timeout = setTimeout(() => {
|
|
13269
13269
|
if (!resolved) {
|
|
13270
13270
|
resolved = true;
|
|
13271
|
-
|
|
13271
|
+
resolve35({
|
|
13272
13272
|
success: false,
|
|
13273
13273
|
output: stdout || "Execution timed out",
|
|
13274
13274
|
error: `Timeout after ${this.execTimeout / 1e3}s`,
|
|
@@ -13285,13 +13285,13 @@ print("__OA_REPL_READY__")
|
|
|
13285
13285
|
if (isInit) {
|
|
13286
13286
|
const ready = cleanOutput.includes("__OA_REPL_READY__");
|
|
13287
13287
|
const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
|
|
13288
|
-
|
|
13288
|
+
resolve35({
|
|
13289
13289
|
success: ready,
|
|
13290
13290
|
output: displayOutput || "REPL initialized",
|
|
13291
13291
|
durationMs: 0
|
|
13292
13292
|
});
|
|
13293
13293
|
} else {
|
|
13294
|
-
|
|
13294
|
+
resolve35({
|
|
13295
13295
|
success: true,
|
|
13296
13296
|
output: cleanOutput || "(no output)",
|
|
13297
13297
|
durationMs: 0
|
|
@@ -13300,7 +13300,7 @@ print("__OA_REPL_READY__")
|
|
|
13300
13300
|
}
|
|
13301
13301
|
if (stdout.length > 2e5) {
|
|
13302
13302
|
cleanup();
|
|
13303
|
-
|
|
13303
|
+
resolve35({
|
|
13304
13304
|
success: true,
|
|
13305
13305
|
output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
|
|
13306
13306
|
durationMs: 0
|
|
@@ -13402,9 +13402,9 @@ print("${sentinel}")
|
|
|
13402
13402
|
if (!this.proc || this.proc.killed) {
|
|
13403
13403
|
return { success: false, path: "" };
|
|
13404
13404
|
}
|
|
13405
|
-
const { mkdirSync:
|
|
13405
|
+
const { mkdirSync: mkdirSync26, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
13406
13406
|
const sessionDir = join22(this.cwd, ".oa", "rlm");
|
|
13407
|
-
|
|
13407
|
+
mkdirSync26(sessionDir, { recursive: true });
|
|
13408
13408
|
const sessionPath = join22(sessionDir, "session.json");
|
|
13409
13409
|
try {
|
|
13410
13410
|
const inspectCode = `
|
|
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13428
13428
|
trajectoryCount: this.trajectory.length,
|
|
13429
13429
|
subCallCount: this.subCallCount
|
|
13430
13430
|
};
|
|
13431
|
-
|
|
13431
|
+
writeFileSync25(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
|
|
13432
13432
|
return { success: true, path: sessionPath };
|
|
13433
13433
|
}
|
|
13434
13434
|
} catch {
|
|
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
|
|
|
13440
13440
|
* what was previously computed. */
|
|
13441
13441
|
async loadSessionInfo() {
|
|
13442
13442
|
try {
|
|
13443
|
-
const { readFileSync:
|
|
13443
|
+
const { readFileSync: readFileSync40, existsSync: existsSync52 } = await import("node:fs");
|
|
13444
13444
|
const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
|
|
13445
|
-
if (!
|
|
13445
|
+
if (!existsSync52(sessionPath))
|
|
13446
13446
|
return null;
|
|
13447
|
-
return JSON.parse(
|
|
13447
|
+
return JSON.parse(readFileSync40(sessionPath, "utf8"));
|
|
13448
13448
|
} catch {
|
|
13449
13449
|
return null;
|
|
13450
13450
|
}
|
|
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
|
|
|
13621
13621
|
const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
|
|
13622
13622
|
let lessons = [];
|
|
13623
13623
|
try {
|
|
13624
|
-
const { readdirSync:
|
|
13625
|
-
const files =
|
|
13624
|
+
const { readdirSync: readdirSync21, readFileSync: readFileSync40 } = await import("node:fs");
|
|
13625
|
+
const files = readdirSync21(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
|
|
13626
13626
|
for (const file of files) {
|
|
13627
|
-
const lines =
|
|
13627
|
+
const lines = readFileSync40(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
|
|
13628
13628
|
for (const line of lines) {
|
|
13629
13629
|
try {
|
|
13630
13630
|
const entry = JSON.parse(line);
|
|
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14008
14008
|
* Optionally filter by task type for phase-aware context (FSM paper insight).
|
|
14009
14009
|
*/
|
|
14010
14010
|
getTopMemoriesSync(k = 5, taskType) {
|
|
14011
|
-
const { readFileSync:
|
|
14011
|
+
const { readFileSync: readFileSync40, existsSync: existsSync52 } = __require("node:fs");
|
|
14012
14012
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14013
14013
|
const storeFile = join23(metaDir, "store.json");
|
|
14014
|
-
if (!
|
|
14014
|
+
if (!existsSync52(storeFile))
|
|
14015
14015
|
return "";
|
|
14016
14016
|
let store = [];
|
|
14017
14017
|
try {
|
|
14018
|
-
store = JSON.parse(
|
|
14018
|
+
store = JSON.parse(readFileSync40(storeFile, "utf8"));
|
|
14019
14019
|
} catch {
|
|
14020
14020
|
return "";
|
|
14021
14021
|
}
|
|
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14037
14037
|
/** Update memory scores based on task outcome. Called after task completion.
|
|
14038
14038
|
* Memories used in successful tasks get boosted. Memories present during failures get decayed. */
|
|
14039
14039
|
updateFromOutcomeSync(surfacedMemoryText, succeeded) {
|
|
14040
|
-
const { readFileSync:
|
|
14040
|
+
const { readFileSync: readFileSync40, writeFileSync: writeFileSync25, existsSync: existsSync52, mkdirSync: mkdirSync26 } = __require("node:fs");
|
|
14041
14041
|
const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
|
|
14042
14042
|
const storeFile = join23(metaDir, "store.json");
|
|
14043
|
-
if (!
|
|
14043
|
+
if (!existsSync52(storeFile))
|
|
14044
14044
|
return;
|
|
14045
14045
|
let store = [];
|
|
14046
14046
|
try {
|
|
14047
|
-
store = JSON.parse(
|
|
14047
|
+
store = JSON.parse(readFileSync40(storeFile, "utf8"));
|
|
14048
14048
|
} catch {
|
|
14049
14049
|
return;
|
|
14050
14050
|
}
|
|
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
|
|
|
14068
14068
|
updated = true;
|
|
14069
14069
|
}
|
|
14070
14070
|
if (updated) {
|
|
14071
|
-
|
|
14072
|
-
|
|
14071
|
+
mkdirSync26(metaDir, { recursive: true });
|
|
14072
|
+
writeFileSync25(storeFile, JSON.stringify(store, null, 2));
|
|
14073
14073
|
}
|
|
14074
14074
|
}
|
|
14075
14075
|
// ── Storage ──────────────────────────────────────────────────────────
|
|
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14491
14491
|
// Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
|
|
14492
14492
|
/** Retrieve top-K strategies for context injection. Returns "" if none. */
|
|
14493
14493
|
getRelevantStrategiesSync(k = 3, taskType) {
|
|
14494
|
-
const { readFileSync:
|
|
14494
|
+
const { readFileSync: readFileSync40, existsSync: existsSync52 } = __require("node:fs");
|
|
14495
14495
|
const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
|
|
14496
|
-
if (!
|
|
14496
|
+
if (!existsSync52(archiveFile))
|
|
14497
14497
|
return "";
|
|
14498
14498
|
let variants = [];
|
|
14499
14499
|
try {
|
|
14500
|
-
variants = JSON.parse(
|
|
14500
|
+
variants = JSON.parse(readFileSync40(archiveFile, "utf8"));
|
|
14501
14501
|
} catch {
|
|
14502
14502
|
return "";
|
|
14503
14503
|
}
|
|
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14515
14515
|
}
|
|
14516
14516
|
/** Archive a strategy variant synchronously (for task completion path) */
|
|
14517
14517
|
archiveVariantSync(strategy, outcome, tags = []) {
|
|
14518
|
-
const { readFileSync:
|
|
14518
|
+
const { readFileSync: readFileSync40, writeFileSync: writeFileSync25, existsSync: existsSync52, mkdirSync: mkdirSync26 } = __require("node:fs");
|
|
14519
14519
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
14520
14520
|
const archiveFile = join25(dir, "variants.json");
|
|
14521
14521
|
let variants = [];
|
|
14522
14522
|
try {
|
|
14523
|
-
if (
|
|
14524
|
-
variants = JSON.parse(
|
|
14523
|
+
if (existsSync52(archiveFile))
|
|
14524
|
+
variants = JSON.parse(readFileSync40(archiveFile, "utf8"));
|
|
14525
14525
|
} catch {
|
|
14526
14526
|
}
|
|
14527
14527
|
variants.push({
|
|
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
|
|
|
14536
14536
|
});
|
|
14537
14537
|
if (variants.length > 50)
|
|
14538
14538
|
variants = variants.slice(-50);
|
|
14539
|
-
|
|
14540
|
-
|
|
14539
|
+
mkdirSync26(dir, { recursive: true });
|
|
14540
|
+
writeFileSync25(archiveFile, JSON.stringify(variants, null, 2));
|
|
14541
14541
|
}
|
|
14542
14542
|
async saveArchive(variants) {
|
|
14543
14543
|
const dir = join25(this.cwd, ".oa", "arche");
|
|
@@ -21684,7 +21684,7 @@ import { spawn as spawn14 } from "node:child_process";
|
|
|
21684
21684
|
async function runShell(options) {
|
|
21685
21685
|
const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
21686
21686
|
const mergedEnv = env ? { ...process.env, ...env } : process.env;
|
|
21687
|
-
return new Promise((
|
|
21687
|
+
return new Promise((resolve35) => {
|
|
21688
21688
|
const start = Date.now();
|
|
21689
21689
|
let timedOut = false;
|
|
21690
21690
|
const child = spawn14(command, args, {
|
|
@@ -21708,7 +21708,7 @@ async function runShell(options) {
|
|
|
21708
21708
|
clearTimeout(timer);
|
|
21709
21709
|
const durationMs = Date.now() - start;
|
|
21710
21710
|
const exitCode = timedOut ? -1 : code ?? -1;
|
|
21711
|
-
|
|
21711
|
+
resolve35({
|
|
21712
21712
|
stdout,
|
|
21713
21713
|
stderr,
|
|
21714
21714
|
exitCode,
|
|
@@ -21720,7 +21720,7 @@ async function runShell(options) {
|
|
|
21720
21720
|
child.on("error", (err) => {
|
|
21721
21721
|
clearTimeout(timer);
|
|
21722
21722
|
const durationMs = Date.now() - start;
|
|
21723
|
-
|
|
21723
|
+
resolve35({
|
|
21724
21724
|
stdout,
|
|
21725
21725
|
stderr: stderr + err.message,
|
|
21726
21726
|
exitCode: -1,
|
|
@@ -21835,7 +21835,7 @@ async function applyUnifiedDiff(patch) {
|
|
|
21835
21835
|
}
|
|
21836
21836
|
function runWithStdin(options) {
|
|
21837
21837
|
const { command, args, cwd: cwd4, stdin } = options;
|
|
21838
|
-
return new Promise((
|
|
21838
|
+
return new Promise((resolve35) => {
|
|
21839
21839
|
const child = spawn15(command, args, {
|
|
21840
21840
|
cwd: cwd4,
|
|
21841
21841
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -21852,10 +21852,10 @@ function runWithStdin(options) {
|
|
|
21852
21852
|
child.stdin.end();
|
|
21853
21853
|
child.on("close", (code) => {
|
|
21854
21854
|
const exitCode = code ?? -1;
|
|
21855
|
-
|
|
21855
|
+
resolve35({ success: exitCode === 0, exitCode, stdout, stderr });
|
|
21856
21856
|
});
|
|
21857
21857
|
child.on("error", (err) => {
|
|
21858
|
-
|
|
21858
|
+
resolve35({ success: false, exitCode: -1, stdout, stderr: err.message });
|
|
21859
21859
|
});
|
|
21860
21860
|
});
|
|
21861
21861
|
}
|
|
@@ -25597,8 +25597,8 @@ ${this.options.dynamicContext}`,
|
|
|
25597
25597
|
async waitIfPaused() {
|
|
25598
25598
|
if (!this._paused)
|
|
25599
25599
|
return true;
|
|
25600
|
-
await new Promise((
|
|
25601
|
-
this._pauseResolve =
|
|
25600
|
+
await new Promise((resolve35) => {
|
|
25601
|
+
this._pauseResolve = resolve35;
|
|
25602
25602
|
});
|
|
25603
25603
|
return !this.aborted;
|
|
25604
25604
|
}
|
|
@@ -25688,7 +25688,32 @@ Respond with your assessment, then take action.`;
|
|
|
25688
25688
|
|
|
25689
25689
|
TASK: ${task}` : task }
|
|
25690
25690
|
];
|
|
25691
|
-
|
|
25691
|
+
let toolDefs = this.buildToolDefinitions();
|
|
25692
|
+
let textToolModeActive = this.options.textToolMode ?? false;
|
|
25693
|
+
if (textToolModeActive) {
|
|
25694
|
+
const toolDescriptions = Array.from(this.tools.values()).map((t) => `- ${t.name}: ${t.description}`).join("\n");
|
|
25695
|
+
messages[0].content += [
|
|
25696
|
+
"\n\n[TEXT TOOL MODE]",
|
|
25697
|
+
"This model uses text-based tool invocation (no native tool API).",
|
|
25698
|
+
"To use a tool, output a JSON block in your response:",
|
|
25699
|
+
"```json",
|
|
25700
|
+
'{"tool": "tool_name", "args": {"param": "value"}}',
|
|
25701
|
+
"```",
|
|
25702
|
+
"\nAvailable tools:",
|
|
25703
|
+
toolDescriptions,
|
|
25704
|
+
"\nRules:",
|
|
25705
|
+
"- Output EXACTLY ONE tool call per response in the JSON format above",
|
|
25706
|
+
"- After seeing the tool result, continue or call another tool",
|
|
25707
|
+
'- When done: {"tool": "task_complete", "args": {"summary": "what you did"}}',
|
|
25708
|
+
"- You CAN also write ```bash ... ``` blocks which will be auto-executed"
|
|
25709
|
+
].join("\n");
|
|
25710
|
+
toolDefs = [];
|
|
25711
|
+
this.emit({
|
|
25712
|
+
type: "status",
|
|
25713
|
+
content: "Text tool mode active \u2014 tools described in prompt, parsed from JSON/code blocks",
|
|
25714
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
25715
|
+
});
|
|
25716
|
+
}
|
|
25692
25717
|
let totalTokens = 0;
|
|
25693
25718
|
let promptTokens = 0;
|
|
25694
25719
|
let completionTokens = 0;
|
|
@@ -26674,14 +26699,14 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
26674
26699
|
waitForSudoPassword(timeoutMs = 12e4) {
|
|
26675
26700
|
if (this._sudoPassword)
|
|
26676
26701
|
return Promise.resolve(this._sudoPassword);
|
|
26677
|
-
return new Promise((
|
|
26702
|
+
return new Promise((resolve35) => {
|
|
26678
26703
|
const timer = setTimeout(() => {
|
|
26679
26704
|
this._sudoResolve = null;
|
|
26680
|
-
|
|
26705
|
+
resolve35(null);
|
|
26681
26706
|
}, timeoutMs);
|
|
26682
26707
|
this._sudoResolve = (pw) => {
|
|
26683
26708
|
clearTimeout(timer);
|
|
26684
|
-
|
|
26709
|
+
resolve35(pw);
|
|
26685
26710
|
};
|
|
26686
26711
|
});
|
|
26687
26712
|
}
|
|
@@ -26814,10 +26839,10 @@ ${marker}` : marker);
|
|
|
26814
26839
|
if (!this._workingDirectory)
|
|
26815
26840
|
return;
|
|
26816
26841
|
try {
|
|
26817
|
-
const { mkdirSync:
|
|
26818
|
-
const { join:
|
|
26819
|
-
const sessionDir =
|
|
26820
|
-
|
|
26842
|
+
const { mkdirSync: mkdirSync26, writeFileSync: writeFileSync25 } = __require("node:fs");
|
|
26843
|
+
const { join: join72 } = __require("node:path");
|
|
26844
|
+
const sessionDir = join72(this._workingDirectory, ".oa", "session", this._sessionId);
|
|
26845
|
+
mkdirSync26(sessionDir, { recursive: true });
|
|
26821
26846
|
const checkpoint = {
|
|
26822
26847
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26823
26848
|
sessionId: this._sessionId,
|
|
@@ -26829,7 +26854,7 @@ ${marker}` : marker);
|
|
|
26829
26854
|
memexEntryCount: this._memexArchive.size,
|
|
26830
26855
|
fileRegistrySize: this._fileRegistry.size
|
|
26831
26856
|
};
|
|
26832
|
-
|
|
26857
|
+
writeFileSync25(join72(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
|
|
26833
26858
|
} catch {
|
|
26834
26859
|
}
|
|
26835
26860
|
}
|
|
@@ -28405,12 +28430,12 @@ var init_nexusBackend = __esm({
|
|
|
28405
28430
|
const deadline = Date.now() + (request.timeoutMs ?? 12e4);
|
|
28406
28431
|
try {
|
|
28407
28432
|
while (!done && Date.now() < deadline) {
|
|
28408
|
-
await new Promise((
|
|
28433
|
+
await new Promise((resolve35) => {
|
|
28409
28434
|
let resolved = false;
|
|
28410
28435
|
const finish = () => {
|
|
28411
28436
|
if (!resolved) {
|
|
28412
28437
|
resolved = true;
|
|
28413
|
-
|
|
28438
|
+
resolve35();
|
|
28414
28439
|
}
|
|
28415
28440
|
};
|
|
28416
28441
|
let watcher = null;
|
|
@@ -29492,9 +29517,9 @@ function ensureTranscribeCliBackground() {
|
|
|
29492
29517
|
}
|
|
29493
29518
|
try {
|
|
29494
29519
|
const { exec: exec4 } = await import("node:child_process");
|
|
29495
|
-
return new Promise((
|
|
29520
|
+
return new Promise((resolve35) => {
|
|
29496
29521
|
exec4("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
|
|
29497
|
-
|
|
29522
|
+
resolve35(!err);
|
|
29498
29523
|
});
|
|
29499
29524
|
});
|
|
29500
29525
|
} catch {
|
|
@@ -29553,7 +29578,7 @@ var init_listen = __esm({
|
|
|
29553
29578
|
return this._ready;
|
|
29554
29579
|
}
|
|
29555
29580
|
async start() {
|
|
29556
|
-
return new Promise((
|
|
29581
|
+
return new Promise((resolve35, reject) => {
|
|
29557
29582
|
const timeout = setTimeout(() => {
|
|
29558
29583
|
reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
|
|
29559
29584
|
}, 3e5);
|
|
@@ -29581,7 +29606,7 @@ var init_listen = __esm({
|
|
|
29581
29606
|
this._ready = true;
|
|
29582
29607
|
clearTimeout(timeout);
|
|
29583
29608
|
this.emit("ready");
|
|
29584
|
-
|
|
29609
|
+
resolve35();
|
|
29585
29610
|
break;
|
|
29586
29611
|
case "transcript":
|
|
29587
29612
|
this.emit("transcript", {
|
|
@@ -29719,8 +29744,8 @@ var init_listen = __esm({
|
|
|
29719
29744
|
const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
|
|
29720
29745
|
if (existsSync32(nvmBase)) {
|
|
29721
29746
|
try {
|
|
29722
|
-
const { readdirSync:
|
|
29723
|
-
for (const ver of
|
|
29747
|
+
const { readdirSync: readdirSync21 } = await import("node:fs");
|
|
29748
|
+
for (const ver of readdirSync21(nvmBase)) {
|
|
29724
29749
|
const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
|
|
29725
29750
|
if (existsSync32(join48(tcPath, "dist", "index.js"))) {
|
|
29726
29751
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
@@ -29785,11 +29810,11 @@ var init_listen = __esm({
|
|
|
29785
29810
|
this.liveTranscriber.on("error", (err) => {
|
|
29786
29811
|
this.emit("error", err);
|
|
29787
29812
|
});
|
|
29788
|
-
await new Promise((
|
|
29813
|
+
await new Promise((resolve35, reject) => {
|
|
29789
29814
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
29790
29815
|
this.liveTranscriber.on("ready", () => {
|
|
29791
29816
|
clearTimeout(timeout);
|
|
29792
|
-
|
|
29817
|
+
resolve35();
|
|
29793
29818
|
});
|
|
29794
29819
|
this.liveTranscriber.on("error", (err) => {
|
|
29795
29820
|
clearTimeout(timeout);
|
|
@@ -29951,11 +29976,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
29951
29976
|
sampleWidth: 2,
|
|
29952
29977
|
chunkDuration: 3
|
|
29953
29978
|
});
|
|
29954
|
-
await new Promise((
|
|
29979
|
+
await new Promise((resolve35, reject) => {
|
|
29955
29980
|
const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
|
|
29956
29981
|
transcriber.on("ready", () => {
|
|
29957
29982
|
clearTimeout(timeout);
|
|
29958
|
-
|
|
29983
|
+
resolve35();
|
|
29959
29984
|
});
|
|
29960
29985
|
transcriber.on("error", (err) => {
|
|
29961
29986
|
clearTimeout(timeout);
|
|
@@ -32258,7 +32283,7 @@ var require_websocket = __commonJS({
|
|
|
32258
32283
|
var http = __require("http");
|
|
32259
32284
|
var net = __require("net");
|
|
32260
32285
|
var tls = __require("tls");
|
|
32261
|
-
var { randomBytes:
|
|
32286
|
+
var { randomBytes: randomBytes16, createHash: createHash6 } = __require("crypto");
|
|
32262
32287
|
var { Duplex, Readable } = __require("stream");
|
|
32263
32288
|
var { URL: URL3 } = __require("url");
|
|
32264
32289
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -32788,7 +32813,7 @@ var require_websocket = __commonJS({
|
|
|
32788
32813
|
}
|
|
32789
32814
|
}
|
|
32790
32815
|
const defaultPort = isSecure ? 443 : 80;
|
|
32791
|
-
const key =
|
|
32816
|
+
const key = randomBytes16(16).toString("base64");
|
|
32792
32817
|
const request = isSecure ? https.request : http.request;
|
|
32793
32818
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
32794
32819
|
let perMessageDeflate;
|
|
@@ -34928,8 +34953,8 @@ var init_voice_session = __esm({
|
|
|
34928
34953
|
this.server.keepAliveTimeout = 0;
|
|
34929
34954
|
this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
|
|
34930
34955
|
this.wss.on("connection", (ws, req) => this.handleWSConnection(ws, req));
|
|
34931
|
-
await new Promise((
|
|
34932
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
34956
|
+
await new Promise((resolve35, reject) => {
|
|
34957
|
+
this.server.listen(port, "127.0.0.1", () => resolve35());
|
|
34933
34958
|
this.server.on("error", reject);
|
|
34934
34959
|
});
|
|
34935
34960
|
try {
|
|
@@ -35147,7 +35172,7 @@ var init_voice_session = __esm({
|
|
|
35147
35172
|
}
|
|
35148
35173
|
// ── Cloudflared tunnel ────────────────────────────────────────────────
|
|
35149
35174
|
startCloudflared(port) {
|
|
35150
|
-
return new Promise((
|
|
35175
|
+
return new Promise((resolve35, reject) => {
|
|
35151
35176
|
const timeout = setTimeout(() => {
|
|
35152
35177
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
35153
35178
|
}, 3e4);
|
|
@@ -35165,7 +35190,7 @@ var init_voice_session = __esm({
|
|
|
35165
35190
|
if (urlMatch && !urlFound) {
|
|
35166
35191
|
urlFound = true;
|
|
35167
35192
|
clearTimeout(timeout);
|
|
35168
|
-
|
|
35193
|
+
resolve35(urlMatch[0]);
|
|
35169
35194
|
}
|
|
35170
35195
|
};
|
|
35171
35196
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -35205,13 +35230,13 @@ var init_voice_session = __esm({
|
|
|
35205
35230
|
}
|
|
35206
35231
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
35207
35232
|
findFreePort() {
|
|
35208
|
-
return new Promise((
|
|
35233
|
+
return new Promise((resolve35, reject) => {
|
|
35209
35234
|
const srv = createServer2();
|
|
35210
35235
|
srv.listen(0, "127.0.0.1", () => {
|
|
35211
35236
|
const addr = srv.address();
|
|
35212
35237
|
if (addr && typeof addr === "object") {
|
|
35213
35238
|
const port = addr.port;
|
|
35214
|
-
srv.close(() =>
|
|
35239
|
+
srv.close(() => resolve35(port));
|
|
35215
35240
|
} else {
|
|
35216
35241
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
35217
35242
|
}
|
|
@@ -35334,8 +35359,8 @@ async function collectSystemMetricsAsync() {
|
|
|
35334
35359
|
vramUtilization: 0
|
|
35335
35360
|
};
|
|
35336
35361
|
try {
|
|
35337
|
-
const smi = await new Promise((
|
|
35338
|
-
exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
35362
|
+
const smi = await new Promise((resolve35, reject) => {
|
|
35363
|
+
exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
|
|
35339
35364
|
});
|
|
35340
35365
|
const line = smi.trim().split("\n")[0];
|
|
35341
35366
|
if (line) {
|
|
@@ -35483,8 +35508,8 @@ var init_expose = __esm({
|
|
|
35483
35508
|
throw new Error("Gateway already running");
|
|
35484
35509
|
const port = await this.findFreePort();
|
|
35485
35510
|
this.server = this.createProxyServer(port);
|
|
35486
|
-
await new Promise((
|
|
35487
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
35511
|
+
await new Promise((resolve35, reject) => {
|
|
35512
|
+
this.server.listen(port, "127.0.0.1", () => resolve35());
|
|
35488
35513
|
this.server.on("error", reject);
|
|
35489
35514
|
});
|
|
35490
35515
|
let lastStartErr;
|
|
@@ -35546,8 +35571,8 @@ var init_expose = __esm({
|
|
|
35546
35571
|
this._cloudflaredPid = state.pid;
|
|
35547
35572
|
this._proxyPort = state.proxyPort;
|
|
35548
35573
|
this.server = this.createProxyServer(state.proxyPort);
|
|
35549
|
-
await new Promise((
|
|
35550
|
-
this.server.listen(state.proxyPort, "127.0.0.1", () =>
|
|
35574
|
+
await new Promise((resolve35, reject) => {
|
|
35575
|
+
this.server.listen(state.proxyPort, "127.0.0.1", () => resolve35());
|
|
35551
35576
|
this.server.on("error", reject);
|
|
35552
35577
|
});
|
|
35553
35578
|
this._stats.status = "active";
|
|
@@ -35572,8 +35597,8 @@ var init_expose = __esm({
|
|
|
35572
35597
|
}
|
|
35573
35598
|
this._cloudflaredPid = null;
|
|
35574
35599
|
if (this.server) {
|
|
35575
|
-
await new Promise((
|
|
35576
|
-
this.server.close(() =>
|
|
35600
|
+
await new Promise((resolve35) => {
|
|
35601
|
+
this.server.close(() => resolve35());
|
|
35577
35602
|
});
|
|
35578
35603
|
this.server = null;
|
|
35579
35604
|
}
|
|
@@ -35905,7 +35930,7 @@ var init_expose = __esm({
|
|
|
35905
35930
|
_proxyPort = 0;
|
|
35906
35931
|
startCloudflared(port) {
|
|
35907
35932
|
this._proxyPort = port;
|
|
35908
|
-
return new Promise((
|
|
35933
|
+
return new Promise((resolve35, reject) => {
|
|
35909
35934
|
const timeout = setTimeout(() => {
|
|
35910
35935
|
reject(new Error("Cloudflared tunnel start timeout (30s)"));
|
|
35911
35936
|
}, 3e4);
|
|
@@ -35934,7 +35959,7 @@ var init_expose = __esm({
|
|
|
35934
35959
|
this.cloudflaredProcess?.unref();
|
|
35935
35960
|
this.cloudflaredProcess?.stdout?.destroy();
|
|
35936
35961
|
this.cloudflaredProcess?.stderr?.destroy();
|
|
35937
|
-
|
|
35962
|
+
resolve35(urlMatch[0]);
|
|
35938
35963
|
}
|
|
35939
35964
|
};
|
|
35940
35965
|
this.cloudflaredProcess.stdout?.on("data", handleOutput);
|
|
@@ -36023,13 +36048,13 @@ ${this.formatConnectionInfo()}`);
|
|
|
36023
36048
|
}
|
|
36024
36049
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
36025
36050
|
findFreePort() {
|
|
36026
|
-
return new Promise((
|
|
36051
|
+
return new Promise((resolve35, reject) => {
|
|
36027
36052
|
const srv = createServer3();
|
|
36028
36053
|
srv.listen(0, "127.0.0.1", () => {
|
|
36029
36054
|
const addr = srv.address();
|
|
36030
36055
|
if (addr && typeof addr === "object") {
|
|
36031
36056
|
const port = addr.port;
|
|
36032
|
-
srv.close(() =>
|
|
36057
|
+
srv.close(() => resolve35(port));
|
|
36033
36058
|
} else {
|
|
36034
36059
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
36035
36060
|
}
|
|
@@ -36976,8 +37001,8 @@ var init_peer_mesh = __esm({
|
|
|
36976
37001
|
this.wss.on("connection", (ws, req) => {
|
|
36977
37002
|
this.handleInboundConnection(ws, req.url ?? "");
|
|
36978
37003
|
});
|
|
36979
|
-
await new Promise((
|
|
36980
|
-
this.server.listen(port, "127.0.0.1", () =>
|
|
37004
|
+
await new Promise((resolve35, reject) => {
|
|
37005
|
+
this.server.listen(port, "127.0.0.1", () => resolve35());
|
|
36981
37006
|
this.server.on("error", reject);
|
|
36982
37007
|
});
|
|
36983
37008
|
this.pingTimer = setInterval(() => this.pingAll(), PING_INTERVAL_MS);
|
|
@@ -37016,7 +37041,7 @@ var init_peer_mesh = __esm({
|
|
|
37016
37041
|
this.wss = null;
|
|
37017
37042
|
}
|
|
37018
37043
|
if (this.server) {
|
|
37019
|
-
await new Promise((
|
|
37044
|
+
await new Promise((resolve35) => this.server.close(() => resolve35()));
|
|
37020
37045
|
this.server = null;
|
|
37021
37046
|
}
|
|
37022
37047
|
this.emit("stopped");
|
|
@@ -37034,7 +37059,7 @@ var init_peer_mesh = __esm({
|
|
|
37034
37059
|
if (!wsUrl.includes("/p2p"))
|
|
37035
37060
|
wsUrl += "/p2p";
|
|
37036
37061
|
wsUrl += `?key=${encodeURIComponent(this._authKey)}`;
|
|
37037
|
-
return new Promise((
|
|
37062
|
+
return new Promise((resolve35, reject) => {
|
|
37038
37063
|
const ws = new import_websocket.default(wsUrl, { handshakeTimeout: 1e4 });
|
|
37039
37064
|
let resolved = false;
|
|
37040
37065
|
const timeout = setTimeout(() => {
|
|
@@ -37074,7 +37099,7 @@ var init_peer_mesh = __esm({
|
|
|
37074
37099
|
this.connections.set(peer.peerId, ws);
|
|
37075
37100
|
this.setupPeerHandlers(ws, peer.peerId);
|
|
37076
37101
|
this.emit("peer_connected", peer);
|
|
37077
|
-
|
|
37102
|
+
resolve35(peer);
|
|
37078
37103
|
} else {
|
|
37079
37104
|
this.handleMessage(msg, ws);
|
|
37080
37105
|
}
|
|
@@ -37129,12 +37154,12 @@ var init_peer_mesh = __esm({
|
|
|
37129
37154
|
throw new Error(`Peer ${peerId} not connected`);
|
|
37130
37155
|
}
|
|
37131
37156
|
const msgId = randomBytes14(8).toString("hex");
|
|
37132
|
-
return new Promise((
|
|
37157
|
+
return new Promise((resolve35, reject) => {
|
|
37133
37158
|
const timeout = setTimeout(() => {
|
|
37134
37159
|
this.pendingRequests.delete(msgId);
|
|
37135
37160
|
reject(new Error(`Inference timeout (${timeoutMs}ms)`));
|
|
37136
37161
|
}, timeoutMs);
|
|
37137
|
-
this.pendingRequests.set(msgId, { resolve:
|
|
37162
|
+
this.pendingRequests.set(msgId, { resolve: resolve35, reject, timeout, chunks: [] });
|
|
37138
37163
|
this.sendMsg(ws, "infer_request", request, msgId);
|
|
37139
37164
|
});
|
|
37140
37165
|
}
|
|
@@ -37356,13 +37381,13 @@ var init_peer_mesh = __esm({
|
|
|
37356
37381
|
ws.send(JSON.stringify(msg));
|
|
37357
37382
|
}
|
|
37358
37383
|
findFreePort() {
|
|
37359
|
-
return new Promise((
|
|
37384
|
+
return new Promise((resolve35, reject) => {
|
|
37360
37385
|
const srv = createServer4();
|
|
37361
37386
|
srv.listen(0, "127.0.0.1", () => {
|
|
37362
37387
|
const addr = srv.address();
|
|
37363
37388
|
if (addr && typeof addr === "object") {
|
|
37364
37389
|
const port = addr.port;
|
|
37365
|
-
srv.close(() =>
|
|
37390
|
+
srv.close(() => resolve35(port));
|
|
37366
37391
|
} else {
|
|
37367
37392
|
srv.close(() => reject(new Error("Could not find free port")));
|
|
37368
37393
|
}
|
|
@@ -37992,26 +38017,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
|
|
|
37992
38017
|
async function fetchPeerModels(peerId, authKey) {
|
|
37993
38018
|
try {
|
|
37994
38019
|
const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
37995
|
-
const { existsSync:
|
|
37996
|
-
const { join:
|
|
38020
|
+
const { existsSync: existsSync52, readFileSync: readFileSync40 } = await import("node:fs");
|
|
38021
|
+
const { join: join72 } = await import("node:path");
|
|
37997
38022
|
const cwd4 = process.cwd();
|
|
37998
38023
|
const nexusTool = new NexusTool2(cwd4);
|
|
37999
38024
|
const nexusDir = nexusTool.getNexusDir();
|
|
38000
38025
|
let isLocalPeer = false;
|
|
38001
38026
|
try {
|
|
38002
|
-
const statusPath =
|
|
38003
|
-
if (
|
|
38004
|
-
const status = JSON.parse(
|
|
38027
|
+
const statusPath = join72(nexusDir, "status.json");
|
|
38028
|
+
if (existsSync52(statusPath)) {
|
|
38029
|
+
const status = JSON.parse(readFileSync40(statusPath, "utf8"));
|
|
38005
38030
|
if (status.peerId === peerId)
|
|
38006
38031
|
isLocalPeer = true;
|
|
38007
38032
|
}
|
|
38008
38033
|
} catch {
|
|
38009
38034
|
}
|
|
38010
38035
|
if (isLocalPeer) {
|
|
38011
|
-
const pricingPath =
|
|
38012
|
-
if (
|
|
38036
|
+
const pricingPath = join72(nexusDir, "pricing.json");
|
|
38037
|
+
if (existsSync52(pricingPath)) {
|
|
38013
38038
|
try {
|
|
38014
|
-
const pricing = JSON.parse(
|
|
38039
|
+
const pricing = JSON.parse(readFileSync40(pricingPath, "utf8"));
|
|
38015
38040
|
const localModels = (pricing.models || []).map((m) => ({
|
|
38016
38041
|
name: m.model || "unknown",
|
|
38017
38042
|
size: m.parameterSize || "",
|
|
@@ -38025,10 +38050,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
38025
38050
|
}
|
|
38026
38051
|
}
|
|
38027
38052
|
}
|
|
38028
|
-
const cachePath =
|
|
38029
|
-
if (
|
|
38053
|
+
const cachePath = join72(nexusDir, "peer-models-cache.json");
|
|
38054
|
+
if (existsSync52(cachePath)) {
|
|
38030
38055
|
try {
|
|
38031
|
-
const cache4 = JSON.parse(
|
|
38056
|
+
const cache4 = JSON.parse(readFileSync40(cachePath, "utf8"));
|
|
38032
38057
|
if (cache4.peerId === peerId && cache4.models?.length > 0) {
|
|
38033
38058
|
const age = Date.now() - new Date(cache4.cachedAt).getTime();
|
|
38034
38059
|
if (age < 5 * 60 * 1e3) {
|
|
@@ -38143,10 +38168,10 @@ async function fetchPeerModels(peerId, authKey) {
|
|
|
38143
38168
|
} catch {
|
|
38144
38169
|
}
|
|
38145
38170
|
if (isLocalPeer) {
|
|
38146
|
-
const pricingPath =
|
|
38147
|
-
if (
|
|
38171
|
+
const pricingPath = join72(nexusDir, "pricing.json");
|
|
38172
|
+
if (existsSync52(pricingPath)) {
|
|
38148
38173
|
try {
|
|
38149
|
-
const pricing = JSON.parse(
|
|
38174
|
+
const pricing = JSON.parse(readFileSync40(pricingPath, "utf8"));
|
|
38150
38175
|
return (pricing.models || []).map((m) => ({
|
|
38151
38176
|
name: m.model || "unknown",
|
|
38152
38177
|
size: m.parameterSize || "",
|
|
@@ -39132,6 +39157,34 @@ import { promisify as promisify6 } from "node:util";
|
|
|
39132
39157
|
import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
|
|
39133
39158
|
import { join as join54 } from "node:path";
|
|
39134
39159
|
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
39160
|
+
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
39161
|
+
if (_toolSupportCache.has(modelName))
|
|
39162
|
+
return _toolSupportCache.get(modelName);
|
|
39163
|
+
try {
|
|
39164
|
+
const resp = await fetch(`${backendUrl.replace(/\/+$/, "")}/api/show`, {
|
|
39165
|
+
method: "POST",
|
|
39166
|
+
headers: { "Content-Type": "application/json" },
|
|
39167
|
+
body: JSON.stringify({ name: modelName }),
|
|
39168
|
+
signal: AbortSignal.timeout(5e3)
|
|
39169
|
+
});
|
|
39170
|
+
if (!resp.ok) {
|
|
39171
|
+
_toolSupportCache.set(modelName, false);
|
|
39172
|
+
return false;
|
|
39173
|
+
}
|
|
39174
|
+
const data = await resp.json();
|
|
39175
|
+
const template = data.template ?? "";
|
|
39176
|
+
const hasTools = template.includes("{{.Tools}}") || template.includes("{{ .Tools }}");
|
|
39177
|
+
_toolSupportCache.set(modelName, hasTools);
|
|
39178
|
+
return hasTools;
|
|
39179
|
+
} catch {
|
|
39180
|
+
_toolSupportCache.set(modelName, false);
|
|
39181
|
+
return false;
|
|
39182
|
+
}
|
|
39183
|
+
}
|
|
39184
|
+
async function needsTextToolMode(modelName, backendUrl) {
|
|
39185
|
+
const hasTools = await checkToolSupport(modelName, backendUrl);
|
|
39186
|
+
return !hasTools;
|
|
39187
|
+
}
|
|
39135
39188
|
function detectSystemSpecs() {
|
|
39136
39189
|
let totalRamGB = 0;
|
|
39137
39190
|
let availableRamGB = 0;
|
|
@@ -39259,21 +39312,13 @@ function calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
|
|
|
39259
39312
|
const label = numCtx >= 1024 ? `${Math.floor(numCtx / 1024)}K` : String(numCtx);
|
|
39260
39313
|
return { numCtx, label };
|
|
39261
39314
|
}
|
|
39262
|
-
function modelSupportsToolCalling(modelName) {
|
|
39263
|
-
const lower = modelName.toLowerCase();
|
|
39264
|
-
for (const known of TOOL_CALLING_MODELS) {
|
|
39265
|
-
if (lower.startsWith(known) || lower.includes(known))
|
|
39266
|
-
return true;
|
|
39267
|
-
}
|
|
39268
|
-
return false;
|
|
39269
|
-
}
|
|
39270
39315
|
function ask(rl, question) {
|
|
39271
|
-
return new Promise((
|
|
39272
|
-
rl.question(question, (answer) =>
|
|
39316
|
+
return new Promise((resolve35) => {
|
|
39317
|
+
rl.question(question, (answer) => resolve35(answer.trim()));
|
|
39273
39318
|
});
|
|
39274
39319
|
}
|
|
39275
39320
|
function askSecret(rl, question) {
|
|
39276
|
-
return new Promise((
|
|
39321
|
+
return new Promise((resolve35) => {
|
|
39277
39322
|
process.stdout.write(question);
|
|
39278
39323
|
let secret = "";
|
|
39279
39324
|
const stdin = process.stdin;
|
|
@@ -39291,7 +39336,7 @@ function askSecret(rl, question) {
|
|
|
39291
39336
|
stdin.setRawMode(hadRawMode ?? false);
|
|
39292
39337
|
}
|
|
39293
39338
|
process.stdout.write("\n");
|
|
39294
|
-
|
|
39339
|
+
resolve35(secret.trim());
|
|
39295
39340
|
return;
|
|
39296
39341
|
} else if (c3 === "") {
|
|
39297
39342
|
stdin.removeListener("data", onData);
|
|
@@ -39299,7 +39344,7 @@ function askSecret(rl, question) {
|
|
|
39299
39344
|
stdin.setRawMode(hadRawMode ?? false);
|
|
39300
39345
|
}
|
|
39301
39346
|
process.stdout.write("\n");
|
|
39302
|
-
|
|
39347
|
+
resolve35("");
|
|
39303
39348
|
return;
|
|
39304
39349
|
} else if (c3 === "\x7F" || c3 === "\b") {
|
|
39305
39350
|
if (secret.length > 0) {
|
|
@@ -39534,7 +39579,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
39534
39579
|
return false;
|
|
39535
39580
|
}
|
|
39536
39581
|
for (let i = 0; i < 5; i++) {
|
|
39537
|
-
await new Promise((
|
|
39582
|
+
await new Promise((resolve35) => setTimeout(resolve35, 2e3));
|
|
39538
39583
|
try {
|
|
39539
39584
|
const resp = await fetch(`${backendUrl}/api/tags`, {
|
|
39540
39585
|
signal: AbortSignal.timeout(3e3)
|
|
@@ -39995,7 +40040,7 @@ async function doSetup(config, rl) {
|
|
|
39995
40040
|
try {
|
|
39996
40041
|
const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
39997
40042
|
child.unref();
|
|
39998
|
-
await new Promise((
|
|
40043
|
+
await new Promise((resolve35) => setTimeout(resolve35, 3e3));
|
|
39999
40044
|
try {
|
|
40000
40045
|
models = await fetchOllamaModels(config.backendUrl);
|
|
40001
40046
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -40023,7 +40068,7 @@ async function doSetup(config, rl) {
|
|
|
40023
40068
|
try {
|
|
40024
40069
|
const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
40025
40070
|
child.unref();
|
|
40026
|
-
await new Promise((
|
|
40071
|
+
await new Promise((resolve35) => setTimeout(resolve35, 3e3));
|
|
40027
40072
|
try {
|
|
40028
40073
|
models = await fetchOllamaModels(config.backendUrl);
|
|
40029
40074
|
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
@@ -40065,33 +40110,42 @@ async function doSetup(config, rl) {
|
|
|
40065
40110
|
process.stdout.write(` ${c2.yellow("\u26A0")} Default model ${c2.bold(config.model)} is not available.
|
|
40066
40111
|
|
|
40067
40112
|
`);
|
|
40068
|
-
|
|
40069
|
-
|
|
40070
|
-
|
|
40113
|
+
if (models.length > 0) {
|
|
40114
|
+
const backendUrl = config.backendUrl || "http://localhost:11434";
|
|
40115
|
+
const modelChecks = await Promise.all(models.slice(0, 15).map(async (m) => ({
|
|
40116
|
+
...m,
|
|
40117
|
+
hasTools: await checkToolSupport(m.name, backendUrl)
|
|
40118
|
+
})));
|
|
40119
|
+
process.stdout.write(` ${c2.cyan("\u25CF")} Available models:
|
|
40071
40120
|
|
|
40072
40121
|
`);
|
|
40073
|
-
for (let i = 0; i <
|
|
40074
|
-
const m =
|
|
40075
|
-
|
|
40122
|
+
for (let i = 0; i < modelChecks.length; i++) {
|
|
40123
|
+
const m = modelChecks[i];
|
|
40124
|
+
const toolTag = m.hasTools ? c2.green("tools \u2713") : c2.yellow("text mode");
|
|
40125
|
+
process.stdout.write(` ${c2.bold(String(i + 1))}. ${m.name} ${c2.dim(`(${m.size})`)} ${toolTag}
|
|
40076
40126
|
`);
|
|
40077
40127
|
}
|
|
40078
40128
|
process.stdout.write(`
|
|
40079
40129
|
${c2.dim("0")}. Pull a new qwen3.5 model instead
|
|
40130
|
+
`);
|
|
40131
|
+
process.stdout.write(`
|
|
40132
|
+
${c2.dim("Models marked 'text mode' work via instruct-and-parse (no native tool API needed)")}
|
|
40080
40133
|
`);
|
|
40081
40134
|
process.stdout.write("\n");
|
|
40082
|
-
const choice = await ask(rl, ` ${c2.bold("Select a model")} (1-${
|
|
40135
|
+
const choice = await ask(rl, ` ${c2.bold("Select a model")} (1-${modelChecks.length}, or 0 to pull new): `);
|
|
40083
40136
|
const idx = parseInt(choice, 10);
|
|
40084
|
-
if (idx > 0 && idx <=
|
|
40085
|
-
const selected =
|
|
40137
|
+
if (idx > 0 && idx <= modelChecks.length) {
|
|
40138
|
+
const selected = modelChecks[idx - 1];
|
|
40086
40139
|
setConfigValue("model", selected.name);
|
|
40140
|
+
const mode = selected.hasTools ? "native tool calling" : "text mode (instruct-and-parse)";
|
|
40087
40141
|
process.stdout.write(`
|
|
40088
|
-
${c2.green("\u2714")} Selected ${c2.bold(selected.name)}. Saved to config.
|
|
40142
|
+
${c2.green("\u2714")} Selected ${c2.bold(selected.name)} \u2014 ${mode}. Saved to config.
|
|
40089
40143
|
|
|
40090
40144
|
`);
|
|
40091
40145
|
return selected.name;
|
|
40092
40146
|
}
|
|
40093
40147
|
} else {
|
|
40094
|
-
process.stdout.write(` ${c2.yellow("\u26A0")} No
|
|
40148
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} No models found on this system.
|
|
40095
40149
|
|
|
40096
40150
|
`);
|
|
40097
40151
|
}
|
|
@@ -40809,7 +40863,7 @@ export PATH="${binDir}:$PATH" # Added by open-agents for nvim
|
|
|
40809
40863
|
} catch {
|
|
40810
40864
|
}
|
|
40811
40865
|
}
|
|
40812
|
-
var execAsync, QWEN_VARIANTS,
|
|
40866
|
+
var execAsync, QWEN_VARIANTS, _toolSupportCache, _cloudflaredInstallPromise;
|
|
40813
40867
|
var init_setup = __esm({
|
|
40814
40868
|
"packages/cli/dist/tui/setup.js"() {
|
|
40815
40869
|
"use strict";
|
|
@@ -40829,19 +40883,7 @@ var init_setup = __esm({
|
|
|
40829
40883
|
{ tag: "qwen3.5:cloud", sizeGB: 0, label: "Cloud (Ollama Cloud)", cloud: true },
|
|
40830
40884
|
{ tag: "qwen3.5:397b-cloud", sizeGB: 0, label: "397B Cloud (Ollama Cloud)", cloud: true }
|
|
40831
40885
|
];
|
|
40832
|
-
|
|
40833
|
-
"qwen3.5",
|
|
40834
|
-
"qwen3",
|
|
40835
|
-
"qwen2.5",
|
|
40836
|
-
"llama3.3",
|
|
40837
|
-
"llama3.1",
|
|
40838
|
-
"mistral",
|
|
40839
|
-
"mixtral",
|
|
40840
|
-
"command-r",
|
|
40841
|
-
"gemma3",
|
|
40842
|
-
"devstral",
|
|
40843
|
-
"deepseek"
|
|
40844
|
-
]);
|
|
40886
|
+
_toolSupportCache = /* @__PURE__ */ new Map();
|
|
40845
40887
|
_cloudflaredInstallPromise = null;
|
|
40846
40888
|
}
|
|
40847
40889
|
});
|
|
@@ -41015,7 +41057,7 @@ function tuiSelect(opts) {
|
|
|
41015
41057
|
const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
|
|
41016
41058
|
let scrollOffset = 0;
|
|
41017
41059
|
let lastRenderedLines = 0;
|
|
41018
|
-
return new Promise((
|
|
41060
|
+
return new Promise((resolve35) => {
|
|
41019
41061
|
const stdin = process.stdin;
|
|
41020
41062
|
const hadRawMode = stdin.isRaw;
|
|
41021
41063
|
const savedRlListeners = [];
|
|
@@ -41190,7 +41232,7 @@ function tuiSelect(opts) {
|
|
|
41190
41232
|
if (!isSkippable(itemIdx) && matchSet.has(itemIdx)) {
|
|
41191
41233
|
cursor = itemIdx;
|
|
41192
41234
|
cleanup();
|
|
41193
|
-
|
|
41235
|
+
resolve35({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
41194
41236
|
return;
|
|
41195
41237
|
} else if (!isSkippable(itemIdx)) {
|
|
41196
41238
|
cursor = itemIdx;
|
|
@@ -41266,7 +41308,7 @@ function tuiSelect(opts) {
|
|
|
41266
41308
|
items.splice(deletedIdx, 1);
|
|
41267
41309
|
if (items.length === 0) {
|
|
41268
41310
|
cleanup();
|
|
41269
|
-
|
|
41311
|
+
resolve35({ confirmed: false, key: null, index: -1 });
|
|
41270
41312
|
return;
|
|
41271
41313
|
}
|
|
41272
41314
|
updateFilter();
|
|
@@ -41355,7 +41397,7 @@ function tuiSelect(opts) {
|
|
|
41355
41397
|
} else if (seq === "\r" || seq === "\n") {
|
|
41356
41398
|
if (!isSkippable(cursor) && matchSet.has(cursor)) {
|
|
41357
41399
|
cleanup();
|
|
41358
|
-
|
|
41400
|
+
resolve35({ confirmed: true, key: items[cursor].key, index: cursor });
|
|
41359
41401
|
}
|
|
41360
41402
|
} else if (seq === "\x1B" || seq === "\x1B\x1B") {
|
|
41361
41403
|
if (filter) {
|
|
@@ -41368,14 +41410,14 @@ function tuiSelect(opts) {
|
|
|
41368
41410
|
render();
|
|
41369
41411
|
} else if (hasBreadcrumbs) {
|
|
41370
41412
|
cleanup();
|
|
41371
|
-
|
|
41413
|
+
resolve35({ confirmed: false, key: "__back__", index: cursor });
|
|
41372
41414
|
} else {
|
|
41373
41415
|
cleanup();
|
|
41374
|
-
|
|
41416
|
+
resolve35({ confirmed: false, key: null, index: cursor });
|
|
41375
41417
|
}
|
|
41376
41418
|
} else if (seq === "") {
|
|
41377
41419
|
cleanup();
|
|
41378
|
-
|
|
41420
|
+
resolve35({ confirmed: false, key: null, index: cursor });
|
|
41379
41421
|
} else if (seq === "\x7F" || seq === "\b") {
|
|
41380
41422
|
if (filter.length > 0) {
|
|
41381
41423
|
filter = filter.slice(0, -1);
|
|
@@ -41389,7 +41431,7 @@ function tuiSelect(opts) {
|
|
|
41389
41431
|
render();
|
|
41390
41432
|
} else if (hasBreadcrumbs) {
|
|
41391
41433
|
cleanup();
|
|
41392
|
-
|
|
41434
|
+
resolve35({ confirmed: false, key: "__back__", index: cursor });
|
|
41393
41435
|
}
|
|
41394
41436
|
} else if (seq.length === 1 && seq.charCodeAt(0) >= 32 && seq.charCodeAt(0) < 127) {
|
|
41395
41437
|
if (opts.onCustomKey && !isSkippable(cursor) && matchSet.has(cursor)) {
|
|
@@ -41397,7 +41439,7 @@ function tuiSelect(opts) {
|
|
|
41397
41439
|
done: () => render(),
|
|
41398
41440
|
resolve: (result) => {
|
|
41399
41441
|
cleanup();
|
|
41400
|
-
|
|
41442
|
+
resolve35(result);
|
|
41401
41443
|
},
|
|
41402
41444
|
getInput: (prompt, prefill) => getInputFromUser(prompt, prefill),
|
|
41403
41445
|
render: () => render(),
|
|
@@ -41939,12 +41981,12 @@ function stopNeovimMode() {
|
|
|
41939
41981
|
} catch {
|
|
41940
41982
|
}
|
|
41941
41983
|
const s = _state;
|
|
41942
|
-
return new Promise((
|
|
41984
|
+
return new Promise((resolve35) => {
|
|
41943
41985
|
setTimeout(() => {
|
|
41944
41986
|
if (s && !s.cleanedUp) {
|
|
41945
41987
|
doCleanup(s);
|
|
41946
41988
|
}
|
|
41947
|
-
|
|
41989
|
+
resolve35();
|
|
41948
41990
|
}, 300);
|
|
41949
41991
|
});
|
|
41950
41992
|
}
|
|
@@ -43615,7 +43657,7 @@ var init_voice = __esm({
|
|
|
43615
43657
|
this.speaking = false;
|
|
43616
43658
|
}
|
|
43617
43659
|
sleep(ms) {
|
|
43618
|
-
return new Promise((
|
|
43660
|
+
return new Promise((resolve35) => setTimeout(resolve35, ms));
|
|
43619
43661
|
}
|
|
43620
43662
|
// -------------------------------------------------------------------------
|
|
43621
43663
|
// Synthesis pipeline
|
|
@@ -43881,7 +43923,7 @@ var init_voice = __esm({
|
|
|
43881
43923
|
const cmd = this.getPlayCommand(path);
|
|
43882
43924
|
if (!cmd)
|
|
43883
43925
|
return;
|
|
43884
|
-
return new Promise((
|
|
43926
|
+
return new Promise((resolve35) => {
|
|
43885
43927
|
const child = nodeSpawn(cmd[0], cmd.slice(1), {
|
|
43886
43928
|
stdio: "ignore",
|
|
43887
43929
|
detached: false
|
|
@@ -43890,12 +43932,12 @@ var init_voice = __esm({
|
|
|
43890
43932
|
child.on("close", () => {
|
|
43891
43933
|
if (this.currentPlayback === child)
|
|
43892
43934
|
this.currentPlayback = null;
|
|
43893
|
-
|
|
43935
|
+
resolve35();
|
|
43894
43936
|
});
|
|
43895
43937
|
child.on("error", () => {
|
|
43896
43938
|
if (this.currentPlayback === child)
|
|
43897
43939
|
this.currentPlayback = null;
|
|
43898
|
-
|
|
43940
|
+
resolve35();
|
|
43899
43941
|
});
|
|
43900
43942
|
setTimeout(() => {
|
|
43901
43943
|
if (this.currentPlayback === child) {
|
|
@@ -43905,7 +43947,7 @@ var init_voice = __esm({
|
|
|
43905
43947
|
}
|
|
43906
43948
|
this.currentPlayback = null;
|
|
43907
43949
|
}
|
|
43908
|
-
|
|
43950
|
+
resolve35();
|
|
43909
43951
|
}, 15e3);
|
|
43910
43952
|
});
|
|
43911
43953
|
}
|
|
@@ -43980,7 +44022,7 @@ var init_voice = __esm({
|
|
|
43980
44022
|
/** Non-blocking shell execution — async alternative to execSync.
|
|
43981
44023
|
* Returns stdout string on exit 0, rejects otherwise. */
|
|
43982
44024
|
asyncShell(command, timeoutMs = 3e4) {
|
|
43983
|
-
return new Promise((
|
|
44025
|
+
return new Promise((resolve35, reject) => {
|
|
43984
44026
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
43985
44027
|
stdio: ["ignore", "pipe", "pipe"],
|
|
43986
44028
|
cwd: tmpdir9()
|
|
@@ -44001,7 +44043,7 @@ var init_voice = __esm({
|
|
|
44001
44043
|
proc.on("close", (code) => {
|
|
44002
44044
|
clearTimeout(timer);
|
|
44003
44045
|
if (code === 0)
|
|
44004
|
-
|
|
44046
|
+
resolve35(stdout.trim());
|
|
44005
44047
|
else
|
|
44006
44048
|
reject(new Error(stderr.slice(0, 300) || `Exit code ${code}`));
|
|
44007
44049
|
});
|
|
@@ -44493,7 +44535,7 @@ if __name__ == '__main__':
|
|
|
44493
44535
|
const venvPy = luxttsVenvPy();
|
|
44494
44536
|
if (!existsSync40(venvPy))
|
|
44495
44537
|
return false;
|
|
44496
|
-
return new Promise((
|
|
44538
|
+
return new Promise((resolve35) => {
|
|
44497
44539
|
const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
|
|
44498
44540
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
|
|
44499
44541
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -44512,7 +44554,7 @@ if __name__ == '__main__':
|
|
|
44512
44554
|
try {
|
|
44513
44555
|
const msg = JSON.parse(line);
|
|
44514
44556
|
if (msg.type === "ready") {
|
|
44515
|
-
|
|
44557
|
+
resolve35(true);
|
|
44516
44558
|
} else if (msg.type === "result" || msg.type === "error") {
|
|
44517
44559
|
const pending = this._luxttsPending.get(msg.id);
|
|
44518
44560
|
if (pending) {
|
|
@@ -44536,25 +44578,25 @@ if __name__ == '__main__':
|
|
|
44536
44578
|
});
|
|
44537
44579
|
daemon.on("error", () => {
|
|
44538
44580
|
this._luxttsDaemon = null;
|
|
44539
|
-
|
|
44581
|
+
resolve35(false);
|
|
44540
44582
|
});
|
|
44541
44583
|
setTimeout(() => {
|
|
44542
44584
|
if (this._luxttsDaemon === daemon && !this._luxttsPending.has("__ready__")) {
|
|
44543
|
-
|
|
44585
|
+
resolve35(false);
|
|
44544
44586
|
}
|
|
44545
44587
|
}, 6e4);
|
|
44546
44588
|
});
|
|
44547
44589
|
}
|
|
44548
44590
|
/** Send a request to the LuxTTS daemon and await the response */
|
|
44549
44591
|
luxttsRequest(req) {
|
|
44550
|
-
return new Promise((
|
|
44592
|
+
return new Promise((resolve35, reject) => {
|
|
44551
44593
|
if (!this._luxttsDaemon || this._luxttsDaemon.killed) {
|
|
44552
44594
|
reject(new Error("LuxTTS daemon not running"));
|
|
44553
44595
|
return;
|
|
44554
44596
|
}
|
|
44555
44597
|
const id = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
44556
44598
|
req.id = id;
|
|
44557
|
-
this._luxttsPending.set(id, { resolve:
|
|
44599
|
+
this._luxttsPending.set(id, { resolve: resolve35, reject });
|
|
44558
44600
|
this._luxttsDaemon.stdin.write(JSON.stringify(req) + "\n");
|
|
44559
44601
|
setTimeout(() => {
|
|
44560
44602
|
if (this._luxttsPending.has(id)) {
|
|
@@ -45937,8 +45979,8 @@ async function handleSlashCommand(input, ctx) {
|
|
|
45937
45979
|
writeFileSync18(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
45938
45980
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
45939
45981
|
try {
|
|
45940
|
-
const { spawn:
|
|
45941
|
-
const child =
|
|
45982
|
+
const { spawn: spawn22 } = __require("node:child_process");
|
|
45983
|
+
const child = spawn22("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
|
|
45942
45984
|
cwd: join57(fDir, "apps", "standalone"),
|
|
45943
45985
|
stdio: "ignore",
|
|
45944
45986
|
detached: true,
|
|
@@ -47695,12 +47737,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
47695
47737
|
continue;
|
|
47696
47738
|
}
|
|
47697
47739
|
const { basename: basename18, join: pathJoin } = await import("node:path");
|
|
47698
|
-
const { copyFileSync: copyFileSync2, mkdirSync:
|
|
47740
|
+
const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync26, existsSync: exists } = await import("node:fs");
|
|
47699
47741
|
const { homedir: homedir18 } = await import("node:os");
|
|
47700
47742
|
const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
47701
47743
|
const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
|
|
47702
47744
|
if (!exists(destDir))
|
|
47703
|
-
|
|
47745
|
+
mkdirSync26(destDir, { recursive: true });
|
|
47704
47746
|
copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
|
|
47705
47747
|
copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
|
|
47706
47748
|
const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
|
|
@@ -48192,11 +48234,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
|
|
|
48192
48234
|
const models = await fetchModels(peerUrl, authKey);
|
|
48193
48235
|
if (models.length > 0) {
|
|
48194
48236
|
try {
|
|
48195
|
-
const { writeFileSync:
|
|
48196
|
-
const { join:
|
|
48197
|
-
const cachePath =
|
|
48198
|
-
|
|
48199
|
-
|
|
48237
|
+
const { writeFileSync: writeFileSync25, mkdirSync: mkdirSync26 } = await import("node:fs");
|
|
48238
|
+
const { join: join72, dirname: dirname22 } = await import("node:path");
|
|
48239
|
+
const cachePath = join72(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
|
|
48240
|
+
mkdirSync26(dirname22(cachePath), { recursive: true });
|
|
48241
|
+
writeFileSync25(cachePath, JSON.stringify({
|
|
48200
48242
|
peerId,
|
|
48201
48243
|
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48202
48244
|
models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
|
|
@@ -48347,8 +48389,8 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
|
|
|
48347
48389
|
}
|
|
48348
48390
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
48349
48391
|
process.env.OLLAMA_NUM_PARALLEL = String(n);
|
|
48350
|
-
const { spawn:
|
|
48351
|
-
const child =
|
|
48392
|
+
const { spawn: spawn22 } = await import("node:child_process");
|
|
48393
|
+
const child = spawn22("ollama", ["serve"], {
|
|
48352
48394
|
stdio: "ignore",
|
|
48353
48395
|
detached: true,
|
|
48354
48396
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
|
|
@@ -48395,17 +48437,17 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48395
48437
|
try {
|
|
48396
48438
|
const { createRequire: createRequire4 } = await import("node:module");
|
|
48397
48439
|
const { fileURLToPath: fileURLToPath14 } = await import("node:url");
|
|
48398
|
-
const { dirname: dirname22, join:
|
|
48399
|
-
const { existsSync:
|
|
48440
|
+
const { dirname: dirname22, join: join72 } = await import("node:path");
|
|
48441
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
48400
48442
|
const req = createRequire4(import.meta.url);
|
|
48401
48443
|
const thisDir = dirname22(fileURLToPath14(import.meta.url));
|
|
48402
48444
|
const candidates = [
|
|
48403
|
-
|
|
48404
|
-
|
|
48405
|
-
|
|
48445
|
+
join72(thisDir, "..", "package.json"),
|
|
48446
|
+
join72(thisDir, "..", "..", "package.json"),
|
|
48447
|
+
join72(thisDir, "..", "..", "..", "package.json")
|
|
48406
48448
|
];
|
|
48407
48449
|
for (const pkgPath of candidates) {
|
|
48408
|
-
if (
|
|
48450
|
+
if (existsSync52(pkgPath)) {
|
|
48409
48451
|
const pkg = req(pkgPath);
|
|
48410
48452
|
if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
|
|
48411
48453
|
currentVersion = pkg.version ?? "0.0.0";
|
|
@@ -48599,11 +48641,11 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48599
48641
|
const targetVersion = info?.latestVersion ?? currentVersion;
|
|
48600
48642
|
const installOverlay = startInstallOverlay(targetVersion);
|
|
48601
48643
|
let installError = "";
|
|
48602
|
-
const runInstall2 = (cmd) => new Promise((
|
|
48644
|
+
const runInstall2 = (cmd) => new Promise((resolve35) => {
|
|
48603
48645
|
const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
48604
48646
|
if (err)
|
|
48605
48647
|
installError = (stderr || err.message || "").trim();
|
|
48606
|
-
|
|
48648
|
+
resolve35(!err);
|
|
48607
48649
|
});
|
|
48608
48650
|
child.stdout?.on("data", (chunk) => {
|
|
48609
48651
|
const text = String(chunk);
|
|
@@ -48697,8 +48739,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48697
48739
|
}
|
|
48698
48740
|
if (doRebuild) {
|
|
48699
48741
|
installOverlay.setStatus("Rebuilding native modules...");
|
|
48700
|
-
await new Promise((
|
|
48701
|
-
const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () =>
|
|
48742
|
+
await new Promise((resolve35) => {
|
|
48743
|
+
const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve35(true));
|
|
48702
48744
|
child.stdout?.resume();
|
|
48703
48745
|
child.stderr?.resume();
|
|
48704
48746
|
});
|
|
@@ -48730,8 +48772,8 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
48730
48772
|
const venvPip2 = isWin2 ? pathJoin(venvDir, "Scripts", "pip.exe") : pathJoin(venvDir, "bin", "pip");
|
|
48731
48773
|
if (fsExists(venvPip2)) {
|
|
48732
48774
|
installOverlay.setStatus("Upgrading Python packages...");
|
|
48733
|
-
await new Promise((
|
|
48734
|
-
const child = exec4(`"${venvPip2}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) =>
|
|
48775
|
+
await new Promise((resolve35) => {
|
|
48776
|
+
const child = exec4(`"${venvPip2}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve35(!err));
|
|
48735
48777
|
child.stdout?.resume();
|
|
48736
48778
|
child.stderr?.resume();
|
|
48737
48779
|
});
|
|
@@ -49127,16 +49169,16 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
49127
49169
|
renderDashboard();
|
|
49128
49170
|
}, 1e3);
|
|
49129
49171
|
let stopGateway = false;
|
|
49130
|
-
await new Promise((
|
|
49172
|
+
await new Promise((resolve35) => {
|
|
49131
49173
|
const onData = (data) => {
|
|
49132
49174
|
const key = data.toString();
|
|
49133
49175
|
if (key === "q" || key === "Q" || key === "\x1B" || key === "") {
|
|
49134
|
-
|
|
49176
|
+
resolve35();
|
|
49135
49177
|
return;
|
|
49136
49178
|
}
|
|
49137
49179
|
if (key === "s" || key === "S") {
|
|
49138
49180
|
stopGateway = true;
|
|
49139
|
-
|
|
49181
|
+
resolve35();
|
|
49140
49182
|
return;
|
|
49141
49183
|
}
|
|
49142
49184
|
if (key === "c" || key === "C") {
|
|
@@ -49187,8 +49229,8 @@ async function showExposeDashboard(gateway, rl, ctx) {
|
|
|
49187
49229
|
process.stdout.write("\x1B[?1002h\x1B[?1006h");
|
|
49188
49230
|
}
|
|
49189
49231
|
};
|
|
49190
|
-
const origResolve =
|
|
49191
|
-
|
|
49232
|
+
const origResolve = resolve35;
|
|
49233
|
+
resolve35 = (() => {
|
|
49192
49234
|
cleanup();
|
|
49193
49235
|
origResolve();
|
|
49194
49236
|
});
|
|
@@ -56589,8 +56631,8 @@ async function collectNetworkMetrics() {
|
|
|
56589
56631
|
}
|
|
56590
56632
|
if (plat === "darwin") {
|
|
56591
56633
|
try {
|
|
56592
|
-
const output = await new Promise((
|
|
56593
|
-
exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
56634
|
+
const output = await new Promise((resolve35, reject) => {
|
|
56635
|
+
exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
|
|
56594
56636
|
});
|
|
56595
56637
|
let rxBytes = 0, txBytes = 0;
|
|
56596
56638
|
for (const line of output.split("\n")) {
|
|
@@ -56624,8 +56666,8 @@ async function collectGpuMetrics() {
|
|
|
56624
56666
|
if (_nvidiaSmiAvailable === false)
|
|
56625
56667
|
return noGpu;
|
|
56626
56668
|
try {
|
|
56627
|
-
const smi = await new Promise((
|
|
56628
|
-
exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) :
|
|
56669
|
+
const smi = await new Promise((resolve35, reject) => {
|
|
56670
|
+
exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
|
|
56629
56671
|
});
|
|
56630
56672
|
_nvidiaSmiAvailable = true;
|
|
56631
56673
|
const line = smi.trim().split("\n")[0];
|
|
@@ -60073,9 +60115,17 @@ ${lines.join("\n")}
|
|
|
60073
60115
|
personalityName: personality ?? void 0,
|
|
60074
60116
|
identityInjection,
|
|
60075
60117
|
environmentProvider
|
|
60118
|
+
// Text tool mode is set dynamically after runner creation (async check)
|
|
60119
|
+
// The runner also auto-detects this when Ollama returns HTTP 400 for tools
|
|
60076
60120
|
});
|
|
60077
60121
|
runner.setWorkingDirectory(repoRoot);
|
|
60078
60122
|
_activeRunnerRef = runner;
|
|
60123
|
+
needsTextToolMode(config.model, config.backendUrl).then((needsText) => {
|
|
60124
|
+
if (needsText) {
|
|
60125
|
+
runner.options.textToolMode = true;
|
|
60126
|
+
}
|
|
60127
|
+
}).catch(() => {
|
|
60128
|
+
});
|
|
60079
60129
|
const tools = buildTools(repoRoot, config, contextWindowSize);
|
|
60080
60130
|
if (contextWindowSize && contextWindowSize > 0) {
|
|
60081
60131
|
for (const tool of tools) {
|
|
@@ -60994,14 +61044,14 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
|
|
|
60994
61044
|
renderInfo(msg);
|
|
60995
61045
|
statusBar.endContentWrite();
|
|
60996
61046
|
}
|
|
60997
|
-
}, () => new Promise((
|
|
61047
|
+
}, () => new Promise((resolve35) => {
|
|
60998
61048
|
depSudoPromptPending = true;
|
|
60999
61049
|
depSudoResolver = (pw) => {
|
|
61000
61050
|
depSudoPromptPending = false;
|
|
61001
61051
|
depSudoResolver = null;
|
|
61002
61052
|
if (pw)
|
|
61003
61053
|
sessionSudoPassword = pw;
|
|
61004
|
-
|
|
61054
|
+
resolve35(pw);
|
|
61005
61055
|
};
|
|
61006
61056
|
const pwPrompt1 = ` ${c2.bold(c2.yellow("\u{1F511} Password needed for dependency install:"))}
|
|
61007
61057
|
`;
|
|
@@ -64032,8 +64082,21 @@ var init_interactive = __esm({
|
|
|
64032
64082
|
// packages/cli/dist/commands/run.js
|
|
64033
64083
|
var run_exports = {};
|
|
64034
64084
|
__export(run_exports, {
|
|
64035
|
-
|
|
64085
|
+
jobsCommand: () => jobsCommand,
|
|
64086
|
+
runCommand: () => runCommand,
|
|
64087
|
+
statusCommand: () => statusCommand
|
|
64036
64088
|
});
|
|
64089
|
+
import { resolve as resolve32 } from "node:path";
|
|
64090
|
+
import { spawn as spawn20 } from "node:child_process";
|
|
64091
|
+
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, readFileSync as readFileSync39, readdirSync as readdirSync20, existsSync as existsSync50 } from "node:fs";
|
|
64092
|
+
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
64093
|
+
import { join as join67 } from "node:path";
|
|
64094
|
+
function jobsDir(repoPath) {
|
|
64095
|
+
const root = resolve32(repoPath ?? process.cwd());
|
|
64096
|
+
const dir = join67(root, ".oa", "jobs");
|
|
64097
|
+
mkdirSync24(dir, { recursive: true });
|
|
64098
|
+
return dir;
|
|
64099
|
+
}
|
|
64037
64100
|
async function runCommand(opts, config) {
|
|
64038
64101
|
const mergedConfig = {
|
|
64039
64102
|
...config,
|
|
@@ -64043,11 +64106,148 @@ async function runCommand(opts, config) {
|
|
|
64043
64106
|
...opts.maxRetries !== void 0 ? { maxRetries: opts.maxRetries } : {}
|
|
64044
64107
|
};
|
|
64045
64108
|
if (opts.task) {
|
|
64046
|
-
|
|
64109
|
+
if (opts.background) {
|
|
64110
|
+
await runBackground(opts.task, mergedConfig, opts);
|
|
64111
|
+
} else if (opts.json) {
|
|
64112
|
+
await runJson(opts.task, mergedConfig, opts.repoPath);
|
|
64113
|
+
} else {
|
|
64114
|
+
await runWithTUI(opts.task, mergedConfig, opts.repoPath);
|
|
64115
|
+
}
|
|
64047
64116
|
} else {
|
|
64048
64117
|
await startInteractive(mergedConfig, opts.repoPath);
|
|
64049
64118
|
}
|
|
64050
64119
|
}
|
|
64120
|
+
async function runJson(task, config, repoPath) {
|
|
64121
|
+
const startTime = Date.now();
|
|
64122
|
+
const origWrite = process.stdout.write.bind(process.stdout);
|
|
64123
|
+
const captured = [];
|
|
64124
|
+
process.stdout.write = ((chunk, ...args) => {
|
|
64125
|
+
if (typeof chunk === "string")
|
|
64126
|
+
captured.push(chunk);
|
|
64127
|
+
return true;
|
|
64128
|
+
});
|
|
64129
|
+
let result;
|
|
64130
|
+
try {
|
|
64131
|
+
await runWithTUI(task, config, repoPath);
|
|
64132
|
+
result = {
|
|
64133
|
+
status: "completed",
|
|
64134
|
+
summary: extractSummary(captured),
|
|
64135
|
+
durationMs: Date.now() - startTime,
|
|
64136
|
+
exitCode: 0
|
|
64137
|
+
};
|
|
64138
|
+
} catch (err) {
|
|
64139
|
+
result = {
|
|
64140
|
+
status: "failed",
|
|
64141
|
+
error: err instanceof Error ? err.message : String(err),
|
|
64142
|
+
durationMs: Date.now() - startTime,
|
|
64143
|
+
exitCode: 1
|
|
64144
|
+
};
|
|
64145
|
+
}
|
|
64146
|
+
process.stdout.write = origWrite;
|
|
64147
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
64148
|
+
if (result.exitCode !== 0)
|
|
64149
|
+
process.exit(1);
|
|
64150
|
+
}
|
|
64151
|
+
function extractSummary(captured) {
|
|
64152
|
+
const all = captured.join("");
|
|
64153
|
+
const match = all.match(/task_complete.*?summary[:\s]*["']?([^"'\n]+)/i);
|
|
64154
|
+
if (match)
|
|
64155
|
+
return match[1].trim();
|
|
64156
|
+
const lines = all.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "").split("\n").filter((l) => l.trim());
|
|
64157
|
+
return lines.slice(-3).join(" ").slice(0, 200);
|
|
64158
|
+
}
|
|
64159
|
+
async function runBackground(task, config, opts) {
|
|
64160
|
+
const id = `job-${randomBytes15(3).toString("hex")}`;
|
|
64161
|
+
const dir = jobsDir(opts.repoPath);
|
|
64162
|
+
const repoRoot = resolve32(opts.repoPath ?? process.cwd());
|
|
64163
|
+
const job = {
|
|
64164
|
+
id,
|
|
64165
|
+
pid: 0,
|
|
64166
|
+
task,
|
|
64167
|
+
status: "running",
|
|
64168
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
64169
|
+
};
|
|
64170
|
+
const oaBin = process.argv[1] || "oa";
|
|
64171
|
+
const args = [task, "--json"];
|
|
64172
|
+
if (config.model)
|
|
64173
|
+
args.push("--model", config.model);
|
|
64174
|
+
const child = spawn20("node", [oaBin, ...args], {
|
|
64175
|
+
cwd: repoRoot,
|
|
64176
|
+
env: { ...process.env, OA_JOB_ID: id },
|
|
64177
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
64178
|
+
detached: true
|
|
64179
|
+
});
|
|
64180
|
+
child.unref();
|
|
64181
|
+
job.pid = child.pid ?? 0;
|
|
64182
|
+
writeFileSync23(join67(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64183
|
+
let output = "";
|
|
64184
|
+
child.stdout?.on("data", (chunk) => {
|
|
64185
|
+
output += chunk.toString();
|
|
64186
|
+
});
|
|
64187
|
+
child.stderr?.on("data", (chunk) => {
|
|
64188
|
+
output += chunk.toString();
|
|
64189
|
+
});
|
|
64190
|
+
child.on("exit", (code) => {
|
|
64191
|
+
try {
|
|
64192
|
+
const result = output.trim() ? JSON.parse(output) : { status: code === 0 ? "completed" : "failed" };
|
|
64193
|
+
job.status = result.status || (code === 0 ? "completed" : "failed");
|
|
64194
|
+
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
64195
|
+
job.summary = result.summary;
|
|
64196
|
+
job.durationMs = result.durationMs;
|
|
64197
|
+
job.error = result.error;
|
|
64198
|
+
writeFileSync23(join67(dir, `${id}.json`), JSON.stringify(job, null, 2));
|
|
64199
|
+
} catch {
|
|
64200
|
+
}
|
|
64201
|
+
});
|
|
64202
|
+
console.log(`Job started: ${id} (PID ${job.pid})`);
|
|
64203
|
+
console.log("");
|
|
64204
|
+
console.log("Monitor this job:");
|
|
64205
|
+
console.log(` oa status ${id} # Check progress`);
|
|
64206
|
+
console.log(` oa output ${id} # See full output`);
|
|
64207
|
+
console.log(` oa jobs # List all jobs`);
|
|
64208
|
+
console.log(` kill ${job.pid} # Stop the job`);
|
|
64209
|
+
console.log("");
|
|
64210
|
+
console.log(`Job file: .oa/jobs/${id}.json`);
|
|
64211
|
+
}
|
|
64212
|
+
function statusCommand(jobId, repoPath) {
|
|
64213
|
+
const dir = jobsDir(repoPath);
|
|
64214
|
+
const file = join67(dir, `${jobId}.json`);
|
|
64215
|
+
if (!existsSync50(file)) {
|
|
64216
|
+
console.error(`Job not found: ${jobId}`);
|
|
64217
|
+
console.log(`Available jobs: oa jobs`);
|
|
64218
|
+
process.exit(1);
|
|
64219
|
+
}
|
|
64220
|
+
const job = JSON.parse(readFileSync39(file, "utf-8"));
|
|
64221
|
+
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
64222
|
+
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
64223
|
+
console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
|
|
64224
|
+
console.log(` Task: ${job.task.slice(0, 80)}`);
|
|
64225
|
+
console.log(` PID: ${job.pid}`);
|
|
64226
|
+
if (job.summary)
|
|
64227
|
+
console.log(` Summary: ${job.summary}`);
|
|
64228
|
+
if (job.error)
|
|
64229
|
+
console.log(` Error: ${job.error}`);
|
|
64230
|
+
if (job.durationMs)
|
|
64231
|
+
console.log(` Duration: ${(job.durationMs / 1e3).toFixed(1)}s`);
|
|
64232
|
+
}
|
|
64233
|
+
function jobsCommand(repoPath) {
|
|
64234
|
+
const dir = jobsDir(repoPath);
|
|
64235
|
+
const files = readdirSync20(dir).filter((f) => f.endsWith(".json")).sort();
|
|
64236
|
+
if (files.length === 0) {
|
|
64237
|
+
console.log("No jobs found.");
|
|
64238
|
+
return;
|
|
64239
|
+
}
|
|
64240
|
+
console.log("Jobs:");
|
|
64241
|
+
for (const file of files) {
|
|
64242
|
+
try {
|
|
64243
|
+
const job = JSON.parse(readFileSync39(join67(dir, file), "utf-8"));
|
|
64244
|
+
const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
|
|
64245
|
+
const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
|
|
64246
|
+
console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
|
|
64247
|
+
} catch {
|
|
64248
|
+
}
|
|
64249
|
+
}
|
|
64250
|
+
}
|
|
64051
64251
|
var init_run = __esm({
|
|
64052
64252
|
"packages/cli/dist/commands/run.js"() {
|
|
64053
64253
|
"use strict";
|
|
@@ -64060,7 +64260,7 @@ import { glob } from "glob";
|
|
|
64060
64260
|
import ignore from "ignore";
|
|
64061
64261
|
import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
|
|
64062
64262
|
import { createHash as createHash5 } from "node:crypto";
|
|
64063
|
-
import { join as
|
|
64263
|
+
import { join as join68, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
|
|
64064
64264
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
64065
64265
|
var init_codebase_indexer = __esm({
|
|
64066
64266
|
"packages/indexer/dist/codebase-indexer.js"() {
|
|
@@ -64104,7 +64304,7 @@ var init_codebase_indexer = __esm({
|
|
|
64104
64304
|
const ig = ignore.default();
|
|
64105
64305
|
if (this.config.respectGitignore) {
|
|
64106
64306
|
try {
|
|
64107
|
-
const gitignoreContent = await readFile23(
|
|
64307
|
+
const gitignoreContent = await readFile23(join68(this.config.rootDir, ".gitignore"), "utf-8");
|
|
64108
64308
|
ig.add(gitignoreContent);
|
|
64109
64309
|
} catch {
|
|
64110
64310
|
}
|
|
@@ -64119,7 +64319,7 @@ var init_codebase_indexer = __esm({
|
|
|
64119
64319
|
for (const relativePath of files) {
|
|
64120
64320
|
if (ig.ignores(relativePath))
|
|
64121
64321
|
continue;
|
|
64122
|
-
const fullPath =
|
|
64322
|
+
const fullPath = join68(this.config.rootDir, relativePath);
|
|
64123
64323
|
try {
|
|
64124
64324
|
const fileStat = await stat4(fullPath);
|
|
64125
64325
|
if (fileStat.size > this.config.maxFileSize)
|
|
@@ -64165,7 +64365,7 @@ var init_codebase_indexer = __esm({
|
|
|
64165
64365
|
if (!child) {
|
|
64166
64366
|
child = {
|
|
64167
64367
|
name: part,
|
|
64168
|
-
path:
|
|
64368
|
+
path: join68(current.path, part),
|
|
64169
64369
|
type: "directory",
|
|
64170
64370
|
children: []
|
|
64171
64371
|
};
|
|
@@ -64247,14 +64447,14 @@ var index_repo_exports = {};
|
|
|
64247
64447
|
__export(index_repo_exports, {
|
|
64248
64448
|
indexRepoCommand: () => indexRepoCommand
|
|
64249
64449
|
});
|
|
64250
|
-
import { resolve as
|
|
64251
|
-
import { existsSync as
|
|
64450
|
+
import { resolve as resolve33 } from "node:path";
|
|
64451
|
+
import { existsSync as existsSync51, statSync as statSync16 } from "node:fs";
|
|
64252
64452
|
import { cwd as cwd2 } from "node:process";
|
|
64253
64453
|
async function indexRepoCommand(opts, _config) {
|
|
64254
|
-
const repoRoot =
|
|
64454
|
+
const repoRoot = resolve33(opts.repoPath ?? cwd2());
|
|
64255
64455
|
printHeader("Index Repository");
|
|
64256
64456
|
printInfo(`Indexing: ${repoRoot}`);
|
|
64257
|
-
if (!
|
|
64457
|
+
if (!existsSync51(repoRoot)) {
|
|
64258
64458
|
printError(`Path does not exist: ${repoRoot}`);
|
|
64259
64459
|
process.exit(1);
|
|
64260
64460
|
}
|
|
@@ -64346,9 +64546,9 @@ var init_index_repo = __esm({
|
|
|
64346
64546
|
// packages/cli/dist/commands/status.js
|
|
64347
64547
|
var status_exports = {};
|
|
64348
64548
|
__export(status_exports, {
|
|
64349
|
-
statusCommand: () =>
|
|
64549
|
+
statusCommand: () => statusCommand2
|
|
64350
64550
|
});
|
|
64351
|
-
async function
|
|
64551
|
+
async function statusCommand2(opts, config) {
|
|
64352
64552
|
printHeader("open-agents status");
|
|
64353
64553
|
const backendType = config.backendType;
|
|
64354
64554
|
if (backendType === "ollama") {
|
|
@@ -64506,7 +64706,7 @@ var config_exports = {};
|
|
|
64506
64706
|
__export(config_exports, {
|
|
64507
64707
|
configCommand: () => configCommand
|
|
64508
64708
|
});
|
|
64509
|
-
import { join as
|
|
64709
|
+
import { join as join69, resolve as resolve34 } from "node:path";
|
|
64510
64710
|
import { homedir as homedir17 } from "node:os";
|
|
64511
64711
|
import { cwd as cwd3 } from "node:process";
|
|
64512
64712
|
function redactIfSensitive(key, value) {
|
|
@@ -64539,7 +64739,7 @@ async function configCommand(opts, config) {
|
|
|
64539
64739
|
return handleShow(opts, config);
|
|
64540
64740
|
}
|
|
64541
64741
|
function handleShow(opts, config) {
|
|
64542
|
-
const repoRoot =
|
|
64742
|
+
const repoRoot = resolve34(opts.repoPath ?? cwd3());
|
|
64543
64743
|
printHeader("Configuration");
|
|
64544
64744
|
const resolved = resolveSettings(repoRoot);
|
|
64545
64745
|
printSection("Core Inference");
|
|
@@ -64589,7 +64789,7 @@ function handleShow(opts, config) {
|
|
|
64589
64789
|
}
|
|
64590
64790
|
}
|
|
64591
64791
|
printSection("Config File");
|
|
64592
|
-
printInfo(`~/.open-agents/config.json (${
|
|
64792
|
+
printInfo(`~/.open-agents/config.json (${join69(homedir17(), ".open-agents", "config.json")})`);
|
|
64593
64793
|
printSection("Priority Chain");
|
|
64594
64794
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
64595
64795
|
printInfo(" 2. Project .oa/settings.json (--local)");
|
|
@@ -64622,13 +64822,13 @@ function handleSet(opts, _config) {
|
|
|
64622
64822
|
process.exit(1);
|
|
64623
64823
|
}
|
|
64624
64824
|
if (opts.local) {
|
|
64625
|
-
const repoRoot =
|
|
64825
|
+
const repoRoot = resolve34(opts.repoPath ?? cwd3());
|
|
64626
64826
|
try {
|
|
64627
64827
|
initOaDirectory(repoRoot);
|
|
64628
64828
|
const coerced = coerceForSettings(key, value);
|
|
64629
64829
|
saveProjectSettings(repoRoot, { [key]: coerced });
|
|
64630
64830
|
printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
|
|
64631
|
-
printInfo(`Saved to ${
|
|
64831
|
+
printInfo(`Saved to ${join69(repoRoot, ".oa", "settings.json")}`);
|
|
64632
64832
|
printInfo("This override applies only when running in this workspace.");
|
|
64633
64833
|
} catch (err) {
|
|
64634
64834
|
printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -64728,7 +64928,7 @@ var serve_exports = {};
|
|
|
64728
64928
|
__export(serve_exports, {
|
|
64729
64929
|
serveCommand: () => serveCommand
|
|
64730
64930
|
});
|
|
64731
|
-
import { spawn as
|
|
64931
|
+
import { spawn as spawn21 } from "node:child_process";
|
|
64732
64932
|
async function serveCommand(opts, config) {
|
|
64733
64933
|
const backendType = config.backendType;
|
|
64734
64934
|
if (backendType === "ollama") {
|
|
@@ -64820,8 +65020,8 @@ async function serveVllm(opts, config) {
|
|
|
64820
65020
|
await runVllmServer(args, opts.verbose ?? false);
|
|
64821
65021
|
}
|
|
64822
65022
|
async function runVllmServer(args, verbose) {
|
|
64823
|
-
return new Promise((
|
|
64824
|
-
const child =
|
|
65023
|
+
return new Promise((resolve35, reject) => {
|
|
65024
|
+
const child = spawn21("python", args, {
|
|
64825
65025
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
64826
65026
|
env: { ...process.env }
|
|
64827
65027
|
});
|
|
@@ -64855,10 +65055,10 @@ async function runVllmServer(args, verbose) {
|
|
|
64855
65055
|
child.once("exit", (code, signal) => {
|
|
64856
65056
|
if (signal) {
|
|
64857
65057
|
printInfo(`vLLM server stopped by signal ${signal}`);
|
|
64858
|
-
|
|
65058
|
+
resolve35();
|
|
64859
65059
|
} else if (code === 0) {
|
|
64860
65060
|
printSuccess("vLLM server exited cleanly");
|
|
64861
|
-
|
|
65061
|
+
resolve35();
|
|
64862
65062
|
} else {
|
|
64863
65063
|
printError(`vLLM server exited with code ${code}`);
|
|
64864
65064
|
reject(new Error(`vLLM exited with code ${code}`));
|
|
@@ -64886,8 +65086,8 @@ __export(eval_exports, {
|
|
|
64886
65086
|
evalCommand: () => evalCommand
|
|
64887
65087
|
});
|
|
64888
65088
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
64889
|
-
import { mkdirSync as
|
|
64890
|
-
import { join as
|
|
65089
|
+
import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync24 } from "node:fs";
|
|
65090
|
+
import { join as join70 } from "node:path";
|
|
64891
65091
|
async function evalCommand(opts, config) {
|
|
64892
65092
|
const suiteName = opts.suite ?? "basic";
|
|
64893
65093
|
const suite = SUITES[suiteName];
|
|
@@ -65012,9 +65212,9 @@ async function evalCommand(opts, config) {
|
|
|
65012
65212
|
process.exit(failed > 0 ? 1 : 0);
|
|
65013
65213
|
}
|
|
65014
65214
|
function createTempEvalRepo() {
|
|
65015
|
-
const dir =
|
|
65016
|
-
|
|
65017
|
-
|
|
65215
|
+
const dir = join70(tmpdir10(), `open-agents-eval-${Date.now()}`);
|
|
65216
|
+
mkdirSync25(dir, { recursive: true });
|
|
65217
|
+
writeFileSync24(join70(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
|
|
65018
65218
|
return dir;
|
|
65019
65219
|
}
|
|
65020
65220
|
var BASIC_SUITE, FULL_SUITE, SUITES;
|
|
@@ -65074,7 +65274,7 @@ init_updater();
|
|
|
65074
65274
|
import { parseArgs as nodeParseArgs2 } from "node:util";
|
|
65075
65275
|
import { createRequire as createRequire3 } from "node:module";
|
|
65076
65276
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
65077
|
-
import { dirname as dirname21, join as
|
|
65277
|
+
import { dirname as dirname21, join as join71 } from "node:path";
|
|
65078
65278
|
|
|
65079
65279
|
// packages/cli/dist/cli.js
|
|
65080
65280
|
import { createInterface } from "node:readline";
|
|
@@ -65181,7 +65381,7 @@ init_output();
|
|
|
65181
65381
|
function getVersion4() {
|
|
65182
65382
|
try {
|
|
65183
65383
|
const require2 = createRequire3(import.meta.url);
|
|
65184
|
-
const pkgPath =
|
|
65384
|
+
const pkgPath = join71(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
|
|
65185
65385
|
const pkg = require2(pkgPath);
|
|
65186
65386
|
return pkg.version;
|
|
65187
65387
|
} catch {
|
|
@@ -65189,7 +65389,7 @@ function getVersion4() {
|
|
|
65189
65389
|
}
|
|
65190
65390
|
}
|
|
65191
65391
|
function routeCommand(command) {
|
|
65192
|
-
const valid = /* @__PURE__ */ new Set(["run", "index", "status", "config", "serve", "eval"]);
|
|
65392
|
+
const valid = /* @__PURE__ */ new Set(["run", "index", "status", "config", "serve", "eval", "jobs"]);
|
|
65193
65393
|
return valid.has(command) ? command : "unknown";
|
|
65194
65394
|
}
|
|
65195
65395
|
function parseCliArgs(argv) {
|
|
@@ -65209,6 +65409,8 @@ function parseCliArgs(argv) {
|
|
|
65209
65409
|
local: { type: "boolean", short: "l" },
|
|
65210
65410
|
port: { type: "string" },
|
|
65211
65411
|
suite: { type: "string" },
|
|
65412
|
+
json: { type: "boolean", short: "j" },
|
|
65413
|
+
background: { type: "boolean" },
|
|
65212
65414
|
help: { type: "boolean", short: "h" },
|
|
65213
65415
|
version: { type: "boolean", short: "V" }
|
|
65214
65416
|
},
|
|
@@ -65229,6 +65431,8 @@ function parseCliArgs(argv) {
|
|
|
65229
65431
|
timeoutMs: typeof values["timeout-ms"] === "string" ? parseInt(values["timeout-ms"], 10) : void 0,
|
|
65230
65432
|
offline: values.offline === true,
|
|
65231
65433
|
local: values.local === true,
|
|
65434
|
+
json: values.json === true,
|
|
65435
|
+
background: values.background === true,
|
|
65232
65436
|
help: values.help === true,
|
|
65233
65437
|
version: values.version === true
|
|
65234
65438
|
};
|
|
@@ -65259,6 +65463,9 @@ function parseCliArgs(argv) {
|
|
|
65259
65463
|
result.servePort = parseInt(values.port, 10);
|
|
65260
65464
|
}
|
|
65261
65465
|
break;
|
|
65466
|
+
case "status":
|
|
65467
|
+
result.task = rest[0];
|
|
65468
|
+
break;
|
|
65262
65469
|
case "eval":
|
|
65263
65470
|
result.evalSuite = typeof values.suite === "string" ? values.suite : void 0;
|
|
65264
65471
|
break;
|
|
@@ -65365,7 +65572,9 @@ async function main() {
|
|
|
65365
65572
|
verbose: parsed.verbose,
|
|
65366
65573
|
maxRetries: parsed.maxRetries,
|
|
65367
65574
|
timeoutMs: parsed.timeoutMs,
|
|
65368
|
-
offline: parsed.offline
|
|
65575
|
+
offline: parsed.offline,
|
|
65576
|
+
json: parsed.json,
|
|
65577
|
+
background: parsed.background
|
|
65369
65578
|
}, config);
|
|
65370
65579
|
break;
|
|
65371
65580
|
}
|
|
@@ -65378,8 +65587,18 @@ async function main() {
|
|
|
65378
65587
|
break;
|
|
65379
65588
|
}
|
|
65380
65589
|
case "status": {
|
|
65381
|
-
|
|
65382
|
-
|
|
65590
|
+
if (parsed.task && parsed.task.startsWith("job-")) {
|
|
65591
|
+
const { statusCommand: jobStatusCmd } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
65592
|
+
jobStatusCmd(parsed.task, parsed.repoPath);
|
|
65593
|
+
} else {
|
|
65594
|
+
const { statusCommand: statusCommand3 } = await Promise.resolve().then(() => (init_status(), status_exports));
|
|
65595
|
+
await statusCommand3({ verbose: parsed.verbose }, config);
|
|
65596
|
+
}
|
|
65597
|
+
break;
|
|
65598
|
+
}
|
|
65599
|
+
case "jobs": {
|
|
65600
|
+
const { jobsCommand: jobsCommand2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
65601
|
+
jobsCommand2(parsed.repoPath);
|
|
65383
65602
|
break;
|
|
65384
65603
|
}
|
|
65385
65604
|
case "config": {
|