mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
fix(browser): browser_exec uses the local fallback when the cloud browser provider fails
When the configured cloud browser provider fails to create a session (seen live: Browser Use gateway HTTP 429 RATE_LIMIT_EXCEEDED), the session layer already falls back to local Chromium and marks the session fallback_from_cloud, which keeps the built-in browser_* tools working. browser_exec read only cdp_url from that session, found none (local sessions launch lazily), and failed the whole call with "returned no CDP endpoint, so Browser Use mode cannot drive it". On a fallback session, resolve the packaged Chromium's CDP endpoint the same way the no-provider path does, and log the provider failure once.
This commit is contained in:
1 parent
0faf0938eb
commit
04eb00cef7
2 files changed
+25
-1
No files matched your search
@@ -483,6 +483,18 @@ class TestBackendCdpResolution:
|
||||
err = bu_cli._resolve_backend_cdp(self._env(), "t1")
|
||||
assert err and "api down" in err
|
||||
|
||||
def test_provider_fallback_to_local_drives_packaged_chromium(self, monkeypatch, _fake_managed_chromium):
|
||||
"""A cloud failure the session layer already fell back from (429, quota) must drive the local
|
||||
Chromium it chose, not fail the call as 'no CDP endpoint'."""
|
||||
monkeypatch.setattr("tools.browser_tool_cdp._get_cdp_override", lambda: "")
|
||||
monkeypatch.setattr(bt_cloud, "_get_cloud_provider", lambda: object())
|
||||
monkeypatch.setattr(bt_session, "_get_session_info", lambda task_id: {
|
||||
"cdp_url": None, "features": {"local": True}, "fallback_from_cloud": True, "fallback_reason": "429"})
|
||||
env = self._env()
|
||||
assert bu_cli._resolve_backend_cdp(env, "t1") is None
|
||||
assert env["BU_CDP_WS"] == "ws://127.0.0.1:47000/devtools/browser/t1"
|
||||
assert _fake_managed_chromium == [("t1", "get", ("cdp-url",))]
|
||||
|
||||
def test_provider_without_cdp_returns_error(self, monkeypatch):
|
||||
|
||||
monkeypatch.setattr("tools.browser_tool_cdp._get_cdp_override", lambda: "")
|
||||
|
||||
@@ -502,13 +502,25 @@ def _resolve_backend_cdp(env: dict, task_id: Optional[str], session_name: str =
|
||||
return None
|
||||
|
||||
provider_name = type(provider).__name__
|
||||
session: dict = {}
|
||||
|
||||
def _session_info(key: str) -> dict:
|
||||
session.update(_get_session_info(key) or {})
|
||||
return session
|
||||
|
||||
err = _export_session_cdp(
|
||||
env, _get_session_info, _backend_cache_key(task_id, session_name),
|
||||
env, _session_info, _backend_cache_key(task_id, session_name),
|
||||
lambda e: (f"Cloud browser provider {provider_name} failed to provide a session: {e}. "
|
||||
"Fix the provider configuration or switch backends via `hermes tools` → Browser Automation."),
|
||||
f"Cloud browser provider {provider_name} returned no CDP endpoint, so Browser Use mode "
|
||||
"cannot drive it. Switch to the built-in browser tools for this provider.",
|
||||
)
|
||||
if err and session.get("fallback_from_cloud"):
|
||||
# The provider failed (rate limit, quota, outage) and the session layer fell back to local
|
||||
# Chromium, as it does for the built-in tools; that session has no CDP URL until it launches.
|
||||
logger.warning("browser_exec: %s failed (%s); using local Chromium for this session",
|
||||
provider_name, session.get("fallback_reason"))
|
||||
return _resolve_managed_chromium_cdp(env, task_id, session_name)
|
||||
# A provider browser keyed bu-named-<name> is exclusive to this session — the
|
||||
# own-tab preamble would just leak a blank tab into it.
|
||||
if err is None and session_name:
|
||||
|
||||
Reference in new issue
Block a user