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:
Teknium 2026-05-08 07:56:35 -07:00
parent ec3f7d1a89
commit aefd1a37f4
2 changed files with 111 additions and 1 deletions

View file

@ -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)")