open-agents-ai 0.187.312 → 0.187.314
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 +163 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -299357,27 +299357,97 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
|
|
|
299357
299357
|
};
|
|
299358
299358
|
if (sub === "menu") {
|
|
299359
299359
|
try {
|
|
299360
|
-
const r2 = await doFetch("/v1/scheduled");
|
|
299360
|
+
const r2 = await doFetch("/v1/scheduled/status");
|
|
299361
299361
|
const d2 = await r2.json();
|
|
299362
299362
|
const tasks = Array.isArray(d2.tasks) ? d2.tasks : [];
|
|
299363
299363
|
if (!tasks.length) {
|
|
299364
299364
|
renderInfo2("No scheduled tasks found.");
|
|
299365
299365
|
return "handled";
|
|
299366
299366
|
}
|
|
299367
|
-
const items = tasks.map((t2) =>
|
|
299368
|
-
|
|
299369
|
-
|
|
299370
|
-
|
|
299371
|
-
|
|
299367
|
+
const items = tasks.map((t2) => {
|
|
299368
|
+
const procInfo = t2.procs && t2.procs.length ? ` (${t2.procs.length} proc)` : "";
|
|
299369
|
+
const uptime2 = t2.procs && t2.procs[0]?.uptime_s ? ` • up ${Math.max(1, Math.round(t2.procs[0].uptime_s / 60))}m` : "";
|
|
299370
|
+
return {
|
|
299371
|
+
key: t2.id,
|
|
299372
|
+
label: `${t2.enabled ? "●" : "○"} ${t2.name || "(task)"} ${t2.schedule ? "[" + t2.schedule + "]" : ""}${procInfo}${uptime2}`,
|
|
299373
|
+
detail: `${t2.file}#${t2.index}`
|
|
299374
|
+
};
|
|
299375
|
+
});
|
|
299372
299376
|
items.push({ key: "__kill__", label: "Kill OA schedulers + active runs", detail: "Stop scheduler/nexus processes and terminate active OA runs" });
|
|
299373
299377
|
const result = await tuiSelect({
|
|
299374
299378
|
items,
|
|
299375
299379
|
title: "Scheduled Tasks",
|
|
299380
|
+
onAction: (item, action) => {
|
|
299381
|
+
if (item.key === "__kill__") return false;
|
|
299382
|
+
const task = tasks.find((t2) => t2.id === item.key);
|
|
299383
|
+
if (!task) return false;
|
|
299384
|
+
(async () => {
|
|
299385
|
+
const next = !task.enabled;
|
|
299386
|
+
const rr = await doFetch(`/v1/scheduled/${encodeURIComponent(task.id)}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ enabled: next }) });
|
|
299387
|
+
if (rr.ok) {
|
|
299388
|
+
task.enabled = next;
|
|
299389
|
+
try {
|
|
299390
|
+
const rs = await doFetch("/v1/scheduled/status");
|
|
299391
|
+
const ds = await rs.json();
|
|
299392
|
+
const t2 = (Array.isArray(ds.tasks) ? ds.tasks : []).find((x) => x.id === task.id);
|
|
299393
|
+
if (t2) task.procs = t2.procs;
|
|
299394
|
+
} catch {
|
|
299395
|
+
}
|
|
299396
|
+
const pi = task.procs && task.procs.length ? ` (${task.procs.length} proc)` : "";
|
|
299397
|
+
const up = task.procs && task.procs[0]?.uptime_s ? ` • up ${Math.max(1, Math.round(task.procs[0].uptime_s / 60))}m` : "";
|
|
299398
|
+
item.label = `${next ? "●" : "○"} ${task.name || "(task)"} ${task.schedule ? "[" + task.schedule + "]" : ""}${pi}${up}`;
|
|
299399
|
+
renderInfo2(`${next ? "Enabled" : "Disabled"} ${task.id}`);
|
|
299400
|
+
} else {
|
|
299401
|
+
renderWarning2(`Failed to toggle ${task.id}`);
|
|
299402
|
+
}
|
|
299403
|
+
})();
|
|
299404
|
+
return true;
|
|
299405
|
+
},
|
|
299406
|
+
onCustomKey: (item, key, { done }) => {
|
|
299407
|
+
if (item.key === "__kill__") return false;
|
|
299408
|
+
if (key.toLowerCase() !== "k") return false;
|
|
299409
|
+
const task = tasks.find((t2) => t2.id === item.key);
|
|
299410
|
+
if (!task) return true;
|
|
299411
|
+
(async () => {
|
|
299412
|
+
const dir = (task.file || "").split("/").slice(0, -1).join("/") || task.file;
|
|
299413
|
+
const resp = await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ pattern: dir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") }) });
|
|
299414
|
+
try {
|
|
299415
|
+
const j = await resp.json();
|
|
299416
|
+
const kb = Array.isArray(j.killed) ? j.killed.length : 0;
|
|
299417
|
+
const ka = Array.isArray(j.additionally) ? j.additionally.length : 0;
|
|
299418
|
+
renderInfo2(`Killed ${kb + ka} procs for selected task.`);
|
|
299419
|
+
const before = j.gpu_before?.[0];
|
|
299420
|
+
const after = j.gpu_after?.[0];
|
|
299421
|
+
if (before && after) renderInfo2(`GPU util: ${before.gpu_pct}% → ${after.gpu_pct}%`);
|
|
299422
|
+
} catch {
|
|
299423
|
+
}
|
|
299424
|
+
done();
|
|
299425
|
+
})();
|
|
299426
|
+
return true;
|
|
299427
|
+
},
|
|
299376
299428
|
onEnter: (item, { done }) => {
|
|
299377
299429
|
(async () => {
|
|
299378
299430
|
if (item.key === "__kill__") {
|
|
299379
|
-
await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({}) });
|
|
299380
|
-
|
|
299431
|
+
const resp = await doFetch("/v1/scheduled/kill", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({}) });
|
|
299432
|
+
try {
|
|
299433
|
+
const j = await resp.json();
|
|
299434
|
+
const kb = Array.isArray(j.killed) ? j.killed.length : 0;
|
|
299435
|
+
const ka = Array.isArray(j.additionally) ? j.additionally.length : 0;
|
|
299436
|
+
renderInfo2(`Killed ${kb + ka} processes (schedulers + active runs).`);
|
|
299437
|
+
const before = j.gpu_before?.[0];
|
|
299438
|
+
const after = j.gpu_after?.[0];
|
|
299439
|
+
if (before && after) {
|
|
299440
|
+
renderInfo2(`GPU util: ${before.gpu_pct}% → ${after.gpu_pct}%, VRAM: ${before.vram_used_gb}/${before.vram_total_gb} GB → ${after.vram_used_gb}/${after.vram_total_gb} GB`);
|
|
299441
|
+
}
|
|
299442
|
+
const rem = Array.isArray(j.procs_after) ? j.procs_after.length : 0;
|
|
299443
|
+
if (rem > 0) {
|
|
299444
|
+
renderWarning2(`Remaining matched processes: ${rem}`);
|
|
299445
|
+
} else {
|
|
299446
|
+
renderInfo2("No remaining matched processes.");
|
|
299447
|
+
}
|
|
299448
|
+
} catch {
|
|
299449
|
+
renderInfo2("Kill signal sent.");
|
|
299450
|
+
}
|
|
299381
299451
|
done();
|
|
299382
299452
|
return;
|
|
299383
299453
|
}
|
|
@@ -321792,9 +321862,24 @@ async function loadScheduled() {
|
|
|
321792
321862
|
|
|
321793
321863
|
(window as any).killScheduled = async function() {
|
|
321794
321864
|
try {
|
|
321795
|
-
await fetch('/v1/scheduled/kill', { method:'POST', headers: headers(), body: JSON.stringify({}) });
|
|
321796
|
-
|
|
321797
|
-
|
|
321865
|
+
const r = await fetch('/v1/scheduled/kill', { method:'POST', headers: headers(), body: JSON.stringify({}) });
|
|
321866
|
+
const j = await r.json();
|
|
321867
|
+
const kb = Array.isArray(j.killed) ? j.killed.length : 0;
|
|
321868
|
+
const ka = Array.isArray(j.additionally) ? j.additionally.length : 0;
|
|
321869
|
+
const before = j.gpu_before && j.gpu_before[0] ? j.gpu_before[0] : null;
|
|
321870
|
+
const after = j.gpu_after && j.gpu_after[0] ? j.gpu_after[0] : null;
|
|
321871
|
+
const rem = Array.isArray(j.procs_after) ? j.procs_after.length : 0;
|
|
321872
|
+
let msg = 'Killed ' + (kb + ka) + ' processes.';
|
|
321873
|
+
if (before && after) {
|
|
321874
|
+
msg += '
|
|
321875
|
+
GPU util: ' + before.gpu_pct + '% → ' + after.gpu_pct + '%, VRAM: ' + before.vram_used_gb + '/' + before.vram_total_gb + ' GB → ' + after.vram_used_gb + '/' + after.vram_total_gb + ' GB';
|
|
321876
|
+
}
|
|
321877
|
+
msg += rem > 0 ? ('
|
|
321878
|
+
Remaining matched processes: ' + rem) : '
|
|
321879
|
+
No remaining matched processes.';
|
|
321880
|
+
alert(msg);
|
|
321881
|
+
loadScheduled();
|
|
321882
|
+
} catch (e) { alert('Kill failed: ' + (e && e.message || String(e))); }
|
|
321798
321883
|
}
|
|
321799
321884
|
|
|
321800
321885
|
(window as any).disableAllScheduled = async function() {
|
|
@@ -327524,6 +327609,17 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
327524
327609
|
jsonResponse(res, 200, { tasks: listScheduledTasks() });
|
|
327525
327610
|
return;
|
|
327526
327611
|
}
|
|
327612
|
+
if (pathname === "/v1/scheduled/status" && method === "GET") {
|
|
327613
|
+
const tasks = listScheduledTasks();
|
|
327614
|
+
const enriched = tasks.map((t2) => {
|
|
327615
|
+
const dir = t2.file.split("/").slice(0, -1).join("/") || t2.file;
|
|
327616
|
+
const safe = dir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
327617
|
+
const procs = listMatchingProcesses(safe);
|
|
327618
|
+
return { ...t2, procs };
|
|
327619
|
+
});
|
|
327620
|
+
jsonResponse(res, 200, { tasks: enriched });
|
|
327621
|
+
return;
|
|
327622
|
+
}
|
|
327527
327623
|
if (pathname?.startsWith("/v1/scheduled/") && method === "POST") {
|
|
327528
327624
|
const parts = pathname.split("/");
|
|
327529
327625
|
const id = parts[3] ?? "";
|
|
@@ -327541,6 +327637,8 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
327541
327637
|
const body = await parseJsonBody(req2);
|
|
327542
327638
|
const pids = Array.isArray(body?.pids) ? body.pids.filter((n2) => Number.isInteger(n2)) : void 0;
|
|
327543
327639
|
const pattern = typeof body?.pattern === "string" && body.pattern.trim() ? body.pattern.trim() : "(/bin/oa|open-agents-ai|nexus-daemon|OPEN-AGENTS-SCHEDULED|ollama)";
|
|
327640
|
+
const procsBefore = listMatchingProcesses(pattern);
|
|
327641
|
+
const gpuBefore = sampleGpuUtil();
|
|
327544
327642
|
const killed = killScheduledProcesses(pids, pattern);
|
|
327545
327643
|
const additionally = [];
|
|
327546
327644
|
try {
|
|
@@ -327553,23 +327651,35 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
327553
327651
|
} catch {
|
|
327554
327652
|
additionally.push({ pid, ok: false, signal: "TERM", run_id: rid });
|
|
327555
327653
|
}
|
|
327556
|
-
|
|
327557
|
-
try {
|
|
327558
|
-
if (pid > 0) {
|
|
327654
|
+
try {
|
|
327559
327655
|
process.kill(pid, 0);
|
|
327560
327656
|
try {
|
|
327561
327657
|
process.kill(pid, "SIGKILL");
|
|
327562
327658
|
additionally.push({ pid, ok: true, signal: "KILL", run_id: rid });
|
|
327563
327659
|
} catch {
|
|
327564
327660
|
}
|
|
327661
|
+
} catch {
|
|
327565
327662
|
}
|
|
327566
|
-
} catch {
|
|
327567
327663
|
}
|
|
327568
327664
|
runningProcesses.delete(rid);
|
|
327569
327665
|
}
|
|
327570
327666
|
} catch {
|
|
327571
327667
|
}
|
|
327572
|
-
|
|
327668
|
+
try {
|
|
327669
|
+
await new Promise((r2) => setTimeout(r2, 600));
|
|
327670
|
+
} catch {
|
|
327671
|
+
}
|
|
327672
|
+
const procsAfter = listMatchingProcesses(pattern);
|
|
327673
|
+
const gpuAfter = sampleGpuUtil();
|
|
327674
|
+
jsonResponse(res, 200, {
|
|
327675
|
+
killed_count: killed.length + additionally.length,
|
|
327676
|
+
killed,
|
|
327677
|
+
additionally,
|
|
327678
|
+
procs_before: procsBefore,
|
|
327679
|
+
procs_after: procsAfter,
|
|
327680
|
+
gpu_before: gpuBefore,
|
|
327681
|
+
gpu_after: gpuAfter
|
|
327682
|
+
});
|
|
327573
327683
|
return;
|
|
327574
327684
|
}
|
|
327575
327685
|
if ((pathname === "/v1/chat" || pathname === "/api/chat") && method === "POST") {
|
|
@@ -328577,6 +328687,43 @@ function killScheduledProcesses(pids, pattern) {
|
|
|
328577
328687
|
}
|
|
328578
328688
|
return killed;
|
|
328579
328689
|
}
|
|
328690
|
+
function listMatchingProcesses(pattern) {
|
|
328691
|
+
const list = [];
|
|
328692
|
+
try {
|
|
328693
|
+
const { execSync: es } = __require("node:child_process");
|
|
328694
|
+
const re = new RegExp(pattern, "i");
|
|
328695
|
+
const ps = es("ps -eo pid,pcpu,pmem,command", { encoding: "utf8", stdio: "pipe" });
|
|
328696
|
+
for (const line of ps.split("\n")) {
|
|
328697
|
+
const m2 = line.trim().match(/^(\d+)\s+([0-9.]+)?\s+([0-9.]+)?\s+(.+)$/);
|
|
328698
|
+
if (!m2) continue;
|
|
328699
|
+
const pid = parseInt(m2[1], 10);
|
|
328700
|
+
const cpu = m2[2] ? parseFloat(m2[2]) : null;
|
|
328701
|
+
const mem = m2[3] ? parseFloat(m2[3]) : null;
|
|
328702
|
+
const cmd = m2[4] || "";
|
|
328703
|
+
if (!isFinite(pid)) continue;
|
|
328704
|
+
if (re.test(cmd)) list.push({ pid, cpu, mem, cmd });
|
|
328705
|
+
}
|
|
328706
|
+
} catch {
|
|
328707
|
+
}
|
|
328708
|
+
return list;
|
|
328709
|
+
}
|
|
328710
|
+
function sampleGpuUtil() {
|
|
328711
|
+
try {
|
|
328712
|
+
const { execSync: es } = __require("node:child_process");
|
|
328713
|
+
const out = es("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total --format=csv,noheader,nounits", { encoding: "utf8", timeout: 3e3, stdio: "pipe" });
|
|
328714
|
+
const arr = [];
|
|
328715
|
+
for (const line of out.trim().split("\n")) {
|
|
328716
|
+
const [pctS, usedS, totalS] = line.split(",").map((s2) => s2.trim());
|
|
328717
|
+
const pct = parseInt(pctS, 10);
|
|
328718
|
+
const usedGb = Math.round(parseInt(usedS, 10) / 1024 * 10) / 10;
|
|
328719
|
+
const totalGb = Math.round(parseInt(totalS, 10) / 1024);
|
|
328720
|
+
if (!isNaN(pct) && !isNaN(usedGb) && !isNaN(totalGb)) arr.push({ gpu_pct: pct, vram_used_gb: usedGb, vram_total_gb: totalGb });
|
|
328721
|
+
}
|
|
328722
|
+
return arr;
|
|
328723
|
+
} catch {
|
|
328724
|
+
return null;
|
|
328725
|
+
}
|
|
328726
|
+
}
|
|
328580
328727
|
function startApiServer(options2 = {}) {
|
|
328581
328728
|
if (options2.quiet) setQuiet(true);
|
|
328582
328729
|
const log22 = options2.quiet ? (_msg) => {
|
package/package.json
CHANGED