





















@@ -4,7 +4,7 @@ import os from "node:os";
44import path from "node:path";
55import process from "node:process";
66import { setTimeout as delay } from "node:timers/promises";
7-import { pathToFileURL } from "node:url";
7+import { fileURLToPath, pathToFileURL } from "node:url";
8899const PLUGIN_SPEC =
1010process.env.OPENCLAW_KITCHEN_SINK_NPM_SPEC || "npm:@openclaw/kitchen-sink@latest";
@@ -517,12 +517,21 @@ function assertToolInvokeResult(payload) {
517517}
518518}
519519520-async function sampleProcess(pid) {
521-if (!pid || process.platform === "win32") {
520+export async function sampleProcess(pid, options = {}) {
521+const platform = options.platform ?? process.platform;
522+const run = options.runCommand ?? runCommand;
523+if (!pid) {
522524return null;
523525}
526+if (platform === "win32") {
527+return sampleWindowsProcess(pid, run);
528+}
529+return samplePosixProcess(pid, run);
530+}
531+532+async function samplePosixProcess(pid, run) {
524533try {
525-const { stdout } = await runCommand("ps", ["-o", "rss=,pcpu=", "-p", String(pid)], {
534+const { stdout } = await run("ps", ["-o", "rss=,pcpu=", "-p", String(pid)], {
526535timeoutMs: 5000,
527536});
528537const [rssKbRaw, cpuRaw] = stdout.trim().split(/\s+/u);
@@ -540,7 +549,44 @@ async function sampleProcess(pid) {
540549}
541550}
542551543-function assertResourceCeiling(sample) {
552+async function sampleWindowsProcess(pid, run) {
553+const safePid = Number(pid);
554+if (!Number.isInteger(safePid) || safePid <= 0) {
555+return null;
556+}
557+const command = [
558+"$ErrorActionPreference = 'Stop'",
559+`$process = Get-Process -Id ${safePid} -ErrorAction Stop`,
560+"$cpu = 0",
561+"if ($null -ne $process.CPU) { $cpu = $process.CPU }",
562+"[Console]::Out.Write(('{0} {1}' -f $process.WorkingSet64, $cpu))",
563+].join("; ");
564+for (const powershell of ["powershell.exe", "powershell"]) {
565+try {
566+const { stdout } = await run(
567+powershell,
568+["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", command],
569+{ timeoutMs: 5000 },
570+);
571+const [workingSetBytesRaw, cpuSecondsRaw] = stdout.trim().split(/\s+/u);
572+const workingSetBytes = Number.parseInt(workingSetBytesRaw ?? "", 10);
573+const cpuSeconds = Number.parseFloat(cpuSecondsRaw ?? "");
574+if (!Number.isFinite(workingSetBytes)) {
575+return null;
576+}
577+return {
578+rssMiB: Math.round((workingSetBytes / 1024 / 1024) * 10) / 10,
579+cpuPercent: null,
580+cpuSeconds: Number.isFinite(cpuSeconds) ? cpuSeconds : null,
581+};
582+} catch {
583+// Try the next Windows PowerShell command name.
584+}
585+}
586+return null;
587+}
588+589+export function assertResourceCeiling(sample) {
544590if (!sample) {
545591return;
546592}
@@ -590,7 +636,7 @@ function isNonEmptyString(value) {
590636return typeof value === "string" && value.trim().length > 0;
591637}
592638593-async function main() {
639+export async function main() {
594640const runner = resolveOpenClawRunner();
595641const port = readPositiveInt(process.env.OPENCLAW_KITCHEN_SINK_RPC_PORT, DEFAULT_PORT);
596642const { root, env } = makeEnv();
@@ -725,4 +771,6 @@ async function main() {
725771}
726772}
727773728-await main();
774+if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
775+await main();
776+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。