mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
revert(browser_exec): drop pending_dialogs from results
Live probe: browser-harness tracks native dialogs in its own daemon (Page.javascriptDialogOpening on its own target session) and the task's CDP supervisor never captured one on harness-driven pages, so the field had no working source. browser_dialog's text now describes what it actually does: answer a supervisor-held dialog, its error listing candidate ids.
This commit is contained in:
1 parent
d34d78523d
commit
e9bdd57dbc
3 files changed
+7
-22
No files matched your search
@@ -1,7 +1,7 @@
|
||||
"""Agent-facing tool: respond to a native JS dialog captured by the CDP supervisor.
|
||||
|
||||
Response-only: the agent reads ``pending_dialogs`` from a ``browser_exec`` result,
|
||||
then calls ``browser_dialog(action=...)``. Gated on ``_browser_cdp_check`` so it
|
||||
Response-only: the agent calls ``browser_dialog(action=...)`` for a dialog the
|
||||
supervisor holds; with several queued, the error names the candidate ids. Gated on ``_browser_cdp_check`` so it
|
||||
appears together with ``browser_cdp``. Design: ``website/docs/developer-guide/browser-supervisor.md``.
|
||||
"""
|
||||
|
||||
@@ -18,15 +18,14 @@ BROWSER_DIALOG_SCHEMA: dict[str, Any] = {
|
||||
"description": (
|
||||
"Respond to a native JavaScript dialog (alert / confirm / prompt / "
|
||||
"beforeunload) that is currently blocking the page.\n\n"
|
||||
"**Workflow:** when a dialog is open, the browser_exec result lists "
|
||||
"it in the ``pending_dialogs`` field with ``id``, ``type``, "
|
||||
"and ``message``. Then call this tool with ``action='accept'`` or "
|
||||
"**Workflow:** when a page is blocked by a native dialog the CDP "
|
||||
"supervisor captured, call this tool with ``action='accept'`` or "
|
||||
"``action='dismiss'``.\n\n"
|
||||
"**Prompt dialogs:** pass ``prompt_text`` to supply the response "
|
||||
"string. Ignored for alert/confirm/beforeunload.\n\n"
|
||||
"**Multiple dialogs:** if more than one dialog is queued (rare — "
|
||||
"happens when a second dialog fires while the first is still open), "
|
||||
"pass ``dialog_id`` from ``pending_dialogs`` to disambiguate.\n\n"
|
||||
"pass ``dialog_id`` (the error lists the candidates) to disambiguate.\n\n"
|
||||
"**Availability:** only present when a CDP endpoint is attached — "
|
||||
"a local Chromium-family browser via ``/browser connect``, or "
|
||||
"``browser.cdp_url`` in config.yaml."
|
||||
@@ -55,7 +54,7 @@ BROWSER_DIALOG_SCHEMA: dict[str, Any] = {
|
||||
"type": "string",
|
||||
"description": (
|
||||
"Specific dialog to respond to, from "
|
||||
"``pending_dialogs[].id``. Required "
|
||||
"the candidate ids a previous call listed. Required "
|
||||
"only when multiple dialogs are queued."
|
||||
),
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ One ``CDPSupervisor`` per Hermes ``task_id`` with a reachable CDP endpoint: one
|
||||
persistent WebSocket, ``Page`` / ``Runtime`` / ``Target`` events on every attached
|
||||
session (top page + auto-attached OOPIF / worker targets), pending dialogs + frame
|
||||
tree exposed via a thread-safe snapshot. Not in the tool schema — output reaches the
|
||||
agent via ``browser_exec`` results (``pending_dialogs``) / ``browser_dialog``. Dialog capture and frame tracking
|
||||
agent via ``browser_dialog``. Dialog capture and frame tracking
|
||||
are mixins (``browser_supervisor_dialogs`` / ``browser_supervisor_frames``).
|
||||
Design spec: ``website/docs/developer-guide/browser-supervisor.md``.
|
||||
"""
|
||||
|
||||
@@ -666,19 +666,6 @@ def _reload_if_republished(env: dict, generation: int) -> None:
|
||||
_reload_daemons([daemon])
|
||||
|
||||
|
||||
def _pending_dialogs(task_id: Optional[str]) -> dict:
|
||||
"""Native dialogs the task's CDP supervisor is holding open (``browser_dialog`` answers them), page text
|
||||
redacted like every other browser output."""
|
||||
from agent.redact import redact_sensitive_text
|
||||
from tools.browser_supervisor import SUPERVISOR_REGISTRY
|
||||
supervisor = SUPERVISOR_REGISTRY.get(task_id or "default")
|
||||
snapshot = supervisor.snapshot() if supervisor is not None else None
|
||||
if snapshot is None or not snapshot.active or not snapshot.pending_dialogs:
|
||||
return {}
|
||||
return {"pending_dialogs": [{k: redact_sensitive_text(v, force=True) if isinstance(v, str) else v
|
||||
for k, v in d.to_dict().items()} for d in snapshot.pending_dialogs]}
|
||||
|
||||
|
||||
def _take_real_profile_note(route_key: str) -> dict:
|
||||
"""The fallback note for the first result this route returns after falling back, then nothing."""
|
||||
if route_key not in _real_profile_fallback or route_key in _real_profile_note_delivered:
|
||||
@@ -783,7 +770,6 @@ def browser_exec(code: str, session: str = "", timeout_s: int = _DEFAULT_TIMEOUT
|
||||
if session:
|
||||
result["session"] = session
|
||||
result.update(_take_real_profile_note(route_key))
|
||||
result.update(_pending_dialogs(task_id))
|
||||
stderr = redact_sensitive_text((proc.stderr or "").strip(), force=True)
|
||||
if len(stderr) > _STDERR_CAP_CHARS:
|
||||
stderr = stderr[:_STDERR_CAP_CHARS] + "\n… (stderr truncated)"
|
||||
|
||||
Reference in new issue
Block a user