mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-09 03:11:58 +00:00
fix(windows): auto-install Playwright Chromium + surface it in doctor
scripts/install.sh runs 'npx playwright install --with-deps chromium' on every Linux distro after the npm-install step, which is why browser tools Just Work on Linux. scripts/install.ps1 never did the equivalent step, so on native Windows installs check_browser_requirements() in tools/browser_tool.py would return False (no Chromium under %LOCALAPPDATA%\ms-playwright) and every browser_* tool got silently filtered out of the agent's tool schema — no error, no log entry, user just wondered why the tools didn't exist. Two-part fix: 1. scripts/install.ps1: after 'npm install' in InstallDir succeeds, run 'npx playwright install chromium'. Resolves npx via the same execution-policy-aware logic already used for npm (prefer npx.cmd next to npmExe, fall back to Get-Command). Surfaces a warning + manual-recovery hint when the install fails, matching install.sh behaviour for distros. 2. hermes_cli/doctor.py: after the agent-browser check, lazily import tools.browser_tool and reuse the exact same _chromium_installed() predicate check_browser_requirements() uses, so the doctor signal cannot drift from the runtime gate. Skip the check when Camofox / CDP override / a cloud provider / Lightpanda is configured (those bypass local Chromium). On missing Chromium, the hint is platform-correct: '--with-deps' on POSIX, plain 'install chromium' on win32. Verified on Windows 10: - 'npx playwright install chromium' completes successfully, drops Chrome Headless Shell under %LOCALAPPDATA%\ms-playwright - check_browser_requirements() flips from False -> True - 'hermes doctor' now prints either '✓ Playwright Chromium (browser engine)' or '⚠ Playwright Chromium not installed' + fix command - tests/hermes_cli/test_doctor.py: 38/38 pass - tests/tools/test_browser_chromium_check.py: 16/16 pass
This commit is contained in:
parent
b63f9645f0
commit
03566e5124
2 changed files with 111 additions and 1 deletions
|
|
@ -1035,10 +1035,13 @@ def run_doctor(args):
|
|||
check_ok("Node.js")
|
||||
# Check if agent-browser is installed
|
||||
agent_browser_path = PROJECT_ROOT / "node_modules" / "agent-browser"
|
||||
agent_browser_ok = False
|
||||
if agent_browser_path.exists():
|
||||
check_ok("agent-browser (Node.js)", "(browser automation)")
|
||||
agent_browser_ok = True
|
||||
elif shutil.which("agent-browser"):
|
||||
check_ok("agent-browser", "(browser automation)")
|
||||
agent_browser_ok = True
|
||||
else:
|
||||
if _is_termux():
|
||||
check_info("agent-browser is not installed (expected in the tested Termux path)")
|
||||
|
|
@ -1048,6 +1051,56 @@ def run_doctor(args):
|
|||
check_info(step)
|
||||
else:
|
||||
check_warn("agent-browser not installed", "(run: npm install)")
|
||||
|
||||
# Chromium presence — the browser tools silently fail to register when
|
||||
# agent-browser is found but no Playwright-managed Chromium is on disk
|
||||
# (tools/browser_tool.py::check_browser_requirements filters them out
|
||||
# before the agent ever sees them). Reuse the exact predicate it uses
|
||||
# so the two checks cannot diverge. Skip on Termux (not a tested
|
||||
# path).
|
||||
if agent_browser_ok and not _is_termux():
|
||||
try:
|
||||
# Lazy import: browser_tool is a ~150KB module we don't want
|
||||
# to eagerly load in every `hermes doctor` invocation.
|
||||
from tools.browser_tool import (
|
||||
_chromium_installed,
|
||||
_is_camofox_mode,
|
||||
_get_cloud_provider,
|
||||
_get_cdp_override,
|
||||
_using_lightpanda_engine,
|
||||
)
|
||||
except Exception:
|
||||
# If browser_tool can't even import, that's a separate bug
|
||||
# surfaced elsewhere; don't crash doctor.
|
||||
pass
|
||||
else:
|
||||
# Only warn about Chromium if the installed engine actually
|
||||
# requires it: Camofox, CDP override, a cloud provider, or
|
||||
# Lightpanda all bypass the local Chromium requirement.
|
||||
skip_chromium_check = (
|
||||
_is_camofox_mode()
|
||||
or bool(_get_cdp_override())
|
||||
or _get_cloud_provider() is not None
|
||||
or _using_lightpanda_engine()
|
||||
)
|
||||
if not skip_chromium_check:
|
||||
if _chromium_installed():
|
||||
check_ok("Playwright Chromium", "(browser engine)")
|
||||
else:
|
||||
check_warn(
|
||||
"Playwright Chromium not installed",
|
||||
"(browser_* tools will be hidden from the agent)",
|
||||
)
|
||||
if sys.platform == "win32":
|
||||
check_info(
|
||||
f"Install with: cd {PROJECT_ROOT} && "
|
||||
"npx playwright install chromium"
|
||||
)
|
||||
else:
|
||||
check_info(
|
||||
f"Install with: cd {PROJECT_ROOT} && "
|
||||
"npx playwright install --with-deps chromium"
|
||||
)
|
||||
else:
|
||||
if _is_termux():
|
||||
check_info("Node.js not found (browser tools are optional in the tested Termux path)")
|
||||
|
|
|
|||
|
|
@ -1040,7 +1040,64 @@ function Install-NodeDeps {
|
|||
if (Test-Path "$InstallDir\package.json") {
|
||||
Write-Info "Installing Node.js dependencies (browser tools)..."
|
||||
$browserLog = "$env:TEMP\hermes-npm-browser-$(Get-Random).log"
|
||||
[void](_Run-NpmInstall "Browser tools" $InstallDir $browserLog $npmExe)
|
||||
$browserNpmOk = _Run-NpmInstall "Browser tools" $InstallDir $browserLog $npmExe
|
||||
|
||||
# Install Playwright Chromium (mirrors scripts/install.sh behaviour for
|
||||
# Linux). Without this, tools/browser_tool.py::check_browser_requirements
|
||||
# returns False (no Chromium under %LOCALAPPDATA%\ms-playwright), and the
|
||||
# browser_* tools are silently filtered out of the agent's tool schema.
|
||||
# System Chrome at "C:\Program Files\Google\Chrome\..." is NOT used by
|
||||
# agent-browser — it expects a Playwright-managed Chromium.
|
||||
if ($browserNpmOk) {
|
||||
Write-Info "Installing browser engine (Playwright Chromium)..."
|
||||
# npx lives next to npm in the same bin dir. Prefer .cmd to dodge
|
||||
# the same execution-policy gotcha that affects npm.ps1 (see above).
|
||||
$npmDir = Split-Path $npmExe -Parent
|
||||
$npxExe = $null
|
||||
foreach ($cand in @("npx.cmd", "npx.exe", "npx")) {
|
||||
$try = Join-Path $npmDir $cand
|
||||
if (Test-Path $try) { $npxExe = $try; break }
|
||||
}
|
||||
if (-not $npxExe) {
|
||||
$npxCmd = Get-Command npx -ErrorAction SilentlyContinue
|
||||
if ($npxCmd) { $npxExe = $npxCmd.Source }
|
||||
}
|
||||
if (-not $npxExe) {
|
||||
Write-Warn "npx not found — cannot install Playwright Chromium."
|
||||
Write-Info "Run manually later: cd `"$InstallDir`"; npx playwright install chromium"
|
||||
} else {
|
||||
$pwLog = "$env:TEMP\hermes-playwright-install-$(Get-Random).log"
|
||||
Push-Location $InstallDir
|
||||
try {
|
||||
& $npxExe playwright install chromium *> $pwLog
|
||||
$pwCode = $LASTEXITCODE
|
||||
if ($pwCode -eq 0) {
|
||||
Write-Success "Playwright Chromium installed (browser tools ready)"
|
||||
Remove-Item -Force $pwLog -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
Write-Warn "Playwright Chromium install failed — exit code $pwCode"
|
||||
Write-Warn "Browser tools will not work until Chromium is installed."
|
||||
if (Test-Path $pwLog) {
|
||||
$pwErr = Get-Content $pwLog -Raw -ErrorAction SilentlyContinue
|
||||
if ($pwErr) {
|
||||
$snippet = if ($pwErr.Length -gt 1200) { $pwErr.Substring(0, 1200) + "..." } else { $pwErr }
|
||||
Write-Info " playwright output:"
|
||||
foreach ($line in $snippet -split "`n") {
|
||||
Write-Host " $line" -ForegroundColor DarkGray
|
||||
}
|
||||
Write-Info " Full log: $pwLog"
|
||||
}
|
||||
}
|
||||
Write-Info "Run manually later: cd `"$InstallDir`"; npx playwright install chromium"
|
||||
}
|
||||
} catch {
|
||||
Write-Warn "Playwright Chromium install could not be launched: $_"
|
||||
Write-Info "Run manually later: cd `"$InstallDir`"; npx playwright install chromium"
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# TUI
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue