diff --git a/scripts/openclaw-cross-os-release-checks.ts b/scripts/openclaw-cross-os-release-checks.ts index b5352a459ec..1ead13c0bcc 100644 --- a/scripts/openclaw-cross-os-release-checks.ts +++ b/scripts/openclaw-cross-os-release-checks.ts @@ -1759,8 +1759,7 @@ async function runInstalledAgentTurn(params) { logPath: params.logPath, timeoutMs: 10 * 60 * 1000, }); - const payloadTexts = parseAgentPayloadTexts(result.stdout); - if (!payloadTexts.some((text) => text.trim() === "OK")) { + if (!agentOutputHasExpectedOkMarker(result.stdout, { logPath: params.logPath })) { throw new Error("Agent output did not contain the expected OK marker."); } return result; @@ -2405,13 +2404,28 @@ async function runAgentTurn(params) { logPath: params.logPath, timeoutMs: 10 * 60 * 1000, }); - const payloadTexts = parseAgentPayloadTexts(result.stdout); - if (!payloadTexts.some((text) => text.trim() === "OK")) { + if (!agentOutputHasExpectedOkMarker(result.stdout, { logPath: params.logPath })) { throw new Error("Agent output did not contain the expected OK marker."); } return result; } +export function agentOutputHasExpectedOkMarker(stdout, options = {}) { + const payloadTexts = parseAgentPayloadTexts(stdout); + if (payloadTexts.some((text) => text.trim() === "OK")) { + return true; + } + if (typeof options.logPath !== "string") { + return false; + } + try { + const logTexts = parseAgentPayloadTexts(readFileSync(options.logPath, "utf8")); + return logTexts.some((text) => text.trim() === "OK"); + } catch { + return false; + } +} + function parseAgentPayloadTexts(stdout) { try { const payload = JSON.parse(stdout); diff --git a/test/scripts/openclaw-cross-os-release-checks.test.ts b/test/scripts/openclaw-cross-os-release-checks.test.ts index bdeea169169..2fb0c6c5c68 100644 --- a/test/scripts/openclaw-cross-os-release-checks.test.ts +++ b/test/scripts/openclaw-cross-os-release-checks.test.ts @@ -5,6 +5,7 @@ import { join } from "node:path"; import { setTimeout as delay } from "node:timers/promises"; import { describe, expect, it } from "vitest"; import { + agentOutputHasExpectedOkMarker, buildWindowsDevUpdateToolchainCheckScript, buildWindowsFreshShellVersionCheckScript, buildWindowsPathBootstrapScript, @@ -37,6 +38,27 @@ import { } from "../../scripts/openclaw-cross-os-release-checks.ts"; describe("scripts/openclaw-cross-os-release-checks", () => { + it("accepts OK agent output from the captured log when stdout is empty", () => { + const dir = mkdtempSync(join(tmpdir(), "openclaw-cross-os-agent-output-")); + try { + const logPath = join(dir, "agent.log"); + writeFileSync( + logPath, + [ + "2026-04-24T15:00:00.000Z command stdout", + JSON.stringify({ + finalAssistantVisibleText: "OK", + payloads: [{ type: "text", text: "OK" }], + }), + ].join("\n"), + ); + + expect(agentOutputHasExpectedOkMarker("", { logPath })).toBe(true); + } finally { + rmSync(dir, { recursive: true, force: true }); + } + }); + it("treats explicit empty-string args as values instead of boolean flags", () => { expect(parseArgs(["--ubuntu-runner", "", "--mode", "both"])).toEqual({ "ubuntu-runner": "",