mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-22 13:18:09 +00:00
fix(e2e): repair omitted Codex platform package
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
parseProvider,
|
||||
readPositiveIntEnv,
|
||||
modelProviderConfigBatchJson,
|
||||
posixCodexPlatformPackageRepairFunction,
|
||||
posixProviderOnlyPluginIsolationScript,
|
||||
repoRoot,
|
||||
resolveParallelsModelTimeoutSeconds,
|
||||
@@ -741,7 +742,8 @@ rm -f "$provider_config_batch"`);
|
||||
this.restrictAgentTurnPlugins();
|
||||
this.prepareAgentWorkspace();
|
||||
this.guestBash(
|
||||
`agent_ok=false
|
||||
`${posixCodexPlatformPackageRepairFunction()}
|
||||
agent_ok=false
|
||||
for attempt in 1 2; do
|
||||
session_id="parallels-linux-smoke"
|
||||
if [ "$attempt" -gt 1 ]; then session_id="parallels-linux-smoke-retry-$attempt"; fi
|
||||
@@ -755,6 +757,11 @@ for attempt in 1 2; do
|
||||
set -e
|
||||
cat "$output_file"
|
||||
if [ "$rc" -ne 0 ]; then
|
||||
if [ "$attempt" -lt 2 ] && repair_missing_codex_platform_package "$output_file"; then
|
||||
rm -f "$output_file"
|
||||
echo "agent turn attempt $attempt hit a missing Codex platform package; retrying"
|
||||
continue
|
||||
fi
|
||||
rm -f "$output_file"
|
||||
exit "$rc"
|
||||
fi
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
parseMode,
|
||||
parseProvider,
|
||||
modelProviderConfigBatchJson,
|
||||
posixCodexPlatformPackageRepairFunction,
|
||||
posixProviderOnlyPluginIsolationScript,
|
||||
parsePositiveInt,
|
||||
readPositiveIntEnv,
|
||||
@@ -1108,6 +1109,7 @@ rm -f "$provider_config_batch"`);
|
||||
this.restrictAgentTurnPlugins();
|
||||
this.guestSh(
|
||||
`${posixAgentWorkspaceScript("Parallels macOS smoke test assistant.")}
|
||||
${posixCodexPlatformPackageRepairFunction()}
|
||||
agent_ok=false
|
||||
for attempt in 1 2; do
|
||||
session_id="parallels-macos-smoke"
|
||||
@@ -1122,6 +1124,11 @@ for attempt in 1 2; do
|
||||
set -e
|
||||
cat "$output_file"
|
||||
if [ "$rc" -ne 0 ]; then
|
||||
if [ "$attempt" -lt 2 ] && repair_missing_codex_platform_package "$output_file"; then
|
||||
rm -f "$output_file"
|
||||
echo "agent turn attempt $attempt hit a missing Codex platform package; retrying"
|
||||
continue
|
||||
fi
|
||||
rm -f "$output_file"
|
||||
exit "$rc"
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
// Npm Update Scripts script supports OpenClaw repository automation.
|
||||
import { posixAgentWorkspaceScript, windowsAgentWorkspaceScript } from "./agent-workspace.ts";
|
||||
import { shellQuote } from "./host-command.ts";
|
||||
import { posixProviderOnlyPluginIsolationScript } from "./plugin-isolation.ts";
|
||||
import {
|
||||
posixCodexPlatformPackageRepairFunction,
|
||||
posixProviderOnlyPluginIsolationScript,
|
||||
windowsCodexPlatformPackageRepairFunction,
|
||||
} from "./plugin-isolation.ts";
|
||||
import {
|
||||
psSingleQuote,
|
||||
windowsAgentTurnConfigPatchScript,
|
||||
@@ -72,6 +76,7 @@ function posixAssertAgentOkScript(command: string, input: NpmUpdateScriptInput,
|
||||
fallbackPluginId: input.auth.modelId.split("/", 1)[0] || "openai",
|
||||
modelId: input.auth.modelId,
|
||||
})}
|
||||
${posixCodexPlatformPackageRepairFunction()}
|
||||
agent_ok=false
|
||||
for attempt in 1 2; do
|
||||
session_id=${shellQuote(sessionId)}
|
||||
@@ -84,6 +89,11 @@ for attempt in 1 2; do
|
||||
set -e
|
||||
print_log_tail "$output_file"
|
||||
if [ "$rc" -ne 0 ]; then
|
||||
if [ "$attempt" -lt 2 ] && repair_missing_codex_platform_package "$output_file"; then
|
||||
rm -f "$output_file"
|
||||
echo "agent turn attempt $attempt hit a missing Codex platform package; retrying"
|
||||
continue
|
||||
fi
|
||||
rm -f "$output_file"
|
||||
exit "$rc"
|
||||
fi
|
||||
@@ -138,6 +148,7 @@ Wait-OpenClawGateway`;
|
||||
|
||||
function windowsAssertAgentOkScript(input: NpmUpdateScriptInput): string {
|
||||
return `${windowsAgentTurnConfigPatchScript(input.auth.modelId)}
|
||||
${windowsCodexPlatformPackageRepairFunction()}
|
||||
$sessionPath = Join-Path $env:USERPROFILE '.openclaw\\agents\\main\\sessions\\parallels-npm-update-windows.jsonl'
|
||||
Remove-Item $sessionPath -Force -ErrorAction SilentlyContinue
|
||||
${windowsAgentWorkspaceScript("Parallels npm update smoke test assistant.")}
|
||||
@@ -149,16 +160,21 @@ for ($attempt = 1; $attempt -le 2; $attempt++) {
|
||||
$sessionPath = Join-Path $sessionsDir "$sessionId.jsonl"
|
||||
Remove-Item $sessionPath -Force -ErrorAction SilentlyContinue
|
||||
$output = Invoke-OpenClaw agent --local --agent main --session-id $sessionId --model ${psSingleQuote(input.auth.modelId)} --message 'Reply with exact ASCII text OK only.' --thinking off --timeout ${resolveParallelsModelTimeoutSeconds("windows")} --json 2>&1
|
||||
$agentExitCode = $LASTEXITCODE
|
||||
if ($null -ne $output) { $output | ForEach-Object { $_ } }
|
||||
if ($LASTEXITCODE -ne 0) { throw "agent failed with exit code $LASTEXITCODE" }
|
||||
if (($output | Out-String) -match '"finalAssistant(Raw|Visible)Text":\\s*"OK"') {
|
||||
if ($agentExitCode -eq 0 -and ($output | Out-String) -match '"finalAssistant(Raw|Visible)Text":\\s*"OK"') {
|
||||
$agentOk = $true
|
||||
break
|
||||
}
|
||||
if ($agentExitCode -ne 0 -and $attempt -lt 2 -and (Repair-MissingCodexPlatformPackage -Output $output)) {
|
||||
Write-Host "agent turn attempt $attempt hit a missing Codex platform package; retrying"
|
||||
continue
|
||||
}
|
||||
if ($attempt -lt 2) {
|
||||
Write-Host "agent turn attempt $attempt finished without OK response; retrying"
|
||||
Start-Sleep -Seconds 3
|
||||
}
|
||||
if ($agentExitCode -ne 0) { throw "agent failed with exit code $agentExitCode" }
|
||||
}
|
||||
if (-not $agentOk) { throw 'openclaw agent finished without OK response' }`;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,84 @@ interface PluginIsolationOptions {
|
||||
nodeCommand?: string;
|
||||
}
|
||||
|
||||
export function posixCodexPlatformPackageRepairFunction(): string {
|
||||
return `repair_missing_codex_platform_package() {
|
||||
output_file="$1"
|
||||
grep -F 'Missing optional dependency @openai/codex-' "$output_file" >/dev/null 2>&1 || return 1
|
||||
state_home="\${OPENCLAW_PARALLELS_HOME:-\${HOME:-}}"
|
||||
codex_manifest=""
|
||||
for candidate in "$state_home"/.openclaw/npm/projects/*/node_modules/@openclaw/codex/package.json; do
|
||||
[ -f "$candidate" ] || continue
|
||||
codex_manifest="$candidate"
|
||||
break
|
||||
done
|
||||
if [ -z "$codex_manifest" ]; then
|
||||
echo "codex-platform-repair: managed Codex project not found" >&2
|
||||
return 1
|
||||
fi
|
||||
project_root="\${codex_manifest%/node_modules/@openclaw/codex/package.json}"
|
||||
cache_dir="$(mktemp -d "\${TMPDIR:-/tmp}/openclaw-npm-cache.XXXXXX")"
|
||||
echo "codex-platform-repair: retrying managed npm install once with a fresh cache" >&2
|
||||
repair_rc=0
|
||||
(
|
||||
cd "$project_root"
|
||||
NPM_CONFIG_CACHE="$cache_dir" npm_config_cache="$cache_dir" npm install --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund
|
||||
) || repair_rc=$?
|
||||
rm -rf "$cache_dir"
|
||||
if [ "$repair_rc" -ne 0 ]; then
|
||||
echo "codex-platform-repair: npm install failed with exit code $repair_rc" >&2
|
||||
return "$repair_rc"
|
||||
fi
|
||||
echo "codex-platform-repair: managed npm install completed" >&2
|
||||
}`;
|
||||
}
|
||||
|
||||
export function windowsCodexPlatformPackageRepairFunction(): string {
|
||||
return String.raw`function Repair-MissingCodexPlatformPackage {
|
||||
param([object[]] $Output)
|
||||
$outputText = $Output | Out-String
|
||||
if ($outputText -notmatch [regex]::Escape('Missing optional dependency @openai/codex-')) {
|
||||
return $false
|
||||
}
|
||||
$projectsRoot = Join-Path $env:USERPROFILE '.openclaw\npm\projects'
|
||||
$codexManifest = Get-ChildItem -Path $projectsRoot -Filter package.json -File -Recurse -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -match 'node_modules[\\/]@openclaw[\\/]codex[\\/]package\.json$' } |
|
||||
Select-Object -First 1
|
||||
if (-not $codexManifest) {
|
||||
Write-Warning 'codex-platform-repair: managed Codex project not found'
|
||||
return $false
|
||||
}
|
||||
$projectRoot = $codexManifest.Directory.Parent.Parent.Parent.FullName
|
||||
$cacheDir = Join-Path ([System.IO.Path]::GetTempPath()) ('openclaw-npm-cache-' + [guid]::NewGuid().ToString('N'))
|
||||
$oldUpperCache = [Environment]::GetEnvironmentVariable('NPM_CONFIG_CACHE', 'Process')
|
||||
$oldLowerCache = [Environment]::GetEnvironmentVariable('npm_config_cache', 'Process')
|
||||
$pushedLocation = $false
|
||||
$repairExit = 1
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
|
||||
[Environment]::SetEnvironmentVariable('NPM_CONFIG_CACHE', $cacheDir, 'Process')
|
||||
[Environment]::SetEnvironmentVariable('npm_config_cache', $cacheDir, 'Process')
|
||||
Push-Location $projectRoot
|
||||
$pushedLocation = $true
|
||||
Write-Host 'codex-platform-repair: retrying managed npm install once with a fresh cache'
|
||||
$repairOutput = & npm.cmd install --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund 2>&1
|
||||
$repairExit = $LASTEXITCODE
|
||||
if ($null -ne $repairOutput) { $repairOutput | ForEach-Object { Write-Host $_ } }
|
||||
} finally {
|
||||
if ($pushedLocation) { Pop-Location }
|
||||
[Environment]::SetEnvironmentVariable('NPM_CONFIG_CACHE', $oldUpperCache, 'Process')
|
||||
[Environment]::SetEnvironmentVariable('npm_config_cache', $oldLowerCache, 'Process')
|
||||
Remove-Item $cacheDir -Force -Recurse -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($repairExit -ne 0) {
|
||||
Write-Warning "codex-platform-repair: npm install failed with exit code $repairExit"
|
||||
return $false
|
||||
}
|
||||
Write-Host 'codex-platform-repair: managed npm install completed'
|
||||
return $true
|
||||
}`;
|
||||
}
|
||||
|
||||
export function providerOnlyPluginId(modelId: string, fallbackPluginId: string): string {
|
||||
return providerIdFromModelId(modelId) || fallbackPluginId;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,10 @@ import { runWindowsBackgroundPowerShell, WindowsGuest } from "./guest-transports
|
||||
import { startHostServer } from "./host-server.ts";
|
||||
import { ensureVmRunning } from "./parallels-vm.ts";
|
||||
import { PhaseRunner } from "./phase-runner.ts";
|
||||
import { windowsProviderOnlyPluginIsolationScript } from "./plugin-isolation.ts";
|
||||
import {
|
||||
windowsCodexPlatformPackageRepairFunction,
|
||||
windowsProviderOnlyPluginIsolationScript,
|
||||
} from "./plugin-isolation.ts";
|
||||
import {
|
||||
psSingleQuote,
|
||||
windowsAgentTurnConfigPatchScript,
|
||||
@@ -725,6 +728,7 @@ $PSNativeCommandUseErrorActionPreference = $false
|
||||
${windowsPortableGitPathScript}
|
||||
${windowsAgentTurnConfigPatchScript(this.auth.modelId)}
|
||||
${windowsAgentWorkspaceScript("Parallels Windows smoke test assistant.")}
|
||||
${windowsCodexPlatformPackageRepairFunction()}
|
||||
Set-Item -Path ('Env:' + ${psSingleQuote(this.auth.apiKeyEnv)}) -Value ${psSingleQuote(this.auth.apiKeyValue)}
|
||||
$agentOk = $false
|
||||
for ($attempt = 1; $attempt -le 2; $attempt++) {
|
||||
@@ -754,6 +758,10 @@ for ($attempt = 1; $attempt -le 2; $attempt++) {
|
||||
$agentOk = $true
|
||||
break
|
||||
}
|
||||
if ($agentExitCode -ne 0 -and $attempt -lt 2 -and (Repair-MissingCodexPlatformPackage -Output $output)) {
|
||||
Write-Host "agent turn attempt $attempt hit a missing Codex platform package; retrying"
|
||||
continue
|
||||
}
|
||||
if ($attempt -lt 2) {
|
||||
Write-Host "agent turn attempt $attempt failed or finished without OK response; retrying"
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
@@ -42,6 +42,10 @@ import { parseArgs as parseLinuxSmokeArgs } from "../../scripts/e2e/parallels/li
|
||||
import { parseArgs as parseMacosSmokeArgs } from "../../scripts/e2e/parallels/macos-smoke.ts";
|
||||
import { parseArgs as parseNpmUpdateSmokeArgs } from "../../scripts/e2e/parallels/npm-update-smoke.ts";
|
||||
import { PhaseRunner } from "../../scripts/e2e/parallels/phase-runner.ts";
|
||||
import {
|
||||
posixCodexPlatformPackageRepairFunction,
|
||||
windowsCodexPlatformPackageRepairFunction,
|
||||
} from "../../scripts/e2e/parallels/plugin-isolation.ts";
|
||||
import { parseArgs as parseWindowsSmokeArgs } from "../../scripts/e2e/parallels/windows-smoke.ts";
|
||||
import { withEnv } from "../../src/test-utils/env.js";
|
||||
import { spawnNodeEvalSync } from "../../src/test-utils/node-process.js";
|
||||
@@ -275,6 +279,20 @@ describe("Parallels smoke model selection", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("repairs only the exact missing Codex platform package failure with a fresh npm cache", () => {
|
||||
const posixRepair = posixCodexPlatformPackageRepairFunction();
|
||||
const windowsRepair = windowsCodexPlatformPackageRepairFunction();
|
||||
|
||||
for (const repair of [posixRepair, windowsRepair]) {
|
||||
expect(repair).toContain("Missing optional dependency @openai/codex-");
|
||||
expect(repair).toContain("NPM_CONFIG_CACHE");
|
||||
expect(repair).toContain("--ignore-scripts");
|
||||
expect(repair).toContain("codex-platform-repair: managed npm install completed");
|
||||
}
|
||||
expect(posixRepair).toContain("repair_missing_codex_platform_package");
|
||||
expect(windowsRepair).toContain("Repair-MissingCodexPlatformPackage");
|
||||
});
|
||||
|
||||
it("writes full model ids as config map keys in provider batches", () => {
|
||||
const batch = JSON.parse(modelProviderConfigBatchJson("openai/gpt-5.5", "windows")) as Array<{
|
||||
path: string;
|
||||
|
||||
Reference in New Issue
Block a user