fix(browser): one loopback proxy-bypass helper covers child envs and in-process CDP dials

Move the loopback NO_PROXY merge from browser_tool into agent/proxy_bypass.py (the
module that already owns NO_PROXY semantics) and reuse no_proxy_entries() so comma-
and whitespace-separated operator values are both preserved. Add
loopback_connect_kwargs() and pass proxy=None on the two in-process websockets
dials to loopback CDP endpoints (browser_cdp_tool._cdp_call, BrowserSupervisor._run):
those never see the child env, so the env merge alone left them routed through a
macOS system proxy. Remote CDP URLs keep the default proxy behaviour.

Tests trimmed to two invariants: the built child env appends loopback to an
operator NO_PROXY in both casings, and only loopback URLs get proxy=None.
Sibling helper in tools/browser_use_cli (#110570) is redundant once the shared
env carries the entries.
This commit is contained in:
teknium1
2026-09-14 18:26:14 -07:00
committed by Teknium
parent 00a68a8768
commit 8f6f92d901
5 changed files with 71 additions and 103 deletions
+3 -1
View File
@@ -353,9 +353,11 @@ class CDPSupervisor(DialogSupervisionMixin, FrameTrackingMixin):
A failure before the first successful attach is fatal for ``start()``."""
attempt, last_success_at, backoff = 0, 0.0, 0.5
import websockets # deferred: only supervisors that connect pay the import
from agent.proxy_bypass import loopback_connect_kwargs
connect_kwargs = {"max_size": 50 * 1024 * 1024, **loopback_connect_kwargs(self.cdp_url)}
while not self._stop_requested:
try:
self._ws = await asyncio.wait_for(websockets.connect(self.cdp_url, max_size=50 * 1024 * 1024), timeout=10.0)
self._ws = await asyncio.wait_for(websockets.connect(self.cdp_url, **connect_kwargs), timeout=10.0)
except Exception as e:
attempt += 1
if self._fail_start(e):