mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
browser_vault reached pages only through the task's CDP supervisor. Camofox (now a plugin) has no CDP endpoint, so every fill on a Camofox tab ended with "Could not determine the current page origin": the username from browser_vault list worked, the password never filled. ctx.register_browser_page_backend lets a plugin browser carry the vault's origin read, form inspection and fill script to its own page. Core keeps the secret contract: the exact-origin pre-check and in-page re-check, the Bot Desktop takeover check, an in-page try/catch around the secret script, and fixed failure text on that path. Registration follows the login-backend provenance rule (bundled, or catalog verified/official at its pin) and is refused under plugins.isolation: host. Consolidates the core half of #127179 and #135204 (the Camofox halves already shipped in the official plugin); the in-page wrapper follows #114414. Co-authored-by: Jonathan Bruce <jonathan.bruce369@gmail.com> Co-authored-by: clsferguson <cferguson@live.ca> Co-authored-by: Benjamin PERRY <benjaminperry6@yahoo.fr>
38 lines
1.8 KiB
Python
38 lines
1.8 KiB
Python
"""Browser page backend ABC: a browser that owns its pages outside Hermes's CDP session.
|
|
|
|
``browser_vault`` inspects and fills the page the agent is driving. For ``browser_exec`` that page sits
|
|
behind the task's CDP supervisor. A plugin browser with its own transport (Camofox's REST server) has
|
|
no CDP endpoint, so it registers one of these via :meth:`PluginContext.register_browser_page_backend`
|
|
and the vault evaluates its inspection, origin-check and fill scripts through it instead.
|
|
|
|
Core keeps the secret contract: it wraps every secret-bearing script so a page exception never reaches
|
|
the backend's error text, replaces any failure on that path with fixed text, and registers the filled
|
|
value with the browser-result redaction boundary. The backend only carries the script to its page.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import abc
|
|
from typing import Any
|
|
|
|
from agent.provider_base import ProviderBase
|
|
|
|
|
|
class BrowserPageBackend(ProviderBase):
|
|
"""A plugin browser whose live page ``browser_vault`` can evaluate JavaScript on."""
|
|
|
|
@abc.abstractmethod
|
|
def has_page(self, task_id: str) -> bool:
|
|
"""True when this backend already holds a live page for ``task_id`` (the agent navigated it).
|
|
|
|
Cheap and side-effect free: never open a tab or a session to answer. ``False`` lets the vault
|
|
fall back to the CDP session."""
|
|
|
|
@abc.abstractmethod
|
|
def evaluate(self, task_id: str, expression: str, *, secret: bool) -> Any:
|
|
"""Evaluate ``expression`` on the task's current page and return its value; raise on failure.
|
|
|
|
Never open a tab. With ``secret=True`` the expression embeds a credential: send it only over a
|
|
transport that keeps it out of argv and off the network in clear text (loopback or HTTPS), never
|
|
follow a redirect with it, and never log it. Exception text on that path is discarded by core."""
|