fix(installer): re-resolve Python fallback at venv stage on Windows (#50769)

The Windows installer runs each -Stage NAME in its own powershell.exe under
Hermes-Setup.exe. Test-Python records a detected fallback (e.g. 3.12 when 3.11
is absent) via an in-memory $script:PythonVersion = $fallbackVer mutation,
which dies with the python stage's process. The fresh venv stage starts with
$PythonVersion back at its "3.11" default, so it logged "Creating virtual
environment with Python 3.11..." and ran uv venv venv --python 3.11, failing
with exit 2 on machines that only had the fallback installed.

Add a cross-process-safe Resolve-AvailablePythonVersion helper (preferring the
requested version, then the shared $PythonFallbackVersions list, probed via
uv python find) and call it at the top of Install-Venv before creating the
venv. Test-Python's fallback loop now iterates the same shared constant so
detection and venv creation can't drift.
This commit is contained in:
xxxigm 2026-06-22 19:04:43 +07:00 committed by Teknium
parent 935f2bc48d
commit 23683c3353

View file

@ -139,6 +139,11 @@ foreach ($tmpVar in @('TEMP', 'TMP')) {
$RepoUrlSsh = "git@github.com:NousResearch/hermes-agent.git"
$RepoUrlHttps = "https://github.com/NousResearch/hermes-agent.git"
$PythonVersion = "3.11"
# Minor versions the installer accepts when the requested $PythonVersion isn't
# available, in preference order. uv discovers both uv-managed and system
# interpreters, so this list also matches a pre-existing system Python. Single
# source of truth shared by Test-Python's fallback and Resolve-AvailablePythonVersion.
$PythonFallbackVersions = @("3.12", "3.13", "3.10")
$NodeVersion = "22"
# Stage-protocol version. Bumped only for genuinely breaking changes to the
@ -510,6 +515,31 @@ function Resolve-UvCmd {
throw "uv is not installed. Run install.ps1 -Stage uv first."
}
function Resolve-AvailablePythonVersion {
# Return the first Python minor version uv can actually find, preferring the
# requested $PythonVersion and then $PythonFallbackVersions. Returns $null
# when none are available.
#
# This is the cross-process-safe counterpart to Test-Python's in-memory
# ``$script:PythonVersion = $fallbackVer`` mutation. Under Hermes-Setup.exe
# each ``-Stage NAME`` runs in a *fresh* powershell.exe, so the fallback the
# ``python`` stage settled on (e.g. 3.12 when 3.11 is absent) does NOT
# survive into the ``venv`` stage's process -- there $PythonVersion is back
# at its "3.11" default. Consumers re-resolve here instead of trusting that
# default, which is exactly the propagation gap behind issue #50769.
$candidates = @($PythonVersion) + $PythonFallbackVersions
$seen = @{}
foreach ($ver in $candidates) {
if (-not $ver -or $seen.ContainsKey($ver)) { continue }
$seen[$ver] = $true
try {
$found = & $UvCmd python find $ver 2>$null
if ($found) { return $ver }
} catch { }
}
return $null
}
function Test-Python {
Write-Info "Checking Python $PythonVersion..."
@ -566,7 +596,7 @@ function Test-Python {
# Fallback: check if ANY Python 3.10+ is already available on the system
Write-Info "Trying to find any existing Python 3.10+..."
foreach ($fallbackVer in @("3.12", "3.13", "3.10")) {
foreach ($fallbackVer in $PythonFallbackVersions) {
try {
$pythonPath = & $UvCmd python find $fallbackVer 2>$null
if ($pythonPath) {
@ -1513,7 +1543,19 @@ function Install-Venv {
Write-Info "Skipping virtual environment (-NoVenv)"
return
}
# Re-resolve the interpreter before creating the venv. Under Hermes-Setup.exe
# each stage runs in its own powershell.exe, so the fallback the `python`
# stage picked (e.g. 3.12 when 3.11 is absent) did NOT propagate into this
# fresh process -- $PythonVersion is back at its "3.11" default. Trusting it
# here made `uv venv venv --python 3.11` fail with exit 2 on machines without
# 3.11 even though the `python` stage reported success (issue #50769).
$resolved = Resolve-AvailablePythonVersion
if ($resolved -and $resolved -ne $PythonVersion) {
Write-Info "Python $PythonVersion not available; using detected Python $resolved"
$script:PythonVersion = $resolved
}
Write-Info "Creating virtual environment with Python $PythonVersion..."
Push-Location $InstallDir