Files
openclaw/scripts/resolve-frozen-codex-live-suite.mjs
Dallin Romney ee51b35616 fix(release): support frozen Codex validation (#108343)
* fix(release): support frozen Codex validation

* fix(release): support frozen Codex validation

* fix(release): support frozen Codex validation

* fix(release): support frozen Codex validation
2026-07-15 10:05:02 -07:00

105 lines
3.4 KiB
JavaScript

#!/usr/bin/env node
import { appendFileSync, readFileSync } from "node:fs";
import path from "node:path";
const CODEX_SUITE_PREFIX = "live-codex-harness";
const GENERIC_CODEX_SUITE = "live-codex-harness-docker";
const GPT_56_SUITE_PREFIX = "live-codex-harness-gpt56-";
function requireEnv(name) {
const value = process.env[name]?.trim();
if (!value) {
throw new Error(`${name} is required`);
}
return value;
}
function appendLine(file, line) {
appendFileSync(file, `${line}\n`, "utf8");
}
function readFallbackModelIds(targetRoot) {
const catalogPath = path.join(targetRoot, "extensions/codex/provider-catalog.ts");
const source = readFileSync(catalogPath, "utf8");
const start = source.indexOf("export const FALLBACK_CODEX_MODELS = [");
const end = source.indexOf("] satisfies", start);
if (start < 0 || end < 0) {
throw new Error(`cannot read the frozen Codex fallback catalog from ${catalogPath}`);
}
return new Set(
[...source.slice(start, end).matchAll(/\bid:\s*["']([^"']+)["']/gu)].map((match) => match[1]),
);
}
function resolveFrozenCodexCompatibility({ suiteId, targetRoot }) {
const modelIds = readFallbackModelIds(targetRoot);
const hasSol = modelIds.has("gpt-5.6-sol");
const hasLuna = modelIds.has("gpt-5.6-luna");
if (hasSol !== hasLuna) {
throw new Error("frozen Codex GPT-5.6 capability marker is incomplete; refusing to guess");
}
const supportsGpt56Cohort = hasSol && hasLuna;
if (suiteId === GENERIC_CODEX_SUITE) {
const model = supportsGpt56Cohort
? "openai/gpt-5.6-luna"
: modelIds.has("gpt-5.5")
? "openai/gpt-5.5"
: modelIds.has("gpt-5.4-mini")
? "openai/gpt-5.4-mini"
: undefined;
if (!model) {
throw new Error("frozen Codex catalog has no supported generic live-harness model");
}
return { model, runLane: true };
}
if (suiteId.startsWith(GPT_56_SUITE_PREFIX)) {
return { runLane: supportsGpt56Cohort };
}
return { runLane: true };
}
function main() {
const outputFile = requireEnv("GITHUB_OUTPUT");
const suiteId = requireEnv("OPENCLAW_FROZEN_CODEX_SUITE_ID");
const selectedSha = requireEnv("OPENCLAW_SELECTED_SHA");
const workflowSha = requireEnv("OPENCLAW_WORKFLOW_SHA");
const isFrozenTarget = selectedSha !== workflowSha;
const omissionsAllowed = process.env.OPENCLAW_ALLOW_FROZEN_TARGET_SCENARIO_OMISSIONS === "1";
if (!suiteId.startsWith(CODEX_SUITE_PREFIX) || !isFrozenTarget || !omissionsAllowed) {
appendLine(outputFile, "run_lane=true");
return;
}
const result = resolveFrozenCodexCompatibility({
suiteId,
targetRoot: requireEnv("OPENCLAW_FROZEN_TARGET_ROOT"),
});
appendLine(outputFile, `run_lane=${result.runLane}`);
const summaryFile = requireEnv("GITHUB_STEP_SUMMARY");
if (result.model) {
appendLine(requireEnv("GITHUB_ENV"), `OPENCLAW_LIVE_CODEX_HARNESS_MODEL=${result.model}`);
appendLine(
summaryFile,
`Frozen Codex target \`${selectedSha}\`: \`${suiteId}\` uses \`${result.model}\`.`,
);
} else if (!result.runLane) {
appendLine(
summaryFile,
`Frozen Codex target \`${selectedSha}\`: omitted unsupported current-only suite \`${suiteId}\`.`,
);
console.log(`::notice::Omitting unsupported frozen-target Codex suite ${suiteId}`);
}
}
try {
main();
} catch (error) {
console.error(error instanceof Error ? error.message : String(error));
process.exitCode = 1;
}