Files
hermes-agent/tools
shadus 7dc0df1be8 fix: browser_exec honours hybrid routing for private/LAN URLs
With a cloud browser provider configured (the picker's `nous`, or any
browserbase/browser-use key), `browser.auto_local_for_private_urls` is on by
default and `browser_navigate` routes private/loopback/LAN URLs to a LOCAL
Chromium sidecar so the cloud provider never sees them. `browser_exec`'s
pre-flight URL scan did not consult that decision, so *every* LAN URL was
refused with "Blocked: URL targets a private or internal address" — and in
Browser Use mode (`browser.backend` unset, the default) `browser_exec` is the
only browser tool, so the documented hybrid workflow was unreachable.

Relaxing the pre-flight alone would have been wrong: the exec call resolves ONE
CDP endpoint for the whole code blob (`_resolve_backend_cdp`), so an allowed
private URL would then have been executed against the configured cloud browser
— exactly the leak the guard exists to prevent. Verdict and route now move
together:

* Extract `_hybrid_routes_locally(url)` in browser_tool as the single source of
  truth for the predicate; `_navigation_session_key` reads it too, so the
  navigate and exec paths cannot drift apart.
* `evaluate_url_safety(url, *, auto_local=False)` forwards the relaxation to
  `_url_policy_error` (the cloud-metadata floor stays unconditional).
* `_blocked_url_in_code` passes `auto_local=_hybrid_routes_locally(url)`, the
  same verdict the navigation path reaches for itself.
* `browser_exec` computes `local_sidecar` from the URLs in the code and threads
  it through `_route_backend` → `_resolve_backend_cdp(force_local_sidecar=...)`,
  which declines the cloud provider so the local engine serves the call. One
  endpoint per call means a mixed call runs wholly local — the safe direction.

Scope is deliberately narrow: no cloud provider, a CDP override, or Camofox all
leave `_hybrid_routes_locally` False, so those paths are byte-for-byte unchanged.
The two operator overrides (BU_CDP_*/`browser.cdp_url`) still outrank it.

Tests: 9 new cases in tests/tools/test_browser_use_cli.py covering the URL
verdict (LAN, loopback, public, IMDS still blocked, hybrid off, no provider) and
the endpoint the verdict depends on (LAN-only and mixed calls must never reach
the provider; public-only still must). Full browser suite: 663 passed.
2026-10-10 23:42:04 -07:00
..
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 19:54:07 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 19:54:07 +02:00
2026-10-08 21:29:48 +02:00
2026-10-08 21:35:58 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:36 +02:00
2026-10-08 21:38:05 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:36 +02:00
2026-10-09 17:34:36 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:36 +02:00
2026-10-09 17:34:36 +02:00
2026-10-09 17:34:36 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 19:42:29 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-09 17:34:38 +02:00
2026-10-08 21:29:48 +02:00
2026-10-09 17:34:36 +02:00