@pushpalsdev/cli 1.0.24 → 1.0.25
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/pushpals-cli.js +66 -1
- package/package.json +1 -1
- package/runtime/configs/default.toml +3 -3
- package/runtime/configs/local.example.toml +3 -3
- package/runtime/sandbox/configs/default.toml +3 -3
- package/runtime/sandbox/configs/local.example.toml +3 -3
- package/runtime/sandbox/packages/shared/src/config.ts +4 -1
package/dist/pushpals-cli.js
CHANGED
|
@@ -637,7 +637,7 @@ function loadPushPalsConfig(options = {}) {
|
|
|
637
637
|
workerpalOnlineTtlMs: Math.max(1000, asInt(parseIntEnv("REMOTEBUDDY_WORKERPAL_ONLINE_TTL_MS") ?? remoteNode.workerpal_online_ttl_ms, 15000)),
|
|
638
638
|
waitForWorkerpalMs: Math.max(0, asInt(parseIntEnv("REMOTEBUDDY_WAIT_FOR_WORKERPAL_MS") ?? remoteNode.wait_for_workerpal_ms, 15000)),
|
|
639
639
|
autoSpawnWorkerpals: parseBoolEnv("REMOTEBUDDY_AUTO_SPAWN_WORKERPALS") ?? asBoolean(remoteNode.auto_spawn_workerpals, true),
|
|
640
|
-
maxWorkerpals: Math.max(1, asInt(remoteNode.max_workerpals, 20)),
|
|
640
|
+
maxWorkerpals: Math.max(1, asInt(parseIntEnv("REMOTEBUDDY_MAX_WORKERPALS") ?? remoteNode.max_workerpals, 20)),
|
|
641
641
|
workerpalStartupTimeoutMs: Math.max(1000, asInt(parseIntEnv("REMOTEBUDDY_WORKERPAL_STARTUP_TIMEOUT_MS") ?? remoteNode.workerpal_startup_timeout_ms, 1e4)),
|
|
642
642
|
workerpalDocker: parseBoolEnv("REMOTEBUDDY_WORKERPAL_DOCKER") ?? asBoolean(remoteNode.workerpal_docker, true),
|
|
643
643
|
workerpalRequireDocker: parseBoolEnv("REMOTEBUDDY_WORKERPAL_REQUIRE_DOCKER") ?? asBoolean(remoteNode.workerpal_require_docker, true),
|
|
@@ -2430,10 +2430,54 @@ async function resolveWorkerpalDockerProbe(cwd, env, platform = process.platform
|
|
|
2430
2430
|
}
|
|
2431
2431
|
var WORKERPAL_SANDBOX_RUNTIME_TAG_LABEL = "pushpals.runtime_tag";
|
|
2432
2432
|
var WORKERPAL_SANDBOX_COMPONENT_LABEL = "pushpals.component=workerpals-sandbox";
|
|
2433
|
+
var WORKERPAL_WARM_COMPONENT_LABEL = "pushpals.component=workerpals-warm";
|
|
2433
2434
|
function resolveConfiguredDockerExecutable(env, platform = process.platform) {
|
|
2434
2435
|
const configured = String(env.PUSHPALS_DOCKER_BIN_ABSOLUTE ?? env.PUSHPALS_DOCKER_BIN ?? (platform === "win32" ? "docker.exe" : "docker")).trim();
|
|
2435
2436
|
return configured || (platform === "win32" ? "docker.exe" : "docker");
|
|
2436
2437
|
}
|
|
2438
|
+
async function cleanupLingeringWorkerpalWarmContainers(opts) {
|
|
2439
|
+
const runCommandWithEnvFn = opts.runCommandWithEnvFn ?? runCommandWithEnv;
|
|
2440
|
+
const dockerExecutable = resolveConfiguredDockerExecutable(opts.env, opts.platform ?? process.platform);
|
|
2441
|
+
const list = await runCommandWithEnvFn([
|
|
2442
|
+
dockerExecutable,
|
|
2443
|
+
"ps",
|
|
2444
|
+
"-aq",
|
|
2445
|
+
"--filter",
|
|
2446
|
+
`label=${WORKERPAL_WARM_COMPONENT_LABEL}`,
|
|
2447
|
+
"--filter",
|
|
2448
|
+
`label=pushpals.repo=${opts.repoRoot}`
|
|
2449
|
+
], opts.repoRoot, opts.env);
|
|
2450
|
+
if (!list.ok) {
|
|
2451
|
+
const detail = list.stderr || list.stdout || `exit ${list.exitCode}`;
|
|
2452
|
+
return {
|
|
2453
|
+
ok: false,
|
|
2454
|
+
detail: `failed to inspect lingering WorkerPal warm containers: ${detail}`,
|
|
2455
|
+
removed: 0
|
|
2456
|
+
};
|
|
2457
|
+
}
|
|
2458
|
+
const containerIds = list.stdout.split(/\s+/).map((value) => value.trim()).filter(Boolean);
|
|
2459
|
+
if (containerIds.length === 0) {
|
|
2460
|
+
return {
|
|
2461
|
+
ok: true,
|
|
2462
|
+
detail: "no lingering WorkerPal warm containers found",
|
|
2463
|
+
removed: 0
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
const remove = await runCommandWithEnvFn([dockerExecutable, "rm", "-f", ...containerIds], opts.repoRoot, opts.env);
|
|
2467
|
+
if (!remove.ok) {
|
|
2468
|
+
const detail = remove.stderr || remove.stdout || `exit ${remove.exitCode}`;
|
|
2469
|
+
return {
|
|
2470
|
+
ok: false,
|
|
2471
|
+
detail: `failed to remove lingering WorkerPal warm containers: ${detail}`,
|
|
2472
|
+
removed: 0
|
|
2473
|
+
};
|
|
2474
|
+
}
|
|
2475
|
+
return {
|
|
2476
|
+
ok: true,
|
|
2477
|
+
detail: `removed ${containerIds.length} lingering WorkerPal warm container(s)`,
|
|
2478
|
+
removed: containerIds.length
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2437
2481
|
async function inspectDockerImageRuntimeTag(dockerExecutable, imageName, cwd, env) {
|
|
2438
2482
|
const inspect = await runCommandWithEnv([
|
|
2439
2483
|
dockerExecutable,
|
|
@@ -3919,6 +3963,24 @@ async function main() {
|
|
|
3919
3963
|
let autoStartedServices = [];
|
|
3920
3964
|
let pushpalsLogPath;
|
|
3921
3965
|
let resolvedRuntimeTagForAutoStart = preparedRuntime.runtimeTag || parsed.runtimeTag || "";
|
|
3966
|
+
const cleanupWorkerpalWarmContainersIfNeeded = async (phase) => {
|
|
3967
|
+
if (workerpalDockerPrecheck.status === "failed")
|
|
3968
|
+
return;
|
|
3969
|
+
if (!config.remotebuddy.autoSpawnWorkerpals || !config.remotebuddy.workerpalDocker || !config.remotebuddy.workerpalRequireDocker) {
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
const cleanup = await cleanupLingeringWorkerpalWarmContainers({
|
|
3973
|
+
repoRoot,
|
|
3974
|
+
env: workerpalDockerPrecheck.env
|
|
3975
|
+
});
|
|
3976
|
+
if (!cleanup.ok) {
|
|
3977
|
+
console.warn(`[pushpals] WorkerPal warm-container cleanup warning (${phase}): ${cleanup.detail}`);
|
|
3978
|
+
return;
|
|
3979
|
+
}
|
|
3980
|
+
if (cleanup.removed > 0) {
|
|
3981
|
+
console.log(`[pushpals] ${cleanup.detail} (${phase}).`);
|
|
3982
|
+
}
|
|
3983
|
+
};
|
|
3922
3984
|
const stopAutoStartedServices = () => {
|
|
3923
3985
|
if (autoStartedServices.length === 0)
|
|
3924
3986
|
return;
|
|
@@ -3940,6 +4002,7 @@ async function main() {
|
|
|
3940
4002
|
console.warn(`[pushpals] ${shutdown.detail}`);
|
|
3941
4003
|
}
|
|
3942
4004
|
await stopRuntimeServicesGracefully(services);
|
|
4005
|
+
await cleanupWorkerpalWarmContainersIfNeeded("cli shutdown");
|
|
3943
4006
|
};
|
|
3944
4007
|
let serverHealthy = await probeServer(serverUrl);
|
|
3945
4008
|
const serverWasAlreadyHealthy = serverHealthy;
|
|
@@ -3968,6 +4031,7 @@ async function main() {
|
|
|
3968
4031
|
detail: `No connected RemoteBuddy session consumer found for session ${sessionId}`
|
|
3969
4032
|
};
|
|
3970
4033
|
if (!serverHealthy) {
|
|
4034
|
+
await cleanupWorkerpalWarmContainersIfNeeded("startup preflight");
|
|
3971
4035
|
if (!parsed.noAutoStart) {
|
|
3972
4036
|
try {
|
|
3973
4037
|
const startedRuntime = await autoStartRuntimeServices({
|
|
@@ -4264,6 +4328,7 @@ export {
|
|
|
4264
4328
|
ensureWorkerpalDockerImageReady,
|
|
4265
4329
|
downloadRuntimeAssetsFromSourceTag,
|
|
4266
4330
|
copyTrackedRepoPath,
|
|
4331
|
+
cleanupLingeringWorkerpalWarmContainers,
|
|
4267
4332
|
bundledMonitoringHubNeedsRefresh,
|
|
4268
4333
|
buildWorkerpalSandboxPaths,
|
|
4269
4334
|
buildServiceStopCommand,
|
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@ status_heartbeat_ms = 120000
|
|
|
40
40
|
workerpal_online_ttl_ms = 15000
|
|
41
41
|
wait_for_workerpal_ms = 15000
|
|
42
42
|
auto_spawn_workerpals = true
|
|
43
|
-
max_workerpals =
|
|
43
|
+
max_workerpals = 3
|
|
44
44
|
workerpal_startup_timeout_ms = 10000
|
|
45
45
|
workerpal_docker = true
|
|
46
46
|
workerpal_require_docker = true
|
|
@@ -143,8 +143,8 @@ docker_warm_max_attempts = 3
|
|
|
143
143
|
docker_warm_retry_backoff_ms = 2000
|
|
144
144
|
docker_job_max_attempts = 2
|
|
145
145
|
docker_job_retry_backoff_ms = 3000
|
|
146
|
-
docker_warm_memory_mb =
|
|
147
|
-
docker_warm_cpus =
|
|
146
|
+
docker_warm_memory_mb = 1024
|
|
147
|
+
docker_warm_cpus = 1
|
|
148
148
|
file_modifying_jobs = ["task.execute"]
|
|
149
149
|
output_max_chars = 196608
|
|
150
150
|
output_max_lines = 600
|
|
@@ -23,7 +23,7 @@ codex_timeout_ms = 120000
|
|
|
23
23
|
reasoning_effort = "high"
|
|
24
24
|
|
|
25
25
|
[remotebuddy]
|
|
26
|
-
max_workerpals =
|
|
26
|
+
max_workerpals = 3
|
|
27
27
|
crash_restart_enabled = true
|
|
28
28
|
crash_restart_max_restarts = 3
|
|
29
29
|
crash_restart_backoff_ms = 3000
|
|
@@ -59,8 +59,8 @@ openhands_stuck_guard_explore_limit = 18
|
|
|
59
59
|
openhands_stuck_guard_min_elapsed_ms = 180000
|
|
60
60
|
openhands_stuck_guard_broad_scan_limit = 2
|
|
61
61
|
openhands_stuck_guard_no_progress_max_ms = 300000
|
|
62
|
-
docker_warm_memory_mb =
|
|
63
|
-
docker_warm_cpus =
|
|
62
|
+
docker_warm_memory_mb = 1024
|
|
63
|
+
docker_warm_cpus = 1
|
|
64
64
|
file_modifying_jobs = ["task.execute"]
|
|
65
65
|
output_max_chars = 196608
|
|
66
66
|
output_max_lines = 600
|
|
@@ -40,7 +40,7 @@ status_heartbeat_ms = 120000
|
|
|
40
40
|
workerpal_online_ttl_ms = 15000
|
|
41
41
|
wait_for_workerpal_ms = 15000
|
|
42
42
|
auto_spawn_workerpals = true
|
|
43
|
-
max_workerpals =
|
|
43
|
+
max_workerpals = 3
|
|
44
44
|
workerpal_startup_timeout_ms = 10000
|
|
45
45
|
workerpal_docker = true
|
|
46
46
|
workerpal_require_docker = true
|
|
@@ -143,8 +143,8 @@ docker_warm_max_attempts = 3
|
|
|
143
143
|
docker_warm_retry_backoff_ms = 2000
|
|
144
144
|
docker_job_max_attempts = 2
|
|
145
145
|
docker_job_retry_backoff_ms = 3000
|
|
146
|
-
docker_warm_memory_mb =
|
|
147
|
-
docker_warm_cpus =
|
|
146
|
+
docker_warm_memory_mb = 1024
|
|
147
|
+
docker_warm_cpus = 1
|
|
148
148
|
file_modifying_jobs = ["task.execute"]
|
|
149
149
|
output_max_chars = 196608
|
|
150
150
|
output_max_lines = 600
|
|
@@ -23,7 +23,7 @@ codex_timeout_ms = 120000
|
|
|
23
23
|
reasoning_effort = "high"
|
|
24
24
|
|
|
25
25
|
[remotebuddy]
|
|
26
|
-
max_workerpals =
|
|
26
|
+
max_workerpals = 3
|
|
27
27
|
crash_restart_enabled = true
|
|
28
28
|
crash_restart_max_restarts = 3
|
|
29
29
|
crash_restart_backoff_ms = 3000
|
|
@@ -59,8 +59,8 @@ openhands_stuck_guard_explore_limit = 18
|
|
|
59
59
|
openhands_stuck_guard_min_elapsed_ms = 180000
|
|
60
60
|
openhands_stuck_guard_broad_scan_limit = 2
|
|
61
61
|
openhands_stuck_guard_no_progress_max_ms = 300000
|
|
62
|
-
docker_warm_memory_mb =
|
|
63
|
-
docker_warm_cpus =
|
|
62
|
+
docker_warm_memory_mb = 1024
|
|
63
|
+
docker_warm_cpus = 1
|
|
64
64
|
file_modifying_jobs = ["task.execute"]
|
|
65
65
|
output_max_chars = 196608
|
|
66
66
|
output_max_lines = 600
|
|
@@ -1508,7 +1508,10 @@ export function loadPushPalsConfig(options: LoadOptions = {}): PushPalsConfig {
|
|
|
1508
1508
|
asBoolean(remoteNode.auto_spawn_workerpals, true),
|
|
1509
1509
|
maxWorkerpals: Math.max(
|
|
1510
1510
|
1,
|
|
1511
|
-
asInt(
|
|
1511
|
+
asInt(
|
|
1512
|
+
parseIntEnv("REMOTEBUDDY_MAX_WORKERPALS") ?? remoteNode.max_workerpals,
|
|
1513
|
+
20,
|
|
1514
|
+
),
|
|
1512
1515
|
),
|
|
1513
1516
|
workerpalStartupTimeoutMs: Math.max(
|
|
1514
1517
|
1_000,
|