From d9506ff26ef3f7d1db83109bf8507dcc8387bcff Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 26 Aug 2026 21:42:56 -0700 Subject: [PATCH] fix(crabbox): restore cloud machine CPU and RAM (#130684) Preserve structured provider catalogs beyond the lifecycle log capture limit so the cloud machine picker shows CPU/RAM and all available classes again. Keep lifecycle output limits and machine selection unchanged. Fixes #130660. --- .../src/crabbox-worker-machine-options.ts | 11 ++--- .../src/crabbox-worker-provider.test.ts | 49 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/extensions/crabbox/src/crabbox-worker-machine-options.ts b/extensions/crabbox/src/crabbox-worker-machine-options.ts index 801d7d340cf1..5d76cd5ff8f9 100644 --- a/extensions/crabbox/src/crabbox-worker-machine-options.ts +++ b/extensions/crabbox/src/crabbox-worker-machine-options.ts @@ -1,7 +1,6 @@ import type { WorkerProvider } from "openclaw/plugin-sdk/plugin-entry"; import { asPositiveSafeInteger, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime"; import type { CrabboxCommandRunner } from "./crabbox-worker-command.js"; -import { runCrabboxCommand } from "./crabbox-worker-command.js"; import { type CrabboxMachineShape, listCrabboxMachineOptions, @@ -55,11 +54,11 @@ export function createCrabboxMachineOptionsResolver( const machineShapesByBinary = new Map>(); const loadMachineShapes = async (binary: string): Promise => { try { - const result = await runCrabboxCommand({ - action: "providers", - args: ["providers", "--json"], - binary, - runCommand: dependencies.runCommand, + // The full provider matrix exceeds the lifecycle command's 64 KiB log cap. + // Keep catalog JSON intact or every provider loses its machine shapes. + const result = await dependencies.runCommand([binary, "providers", "--json"], { + maxOutputBytes: 1024 * 1024, + killProcessTree: true, timeoutMs: CRABBOX_MACHINE_CATALOG_TIMEOUT_MS, }); if (result.termination !== "exit" || result.code !== 0) { diff --git a/extensions/crabbox/src/crabbox-worker-provider.test.ts b/extensions/crabbox/src/crabbox-worker-provider.test.ts index 5b3a7ac21816..841a8a45edc3 100644 --- a/extensions/crabbox/src/crabbox-worker-provider.test.ts +++ b/extensions/crabbox/src/crabbox-worker-provider.test.ts @@ -166,25 +166,34 @@ function hasLoneSurrogate(value: string): boolean { } describe("Crabbox worker provider", () => { - it("derives ordered machine classes and shapes while preserving configured defaults", async () => { + it("reads large machine catalogs while preserving shapes, order, and configured defaults", async () => { const calls: string[][] = []; - const provider = providerWithRunner(async (argv) => { + const provider = providerWithRunner(async (argv, options) => { calls.push(argv); - return commandResult({ - stdout: JSON.stringify([ - { - provider: "aws", - classes: [ - { class: "tiny", type: "c7a.2xlarge", vcpu: 8, memoryGb: 16 }, - { class: "small", type: "c7a.4xlarge", vcpu: 16, memoryGb: 32 }, - { class: "standard", type: "c7a.8xlarge", vcpu: 32, memoryGb: 64 }, - { class: "fast", type: "c7a.16xlarge", vcpu: 64, memoryGb: 128 }, - { class: "large", type: "c7a.24xlarge", vcpu: 96, memoryGb: 192 }, - { class: "beast", type: "c7a.48xlarge", vcpu: 192, memoryGb: 384 }, - ], - }, - ]), - }); + return processRuntime.runCommandWithTimeout( + [process.execPath, "-e", "process.stdin.pipe(process.stdout)"], + { + ...options, + input: JSON.stringify([ + { + provider: "unrelated", + classCatalog: { metadata: "x".repeat(65_536) }, + }, + { + provider: "aws", + classes: [ + { class: "tiny", type: "c7a.2xlarge", vcpu: 8, memoryGb: 16 }, + { class: "small", type: "c7a.4xlarge", vcpu: 16, memoryGb: 32 }, + { class: "standard", type: "c7a.8xlarge", vcpu: 32, memoryGb: 64 }, + { class: "fast", type: "c7a.16xlarge", vcpu: 64, memoryGb: 128 }, + { class: "large", type: "c7a.24xlarge", vcpu: 96, memoryGb: 192 }, + { class: "beast", type: "c7a.48xlarge", vcpu: 192, memoryGb: 384 }, + ], + }, + { provider: "machine0", classCatalog: { disposition: "unmapped", profiles: [] } }, + ]), + }, + ); }); expect(provider.supportedExecutionModes).toEqual(["worker-turn", "remote-exec"]); expect(await provider.listMachineOptions?.(PROFILE)).toEqual([ @@ -215,6 +224,12 @@ describe("Crabbox worker provider", () => { }, ]); await provider.listMachineOptions?.(PROFILE); + expect(await provider.listMachineOptions?.({ ...PROFILE, provider: "machine0" })).toEqual([ + { id: "standard", label: "Standard", default: true }, + { id: "fast", label: "Fast" }, + { id: "large", label: "Large" }, + { id: "beast", label: "Beast" }, + ]); expect(calls.filter((argv) => argv[1] === "providers")).toHaveLength(1); });