

























@@ -614,6 +614,150 @@ EOF
614614)"
615615}
616616617+guest_run_agent_turn_process() {
618+local env_name_q env_value_q runner_basename runner_script_path runner_url runner_url_q
619+local runner_name stdout_name stderr_name done_name
620+local start_seconds poll_deadline startup_checked state_rc log_rc done_rc
621+local agent_combined done_status launcher_state
622+ env_name_q="$(ps_single_quote "$API_KEY_ENV")"
623+ env_value_q="$(ps_single_quote "$API_KEY_VALUE")"
624+ runner_basename="openclaw-parallels-agent-runner-$RANDOM-$RANDOM.ps1"
625+ runner_script_path="$MAIN_TGZ_DIR/$runner_basename"
626+ runner_url="http://$HOST_IP:$HOST_PORT/$runner_basename"
627+ runner_url_q="$(ps_single_quote "$runner_url")"
628+ runner_name="openclaw-parallels-agent-$RANDOM-$RANDOM.ps1"
629+ stdout_name="openclaw-parallels-agent-$RANDOM-$RANDOM.out.log"
630+ stderr_name="openclaw-parallels-agent-$RANDOM-$RANDOM.err.log"
631+ done_name="openclaw-parallels-agent-$RANDOM-$RANDOM.done"
632+ start_seconds="$SECONDS"
633+ poll_deadline=$((SECONDS + TIMEOUT_AGENT_S + 60))
634+ startup_checked=0
635+636+ cat >"$runner_script_path" <<'EOF'
637+param(
638+ [string]$StdoutPath,
639+ [string]$StderrPath,
640+ [string]$DonePath,
641+ [string]$EnvName,
642+ [string]$EnvValue
643+)
644+$ErrorActionPreference = 'Continue'
645+try {
646+ if ($EnvName -ne '') {
647+ Set-Item -Path ('Env:' + $EnvName) -Value $EnvValue
648+ }
649+ $node = Join-Path $env:ProgramFiles 'nodejs\node.exe'
650+ if (-not (Test-Path $node)) {
651+ $node = 'node'
652+ }
653+ $entry = Join-Path $env:APPDATA 'npm\node_modules\openclaw\openclaw.mjs'
654+ & $node $entry agent --local --agent main --session-id 'parallels-windows-smoke' --message 'Reply with exact ASCII text OK only.' --json > $StdoutPath 2> $StderrPath
655+ Set-Content -Path $DonePath -Value ([string]$LASTEXITCODE)
656+ exit $LASTEXITCODE
657+} catch {
658+ $_ | Out-String | Set-Content -Path $StderrPath
659+ Set-Content -Path $DonePath -Value '1'
660+ exit 1
661+}
662+EOF
663+664+ guest_powershell_poll 20 "$(cat <<EOF
665+\$runner = Join-Path \$env:TEMP '$runner_name'
666+\$stdout = Join-Path \$env:TEMP '$stdout_name'
667+\$stderr = Join-Path \$env:TEMP '$stderr_name'
668+\$done = Join-Path \$env:TEMP '$done_name'
669+Remove-Item \$runner, \$stdout, \$stderr, \$done -Force -ErrorAction SilentlyContinue
670+curl.exe -fsSL '${runner_url_q}' -o \$runner
671+Start-Process powershell.exe -ArgumentList @(
672+ '-NoProfile',
673+ '-ExecutionPolicy',
674+ 'Bypass',
675+ '-File',
676+ \$runner,
677+ '-StdoutPath',
678+ \$stdout,
679+ '-StderrPath',
680+ \$stderr,
681+ '-DonePath',
682+ \$done,
683+ '-EnvName',
684+ '${env_name_q}',
685+ '-EnvValue',
686+ '${env_value_q}'
687+) -WindowStyle Hidden | Out-Null
688+EOF
689+ )"
690+691+while true; do
692+set +e
693+ agent_combined="$(
694+ guest_powershell_poll 20 "\$stdout = Join-Path \$env:TEMP '$stdout_name'; \$stderr = Join-Path \$env:TEMP '$stderr_name'; \$out = ''; \$err = ''; if (Test-Path \$stdout) { \$out = Get-Content -Path \$stdout -Raw -ErrorAction SilentlyContinue }; if (Test-Path \$stderr) { \$err = Get-Content -Path \$stderr -Raw -ErrorAction SilentlyContinue }; \$out + [Environment]::NewLine + \$err"
695+ )"
696+ log_rc=$?
697+set -e
698+if [[ $log_rc -eq 0 ]] && printf '%s\n' "$agent_combined" | grep -Eq '"finalAssistant(Raw|Visible)Text":[[:space:]]*"OK"'; then
699+printf '%s\n' "$agent_combined"
700+ guest_powershell_poll 20 "\$runner = Join-Path \$env:TEMP '$runner_name'; \$done = Join-Path \$env:TEMP '$done_name'; Remove-Item \$runner, \$done -Force -ErrorAction SilentlyContinue"
701+return 0
702+fi
703+704+set +e
705+ done_status="$(
706+ guest_powershell_poll 20 "\$done = Join-Path \$env:TEMP '$done_name'; if (Test-Path \$done) { (Get-Content \$done -Raw).Trim() }"
707+ )"
708+ done_rc=$?
709+set -e
710+if [[ $done_rc -eq 0 && -n "$done_status" ]]; then
711+if [[ $log_rc -eq 0 && -n "$agent_combined" ]]; then
712+printf '%s\n' "$agent_combined"
713+fi
714+ guest_powershell_poll 20 "\$runner = Join-Path \$env:TEMP '$runner_name'; \$done = Join-Path \$env:TEMP '$done_name'; Remove-Item \$runner, \$done -Force -ErrorAction SilentlyContinue"
715+ warn "openclaw agent finished without OK response (exit $done_status)"
716+return 1
717+fi
718+719+if [[ "$startup_checked" -eq 0 && $((SECONDS - start_seconds)) -ge 20 ]]; then
720+set +e
721+ launcher_state="$(
722+ guest_powershell_poll 20 "\$runner = Join-Path \$env:TEMP '$runner_name'; \$stdout = Join-Path \$env:TEMP '$stdout_name'; \$stderr = Join-Path \$env:TEMP '$stderr_name'; \$done = Join-Path \$env:TEMP '$done_name'; \$currentPid = \$PID; \$process = Get-CimInstance Win32_Process | Where-Object { \$_.ProcessId -ne \$currentPid -and ((\$_.CommandLine -like '*$runner_name*') -or (\$_.CommandLine -like '*openclaw.mjs*agent*parallels-windows-smoke*')) } | Select-Object -First 1; 'runner=' + (Test-Path \$runner) + ' stdout=' + (Test-Path \$stdout) + ' stderr=' + (Test-Path \$stderr) + ' done=' + (Test-Path \$done) + ' process=' + [bool]\$process"
723+ )"
724+ state_rc=$?
725+set -e
726+ launcher_state="${launcher_state//$'\r'/}"
727+ startup_checked=1
728+if [[ $state_rc -eq 0 && "$launcher_state" == *"runner=False"* && "$launcher_state" == *"stdout=False"* && "$launcher_state" == *"stderr=False"* && "$launcher_state" == *"done=False"* && "$launcher_state" == *"process=False"* ]]; then
729+ warn "windows agent helper failed to materialize guest files"
730+return 1
731+fi
732+fi
733+734+if (( SECONDS >= poll_deadline )); then
735+if [[ $log_rc -eq 0 && -n "$agent_combined" ]]; then
736+printf '%s\n' "$agent_combined"
737+fi
738+ guest_powershell_poll 20 "\$runner = Join-Path \$env:TEMP '$runner_name'; \$done = Join-Path \$env:TEMP '$done_name'; Remove-Item \$runner, \$done -Force -ErrorAction SilentlyContinue"
739+ warn "openclaw agent timed out after $TIMEOUT_AGENT_S seconds"
740+return 1
741+fi
742+ sleep 2
743+done
744+}
745+746+stop_gateway_processes_for_local_agent_turn() {
747+ guest_powershell_poll 20 "$(cat <<'EOF'
748+$processes = Get-CimInstance Win32_Process | Where-Object {
749+ $_.CommandLine -match 'openclaw(.cmd|.mjs|\\dist\\index.js)?.*gateway'
750+}
751+foreach ($process in $processes) {
752+ Stop-Process -Id $process.ProcessId -Force -ErrorAction SilentlyContinue
753+}
754+if ($processes) {
755+ "Stopped OpenClaw gateway processes for local agent turn"
756+}
757+EOF
758+)"
759+}
760+617761ensure_vm_running_for_retry() {
618762local status
619763 status="$(prlctl status "$VM_NAME" 2>/dev/null || true)"
@@ -1335,6 +1479,7 @@ PY
13351479}
1336148013371481install_latest_release() {
1482+local expected_version="${1:-}"
13381483local install_url_q version_flag_q
13391484local script_url
13401485local runner_name log_name done_name done_status launcher_state guest_log
@@ -1429,6 +1574,13 @@ PY
14291574if ! stream_windows_latest_install_log; then
14301575 warn "windows latest install helper log drain failed after completion"
14311576fi
1577+if [[ "$done_status" != "0" ]] && recover_successful_published_install "$log_state_path" "$expected_version"; then
1578+ rm -f "$log_state_path"
1579+return 0
1580+fi
1581+if [[ "$done_status" != "0" ]]; then
1582+ dump_latest_guest_npm_log_tail "windows latest install npm debug tail" || true
1583+fi
14321584 rm -f "$log_state_path"
14331585 [[ "$done_status" == "0" ]]
14341586return $?
@@ -1452,6 +1604,7 @@ PY
14521604if ! stream_windows_latest_install_log; then
14531605 warn "windows latest install helper log drain failed after timeout"
14541606fi
1607+ dump_latest_guest_npm_log_tail "windows latest install npm debug tail" || true
14551608 warn "windows latest install helper timed out waiting for done file"
14561609 rm -f "$log_state_path"
14571610return 1
@@ -1460,6 +1613,34 @@ PY
14601613done
14611614}
146216151616+recover_successful_published_install() {
1617+local log_path="$1"
1618+local expected_version="$2"
1619+local installed_version rc
1620+1621+ [[ -n "$expected_version" ]] || return 1
1622+ [[ -f "$log_path" ]] || return 1
1623+ grep -Fq "OpenClaw installed successfully" "$log_path" || return 1
1624+ grep -Fq "Cannot process argument transformation on parameter 'Succeeded'" "$log_path" || return 1
1625+ grep -Fq "System.Object[]" "$log_path" || return 1
1626+ grep -Fq "System.Boolean" "$log_path" || return 1
1627+1628+set +e
1629+ installed_version="$(guest_run_openclaw "" "" "--version")"
1630+ rc=$?
1631+set -e
1632+ installed_version="${installed_version//$'\r'/}"
1633+if [[ $rc -ne 0 || "$installed_version" != *"OpenClaw $expected_version "* ]]; then
1634+ warn "published installer reported known success-return bug, but installed version did not match $expected_version"
1635+printf '%s\n' "$installed_version" >&2
1636+return 1
1637+fi
1638+1639+ warn "published installer reported known success-return bug after installing $expected_version; continuing"
1640+printf '%s\n' "$installed_version"
1641+return 0
1642+}
1643+14631644install_main_tgz() {
14641645local host_ip="$1"
14651646local temp_name="$2"
@@ -2397,10 +2578,9 @@ New-Item -ItemType Directory -Path $stateDir -Force | Out-Null
23972578'@ | Set-Content -Path (Join-Path $stateDir 'workspace-state.json') -Encoding UTF8
23982579Remove-Item (Join-Path $workspace 'BOOTSTRAP.md') -Force -ErrorAction SilentlyContinue
23992580EOF
2400-)"
2401- stop_gateway
2402- guest_run_openclaw "$API_KEY_ENV" "$API_KEY_VALUE" \
2403- agent --local --agent main --session-id parallels-windows-smoke --message "Reply with exact ASCII text OK only." --json
2581+ )"
2582+ stop_gateway_processes_for_local_agent_turn
2583+ guest_run_agent_turn_process
24042584}
2405258524062586capture_latest_ref_failure() {
@@ -2449,7 +2629,7 @@ run_fresh_main_lane() {
24492629run_upgrade_lane() {
24502630local snapshot_id="$1"
24512631local host_ip="$2"
2452-local baseline_version
2632+local baseline_version baseline_install_phase
24532633 phase_run "upgrade.restore-snapshot" "$TIMEOUT_SNAPSHOT_S" restore_snapshot "$snapshot_id" || return $?
24542634 phase_run "upgrade.wait-for-user" "$TIMEOUT_SNAPSHOT_S" wait_for_guest_ready || return $?
24552635if ! phase_run "upgrade.ensure-git" "$TIMEOUT_GIT_SETUP_S" ensure_guest_git "$host_ip"; then
@@ -2462,8 +2642,13 @@ run_upgrade_lane() {
24622642 phase_run "upgrade.verify-baseline-package-version" "$TIMEOUT_VERIFY_S" verify_target_version || return $?
24632643else
24642644 baseline_version="$(baseline_install_version)"
2465- phase_run "upgrade.install-baseline" "$TIMEOUT_INSTALL_S" install_latest_release || return $?
2466- LATEST_INSTALLED_VERSION="$(extract_last_version "$(phase_log_path upgrade.install-baseline)")"
2645+ baseline_install_phase="upgrade.install-baseline"
2646+if ! phase_run "$baseline_install_phase" "$TIMEOUT_INSTALL_S" install_latest_release "$baseline_version"; then
2647+ phase_run "upgrade.wait-for-user-baseline-retry" "$TIMEOUT_SNAPSHOT_S" wait_for_guest_ready || return $?
2648+ phase_run "upgrade.install-baseline-retry" "$TIMEOUT_INSTALL_S" install_latest_release "$baseline_version" || return $?
2649+ baseline_install_phase="upgrade.install-baseline-retry"
2650+fi
2651+ LATEST_INSTALLED_VERSION="$(extract_last_version "$(phase_log_path "$baseline_install_phase")")"
24672652 phase_run "upgrade.verify-baseline-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$baseline_version" || return $?
24682653fi
24692654if [[ "$CHECK_LATEST_REF" -eq 1 ]]; then
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。