mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-26 01:01:40 +00:00
feat(browser): multi-provider cloud browser support + Browser Use integration
Introduce a cloud browser provider abstraction so users can switch between Local Browser, Browserbase, and Browser Use (or future providers) via hermes tools / hermes setup. Cloud browser providers are behind an ABC (tools/browser_providers/base.py) so adding a new provider is a single-file addition with no changes to browser_tool.py internals. Changes: - tools/browser_providers/ package with ABC, Browserbase extraction, and Browser Use provider - browser_tool.py refactored to use _PROVIDER_REGISTRY + _get_cloud_provider() (cached) instead of hardcoded _is_local_mode() / _create_browserbase_session() - tools_config.py: generic _is_provider_active() / _detect_active_provider_index() replace TTS-only logic; Browser Use added as third browser option - config.py: BROWSER_USE_API_KEY added to OPTIONAL_ENV_VARS + show_config + allowlist - subprocess pipe hang fix: agent-browser daemon inherits pipe fds, communicate() blocks. Replaced with Popen + temp files. Original PR: #1208 Co-authored-by: ShawnPana <shawnpana@users.noreply.github.com>
This commit is contained in:
parent
4768ea624d
commit
d44b6b7f1b
7 changed files with 567 additions and 303 deletions
59
tools/browser_providers/base.py
Normal file
59
tools/browser_providers/base.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"""Abstract base class for cloud browser providers."""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict
|
||||
|
||||
|
||||
class CloudBrowserProvider(ABC):
|
||||
"""Interface for cloud browser backends (Browserbase, Steel, etc.).
|
||||
|
||||
Implementations live in sibling modules and are registered in
|
||||
``browser_tool._PROVIDER_REGISTRY``. The user selects a provider via
|
||||
``hermes setup`` / ``hermes tools``; the choice is persisted as
|
||||
``config["browser"]["cloud_provider"]``.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def provider_name(self) -> str:
|
||||
"""Short, human-readable name shown in logs and diagnostics."""
|
||||
|
||||
@abstractmethod
|
||||
def is_configured(self) -> bool:
|
||||
"""Return True when all required env vars / credentials are present.
|
||||
|
||||
Called at tool-registration time (``check_browser_requirements``) to
|
||||
gate availability. Must be cheap — no network calls.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def create_session(self, task_id: str) -> Dict[str, object]:
|
||||
"""Create a cloud browser session and return session metadata.
|
||||
|
||||
Must return a dict with at least::
|
||||
|
||||
{
|
||||
"session_name": str, # unique name for agent-browser --session
|
||||
"bb_session_id": str, # provider session ID (for close/cleanup)
|
||||
"cdp_url": str, # CDP websocket URL
|
||||
"features": dict, # feature flags that were enabled
|
||||
}
|
||||
|
||||
``bb_session_id`` is a legacy key name kept for backward compat with
|
||||
the rest of browser_tool.py — it holds the provider's session ID
|
||||
regardless of which provider is in use.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def close_session(self, session_id: str) -> bool:
|
||||
"""Release / terminate a cloud session by its provider session ID.
|
||||
|
||||
Returns True on success, False on failure. Should not raise.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def emergency_cleanup(self, session_id: str) -> None:
|
||||
"""Best-effort session teardown during process exit.
|
||||
|
||||
Called from atexit / signal handlers. Must tolerate missing
|
||||
credentials, network errors, etc. — log and move on.
|
||||
"""
|
||||
Loading…
Add table
Add a link
Reference in a new issue