openclaw-aegis 1.2.0 → 1.2.1
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/cli/index.js +79 -49
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +78 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -465,7 +465,7 @@ async function httpHealthProbe(target, port, endpoint = "/health", timeoutMs = 5
|
|
|
465
465
|
// src/health/probes/config.ts
|
|
466
466
|
var fs3 = __toESM(require("fs"));
|
|
467
467
|
var REQUIRED_CONFIG_PATHS = [
|
|
468
|
-
{ path: ["gateway", "port"], label: "gateway.port" }
|
|
468
|
+
{ path: [["gateway", "port"], ["port"]], label: "gateway.port" }
|
|
469
469
|
];
|
|
470
470
|
var POISON_KEYS = ["autoAck", "autoAckMessage"];
|
|
471
471
|
async function configProbe(_target, configPath) {
|
|
@@ -493,13 +493,15 @@ async function configProbe(_target, configPath) {
|
|
|
493
493
|
latencyMs: Date.now() - start
|
|
494
494
|
};
|
|
495
495
|
}
|
|
496
|
-
const missingPaths = REQUIRED_CONFIG_PATHS.filter(({ path:
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
496
|
+
const missingPaths = REQUIRED_CONFIG_PATHS.filter(({ path: alternatives }) => {
|
|
497
|
+
return !alternatives.some((keyPath) => {
|
|
498
|
+
let obj = parsed;
|
|
499
|
+
for (const key of keyPath) {
|
|
500
|
+
if (obj === null || typeof obj !== "object" || !(key in obj)) return false;
|
|
501
|
+
obj = obj[key];
|
|
502
|
+
}
|
|
503
|
+
return true;
|
|
504
|
+
});
|
|
503
505
|
});
|
|
504
506
|
if (missingPaths.length > 0) {
|
|
505
507
|
return {
|
|
@@ -594,6 +596,26 @@ async function tunProbe(_target) {
|
|
|
594
596
|
|
|
595
597
|
// src/health/probes/memory.ts
|
|
596
598
|
var fs5 = __toESM(require("fs"));
|
|
599
|
+
var os3 = __toESM(require("os"));
|
|
600
|
+
var import_node_child_process3 = require("child_process");
|
|
601
|
+
function getRssMb(pid) {
|
|
602
|
+
if (os3.platform() !== "darwin") {
|
|
603
|
+
const statusPath = `/proc/${pid}/status`;
|
|
604
|
+
if (!fs5.existsSync(statusPath)) return null;
|
|
605
|
+
const status = fs5.readFileSync(statusPath, "utf-8");
|
|
606
|
+
const rssMatch = status.match(/VmRSS:\s+(\d+)\s+kB/);
|
|
607
|
+
if (!rssMatch) return null;
|
|
608
|
+
return parseInt(rssMatch[1] ?? "0", 10) / 1024;
|
|
609
|
+
}
|
|
610
|
+
try {
|
|
611
|
+
const output = (0, import_node_child_process3.execSync)(`ps -o rss= -p ${pid}`, { encoding: "utf-8" }).trim();
|
|
612
|
+
const rssKb = parseInt(output, 10);
|
|
613
|
+
if (isNaN(rssKb)) return null;
|
|
614
|
+
return rssKb / 1024;
|
|
615
|
+
} catch {
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
597
619
|
async function memoryProbe(_target, pidSource, thresholdMb = 512) {
|
|
598
620
|
const start = Date.now();
|
|
599
621
|
try {
|
|
@@ -607,29 +629,16 @@ async function memoryProbe(_target, pidSource, thresholdMb = 512) {
|
|
|
607
629
|
latencyMs: Date.now() - start
|
|
608
630
|
};
|
|
609
631
|
}
|
|
610
|
-
const
|
|
611
|
-
if (
|
|
632
|
+
const rssMb = getRssMb(pid);
|
|
633
|
+
if (rssMb === null) {
|
|
612
634
|
return {
|
|
613
635
|
name: "memory",
|
|
614
636
|
healthy: false,
|
|
615
637
|
score: 0,
|
|
616
|
-
message: `
|
|
638
|
+
message: `Could not read memory for process ${pid}`,
|
|
617
639
|
latencyMs: Date.now() - start
|
|
618
640
|
};
|
|
619
641
|
}
|
|
620
|
-
const status = fs5.readFileSync(statusPath, "utf-8");
|
|
621
|
-
const rssMatch = status.match(/VmRSS:\s+(\d+)\s+kB/);
|
|
622
|
-
if (!rssMatch) {
|
|
623
|
-
return {
|
|
624
|
-
name: "memory",
|
|
625
|
-
healthy: true,
|
|
626
|
-
score: 1,
|
|
627
|
-
message: "Could not parse RSS from /proc status",
|
|
628
|
-
latencyMs: Date.now() - start
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
const rssKb = parseInt(rssMatch[1] ?? "0", 10);
|
|
632
|
-
const rssMb = rssKb / 1024;
|
|
633
642
|
const healthy = rssMb < thresholdMb;
|
|
634
643
|
return {
|
|
635
644
|
name: "memory",
|
|
@@ -651,6 +660,35 @@ async function memoryProbe(_target, pidSource, thresholdMb = 512) {
|
|
|
651
660
|
|
|
652
661
|
// src/health/probes/cpu.ts
|
|
653
662
|
var fs6 = __toESM(require("fs"));
|
|
663
|
+
var os4 = __toESM(require("os"));
|
|
664
|
+
var import_node_child_process4 = require("child_process");
|
|
665
|
+
async function getCpuPercentLinux(pid, sampleMs) {
|
|
666
|
+
const statPath = `/proc/${pid}/stat`;
|
|
667
|
+
if (!fs6.existsSync(statPath)) return null;
|
|
668
|
+
const readCpuTime = () => {
|
|
669
|
+
const stat = fs6.readFileSync(statPath, "utf-8");
|
|
670
|
+
const fields = stat.split(" ");
|
|
671
|
+
const utime = parseInt(fields[13] ?? "0", 10) || 0;
|
|
672
|
+
const stime = parseInt(fields[14] ?? "0", 10) || 0;
|
|
673
|
+
return utime + stime;
|
|
674
|
+
};
|
|
675
|
+
const cpuTime1 = readCpuTime();
|
|
676
|
+
await new Promise((r) => setTimeout(r, sampleMs));
|
|
677
|
+
const cpuTime2 = readCpuTime();
|
|
678
|
+
const clockTicks = 100;
|
|
679
|
+
const cpuDelta = (cpuTime2 - cpuTime1) / clockTicks;
|
|
680
|
+
return cpuDelta / (sampleMs / 1e3) * 100;
|
|
681
|
+
}
|
|
682
|
+
function getCpuPercentMac(pid) {
|
|
683
|
+
try {
|
|
684
|
+
const output = (0, import_node_child_process4.execSync)(`ps -o %cpu= -p ${pid}`, { encoding: "utf-8" }).trim();
|
|
685
|
+
const cpu = parseFloat(output);
|
|
686
|
+
if (isNaN(cpu)) return null;
|
|
687
|
+
return cpu;
|
|
688
|
+
} catch {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
654
692
|
async function cpuProbe(_target, pidSource, thresholdPercent = 90, sampleMs = 1e3) {
|
|
655
693
|
const start = Date.now();
|
|
656
694
|
try {
|
|
@@ -664,29 +702,21 @@ async function cpuProbe(_target, pidSource, thresholdPercent = 90, sampleMs = 1e
|
|
|
664
702
|
latencyMs: Date.now() - start
|
|
665
703
|
};
|
|
666
704
|
}
|
|
667
|
-
|
|
668
|
-
if (
|
|
705
|
+
let cpuPercent;
|
|
706
|
+
if (os4.platform() === "darwin") {
|
|
707
|
+
cpuPercent = getCpuPercentMac(pid);
|
|
708
|
+
} else {
|
|
709
|
+
cpuPercent = await getCpuPercentLinux(pid, sampleMs);
|
|
710
|
+
}
|
|
711
|
+
if (cpuPercent === null) {
|
|
669
712
|
return {
|
|
670
713
|
name: "cpu",
|
|
671
714
|
healthy: false,
|
|
672
715
|
score: 0,
|
|
673
|
-
message: `
|
|
716
|
+
message: `Could not read CPU usage for process ${pid}`,
|
|
674
717
|
latencyMs: Date.now() - start
|
|
675
718
|
};
|
|
676
719
|
}
|
|
677
|
-
const readCpuTime = () => {
|
|
678
|
-
const stat = fs6.readFileSync(statPath, "utf-8");
|
|
679
|
-
const fields = stat.split(" ");
|
|
680
|
-
const utime = parseInt(fields[13] ?? "0", 10) || 0;
|
|
681
|
-
const stime = parseInt(fields[14] ?? "0", 10) || 0;
|
|
682
|
-
return utime + stime;
|
|
683
|
-
};
|
|
684
|
-
const cpuTime1 = readCpuTime();
|
|
685
|
-
await new Promise((r) => setTimeout(r, sampleMs));
|
|
686
|
-
const cpuTime2 = readCpuTime();
|
|
687
|
-
const clockTicks = 100;
|
|
688
|
-
const cpuDelta = (cpuTime2 - cpuTime1) / clockTicks;
|
|
689
|
-
const cpuPercent = cpuDelta / (sampleMs / 1e3) * 100;
|
|
690
720
|
const healthy = cpuPercent < thresholdPercent;
|
|
691
721
|
return {
|
|
692
722
|
name: "cpu",
|
|
@@ -707,10 +737,10 @@ async function cpuProbe(_target, pidSource, thresholdPercent = 90, sampleMs = 1e
|
|
|
707
737
|
}
|
|
708
738
|
|
|
709
739
|
// src/health/probes/disk.ts
|
|
710
|
-
var
|
|
740
|
+
var import_node_child_process5 = require("child_process");
|
|
711
741
|
var import_node_util2 = require("util");
|
|
712
742
|
var path2 = __toESM(require("path"));
|
|
713
|
-
var execFileAsync2 = (0, import_node_util2.promisify)(
|
|
743
|
+
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process5.execFile);
|
|
714
744
|
async function diskProbe(_target, configPath, thresholdMb = 100) {
|
|
715
745
|
const start = Date.now();
|
|
716
746
|
try {
|
|
@@ -1048,7 +1078,7 @@ var checkCommand = new import_commander2.Command("check").description("Run all h
|
|
|
1048
1078
|
// src/cli/commands/init.ts
|
|
1049
1079
|
var import_commander3 = require("commander");
|
|
1050
1080
|
var fs8 = __toESM(require("fs"));
|
|
1051
|
-
var
|
|
1081
|
+
var os5 = __toESM(require("os"));
|
|
1052
1082
|
var readline = __toESM(require("readline"));
|
|
1053
1083
|
function ask(rl, question, defaultValue) {
|
|
1054
1084
|
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
@@ -1071,19 +1101,19 @@ function detectPort() {
|
|
|
1071
1101
|
return 3e3;
|
|
1072
1102
|
}
|
|
1073
1103
|
function detectPlatform() {
|
|
1074
|
-
if (
|
|
1104
|
+
if (os5.platform() === "darwin") {
|
|
1075
1105
|
return { type: "launchd", pidFile: "ai.openclaw.gateway" };
|
|
1076
1106
|
}
|
|
1077
1107
|
return { type: "systemd", pidFile: "openclaw-gateway.service" };
|
|
1078
1108
|
}
|
|
1079
1109
|
function generateToml(opts) {
|
|
1080
|
-
const
|
|
1110
|
+
const platform5 = detectPlatform();
|
|
1081
1111
|
let toml = `# OpenClaw Aegis Configuration
|
|
1082
1112
|
# Generated by 'aegis init'
|
|
1083
1113
|
|
|
1084
1114
|
[gateway]
|
|
1085
1115
|
configPath = "~/.openclaw/openclaw.json"
|
|
1086
|
-
pidFile = "${
|
|
1116
|
+
pidFile = "${platform5.pidFile}"
|
|
1087
1117
|
port = ${opts.port}
|
|
1088
1118
|
logPath = "~/.openclaw/logs/gateway.log"
|
|
1089
1119
|
healthEndpoint = "/health"
|
|
@@ -1110,7 +1140,7 @@ enabled = true
|
|
|
1110
1140
|
countdownMs = 30000
|
|
1111
1141
|
|
|
1112
1142
|
[platform]
|
|
1113
|
-
type = "${
|
|
1143
|
+
type = "${platform5.type}"
|
|
1114
1144
|
`;
|
|
1115
1145
|
if (opts.channels.length > 0) {
|
|
1116
1146
|
toml += "\n[alerts]\n";
|
|
@@ -1145,9 +1175,9 @@ var initCommand = new import_commander3.Command("init").description("Interactive
|
|
|
1145
1175
|
const channels = [];
|
|
1146
1176
|
if (opts.auto) {
|
|
1147
1177
|
console.log("Auto-detecting configuration...");
|
|
1148
|
-
const
|
|
1178
|
+
const platform5 = detectPlatform();
|
|
1149
1179
|
console.log(` Gateway port: ${detectedPort}`);
|
|
1150
|
-
console.log(` PID source: ${
|
|
1180
|
+
console.log(` PID source: ${platform5.pidFile} (${platform5.type})`);
|
|
1151
1181
|
console.log(` Memory threshold: 768MB`);
|
|
1152
1182
|
} else {
|
|
1153
1183
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|