Автоматизация браузера
В Hermes Agent встроен полноценный набор инструментов для автоматизации браузера, и работать он может через несколько разных бэкендов:
- Облачный режим Browserbase через Browserbase — управляемые облачные браузеры и инструменты обхода антибот-защиты
- Облачный режим Browser Use через Browser Use — альтернативный облачный провайдер браузера
- Облачный режим Firecrawl через Firecrawl — облачные браузеры со встроенным скрейпингом
- Локальный режим Camofox через Camofox — локальный браузинг с защитой от детектирования (подмена отпечатка на базе Firefox)
- Локальный Chromium-family по CDP — подключение браузерных инструментов к вашему экземпляру Chrome, Brave, Chromium или Edge командой
/browser connect - Локальный режим браузера через CLI
agent-browserи установленный локально Chromium
В любом из режимов агент умеет переходить по сайтам, взаимодействовать с элементами страницы, заполнять формы и извлекать информацию.
Обзор
Страницы представлены в виде деревьев доступности (текстовых снимков), и для LLM-агентов такой формат подходит идеально. Интерактивные элементы получают ref-идентификаторы (вроде @e1, @e2), по которым агент кликает и вводит текст.
Что умеет набор:
- Облачное выполнение через несколько провайдеров — Browserbase, Browser Use или Firecrawl — без локального браузера
- Интеграция с локальным Chromium-family — подключение к запущенному Chrome, Brave, Chromium или Edge по CDP для браузинга вживую
- Встроенный стелс — случайные отпечатки, разгадывание CAPTCHA, резидентные прокси (Browserbase)
- Изоляция сессий — у каждой задачи своя браузерная сессия
- Автоматическая очистка — простаивающие сессии закрываются по таймауту
- Анализ зрением — скриншот плюс разбор через ИИ для понимания визуальной части
Установка
Если у вас оплачена подписка Nous Portal, автоматизацию браузера можно запускать через Tool Gateway вообще без отдельных API-ключей. На свежей установке выполните hermes setup --portal, чтобы войти и сразу включить все инструменты шлюза; в уже настроенной установке выберите провайдером браузера Nous Subscription через hermes model или hermes tools.
Облачный режим Browserbase
Чтобы пользоваться управляемыми облачными браузерами Browserbase, добавьте:
# Add to ~/.hermes/.env
BROWSERBASE_API_KEY=***
BROWSERBASE_PROJECT_ID=your-project-id-here
Учётные данные возьмите на browserbase.com.
Облачный режим Browser Use
Чтобы выбрать Browser Use облачным провайдером браузера, добавьте:
# Add to ~/.hermes/.env
BROWSER_USE_API_KEY=***
API-ключ получите на browser-use.com. Browser Use отдаёт облачный браузер через свой REST API. Если заданы учётные данные и Browserbase, и Browser Use, приоритет за Browserbase.
Облачный режим Firecrawl
Чтобы выбрать Firecrawl облачным провайдером браузера, добавьте:
# Add to ~/.hermes/.env
FIRECRAWL_API_KEY=fc-***
API-ключ получите на firecrawl.dev. Затем выберите Firecrawl провайдером браузера:
hermes setup tools
# → Browser Automation → Firecrawl
Необязательные настройки:
# Self-hosted Firecrawl instance (default: https://api.firecrawl.dev)
FIRECRAWL_API_URL=http://localhost:3002
# Session TTL in seconds (default: 300)
FIRECRAWL_BROWSER_TTL=600
Гибридная маршрутизация: облако для публичных URL, локаль для LAN/localhost
Когда настроен облачный провайдер, Hermes автоматически поднимает локальный sidecar на Chromium
для URL, которые резолвятся в приватный, loopback- или LAN-адрес (localhost, 127.0.0.1,
192.168.x.x, 10.x.x.x, 172.16-31.x.x, *.local, *.lan, *.internal,
IPv6-loopback ::1, link-local 169.254.x.x). Публичные URL в той же беседе по-прежнему идут через
облачного провайдера.
Так решается типичная ситуация «разрабатываю локально, но использую Browserbase»:
агент снимет скриншот вашей панели на http://localhost:3000 И заскрейпит
https://github.com, не заставляя вас переключать провайдеров или отключать SSRF-защиту.
Приватный URL облачный провайдер вообще не видит.
Функция включена по умолчанию. Чтобы её отключить (тогда все URL уходят настроенному облачному провайдеру, как раньше):
# ~/.hermes/config.yaml
browser:
cloud_provider: browserbase
auto_local_for_private_urls: false
При отключённой автомаршрутизации приватные URL отклоняются с сообщением
"Blocked: URL targets a private or internal address" — если только вы дополнительно не выставите
browser.allow_private_urls: true (это разрешит облачному провайдеру попробовать их открыть, но
обычно ничего не выйдет: тот же Browserbase до вашей LAN не дотянется).
Требования: локальный sidecar использует тот же CLI agent-browser, что и чисто локальный
режим, поэтому его нужно установить (hermes setup tools → Browser Automation
ставит его автоматически). Редиректы после перехода с публичного URL на приватный
адрес всё равно блокируются — трюк «редирект на внутренний адрес», чтобы достать вашу LAN через
публичный путь, не сработает.
Локальный режим Camofox
Camofox — это self-hosted сервер на Node.js, оборачивающий Camoufox (форк Firefox с подменой отпечатка на C++). Он даёт локальный браузинг с защитой от детектирования без зависимости от облака.
# Clone the Camofox browser server first
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser
# Build and start with Docker using the default container settings
# (auto-detects arch: aarch64 on M1/M2, x86_64 on Intel)
make up
# Stop and remove the default container
make down
# Force a clean rebuild (for example, after upgrading VERSION/RELEASE)
make reset
# Just download binaries without building
make fetch
# Override arch or version explicitly
make up ARCH=x86_64
make up VERSION=135.0.1 RELEASE=beta.24
make up сразу запускает контейнер по умолчанию. Если же вам нужны свои настройки рантайма — например, увеличенная куча Node, VNC или каталог с постоянным профилем — сначала соберите образ, а потом запустите его вручную:
# Build the image without starting the default container
make build
# Start with persistence, VNC live view, and a larger Node heap
mkdir -p ~/.camofox-docker
docker run -d \
--name camofox-browser \
--restart unless-stopped \
-p 9377:9377 \
-p 6080:6080 \
-p 5901:5900 \
-e CAMOFOX_PORT=9377 \
-e ENABLE_VNC=1 \
-e VNC_BIND=0.0.0.0 \
-e VNC_RESOLUTION=1920x1080 \
-e MAX_OLD_SPACE_SIZE=2048 \
-v ~/.camofox-docker:/root/.camofox \
camofox-browser:135.0.1-aarch64
С включённым VNC браузер запускается в headed-режиме, и за ним можно следить вживую в обычном браузере по адресу http://localhost:6080 (noVNC). Можно также подключить нативный VNC-клиент к localhost:5901.
Если вы уже запускали make up, остановите и удалите тот контейнер по умолчанию, прежде чем стартовать свой:
make down
# then run the custom docker run command above
Затем пропишите в ~/.hermes/.env:
CAMOFOX_URL=http://localhost:9377
Если Camofox крутится в Docker и вы хотите, чтобы он открывал веб-приложения с хост-машины, включите переписывание loopback-адресов. CAMOFOX_URL по-прежнему должен указывать на опубликованный на хосте control API, но URL страниц вроде http://127.0.0.1:3000 изнутри контейнера нужно открывать как http://host.docker.internal:3000:
# ~/.hermes/config.yaml
browser:
camofox:
rewrite_loopback_urls: true
loopback_host_alias: host.docker.internal # default; use a LAN IP if needed
Эквивалентные переменные окружения:
CAMOFOX_REWRITE_LOOPBACK_URLS=true
CAMOFOX_LOOPBACK_HOST_ALIAS=host.docker.internal
Переписывание затрагивает только URL переходов с loopback-хостами (localhost, 127.0.0.1, ::1). На CAMOFOX_URL оно не влияет. Для не-Docker установок Camofox оставьте его выключенным: там браузер и так работает на хосте, а loopback-URL корректны.
Или настройте через hermes tools → Browser Automation → Camofox.
Когда задан CAMOFOX_URL, все браузерные инструменты автоматически идут через Camofox вместо Browserbase или agent-browser.
Постоянные браузерные сессии
По умолчанию каждая сессия Camofox получает случайную личность — куки и входы в аккаунты не переживают перезапуск агента. Чтобы включить постоянные браузерные сессии, добавьте в ~/.hermes/config.yaml следующее:
browser:
camofox:
managed_persistence: true
Затем полностью перезапустите Hermes, чтобы новый конфиг подхватился.
Hermes читает browser.camofox.managed_persistence, а не managed_persistence на верхнем уровне. Частая ошибка — написать так:
# ❌ Wrong — Hermes ignores this
managed_persistence: trueЕсли флаг оказался не на том пути, Hermes молча откатывается к случайному эфемерному userId, и состояние входа теряется при каждой сессии.
Что делает Hermes
- Отправляет в Camofox детерминированный
userId, привязанный к профилю, чтобы сервер мог переиспользовать один и тот же профиль Firefox между сессиями. - Пропускает уничтожение контекста на стороне сервера при очистке, так что куки и входы сохраняются между задачами агента.
- Привязывает
userIdк активному профилю Hermes, поэтому разные профили Hermes получают разные браузерные профили (изоляция профилей).
Чего Hermes не делает
- Не навязывает персистентность серверу Camofox. Hermes лишь отправляет стабильный
userId; сервер обязан учесть его и сопоставить этомуuserIdкаталог постоянного профиля Firefox. - Если ваша сборка сервера Camofox считает каждый запрос эфемерным (например, всегда вызывает
browser.newContext()без загрузки сохранённого профиля), сделать такие сессии постоянными Hermes не сможет. Убедитесь, что запущена сборка Camofox с персистентностью профилей по userId.
Проверка работоспособности
- Запустите Hermes и свой сервер Camofox.
- В задаче с браузером откройте Google (или любой сайт со входом) и авторизуйтесь вручную.
- Завершите браузерную задачу штатно.
- Запустите новую браузерную задачу.
- Откройте тот же сайт снова — вы должны остаться авторизованы.
Если на шаге 5 вас разлогинило, сервер Camofox не учитывает стабильный userId. Перепроверьте путь в конфиге, подтвердите, что после правки config.yaml вы полностью перезапустили Hermes, и проверьте, что версия сервера Camofox поддерживает постоянные профили по пользователям.
Где хранится состояние
Стабильный userId Hermes выводит из привязанного к профилю каталога ~/.hermes/browser_auth/camofox/ (или его аналога внутри $HERMES_HOME для нестандартных профилей). Сами данные браузерного профиля живут на стороне сервера Camofox, с ключом по этому userId. Чтобы полностью сбросить постоянный профиль, очистите его на сервере Camofox и удалите соответствующий каталог состояния профиля Hermes.
Управляемые извне сессии Camofox
Когда видимым браузером Camofox управляет другое приложение (десктопный ассистент, своя интеграция, другой агент), настройте Hermes так, чтобы он работал внутри той же личности, а не поднимал собственный изолированный профиль.
Поведением управляют три параметра:
| Параметр | Переменная окружения | Эффект |
|---|---|---|
browser.camofox.user_id | CAMOFOX_USER_ID | userId Camofox, который Hermes использует при создании вкладок. Его установка переводит сессию в режим «управляется извне». |
browser.camofox.session_key | CAMOFOX_SESSION_KEY | sessionKey (он же listItemId), отправляемый при создании вкладки. Нужен для сопоставления с существующей вкладкой при адопции. Если не задан, по умолчанию берётся значение на каждую задачу. |
browser.camofox.adopt_existing_tab | CAMOFOX_ADOPT_EXISTING_TAB | Когда true, Hermes при первом использовании вызывает GET /tabs?userId=<user_id> и переиспользует существующую вкладку, прежде чем создавать новую. |
Переменные окружения имеют приоритет над config.yaml. Подходит любая из форм:
browser:
camofox:
user_id: shared-camofox
session_key: visible-tab
adopt_existing_tab: true
CAMOFOX_USER_ID=shared-camofox
CAMOFOX_SESSION_KEY=visible-tab
CAMOFOX_ADOPT_EXISTING_TAB=true
Что меняется при заданном user_id:
- Hermes пропускает разрушающую очистку в конце задачи (так же, как при
managed_persistence: true). Вкладка, куки и профиль другого приложения остаются целыми. - Hermes не вызывает
DELETE /sessions/<user_id>— этот эндпоинт стирает все пользовательские данные, так что он снёс бы сессию внешнего приложения, если бы сработал.
Как работает адопция вкладок (при adopt_existing_tab: true):
- На первом вызове браузерного инструмента после старта процесса Hermes делает запрос
GET /tabs?userId=<user_id>(таймаут 5 секунд). - Если в ответе есть вкладка с
listItemId == session_key, Hermes адоптирует самую свежесозданную в этой группе. - Иначе Hermes адоптирует самую свежесозданную вкладку пользователя (с любым
listItemId). - Если вкладок нет или запрос провалился, Hermes на следующей операции откатывается к созданию новой вкладки.
Адопция срабатывает только до тех пор, пока для сессии не заполнен tab_id. Если внешнее приложение закроет адоптированную вкладку посреди работы, следующий вызов браузерного инструмента выдаст ошибку Camofox — заново опрашивать свежую вкладку на каждом вызове Hermes не станет.
Как выбрать session_key: если хотите, чтобы Hermes надёжно цеплялся к конкретной существующей вкладке, выставьте session_key равным тому listItemId, который внешнее приложение использовало при её создании. Если оставить session_key пустым и задать только user_id, Hermes сгенерирует session_key на каждую задачу (task_<id>): куки и профиль он разделит с внешним приложением, но откроет рядом собственную вкладку, а не переиспользует существующую.
О параллелизме: внешнее приложение и Hermes могут одновременно управлять одним userId Camofox, но фокус по вкладкам между клиентами Camofox не координирует. Согласуйте владение на уровне приложения (например, внешнее приложение приостанавливается на время работы Hermes).
Просмотр вживую по VNC
Когда Camofox работает в headed-режиме (с видимым окном браузера), он публикует VNC-порт в ответе health-check. Hermes сам это обнаруживает и добавляет VNC-URL в ответы на навигацию, так что агент может поделиться ссылкой, по которой вы будете смотреть за браузером вживую.
Локальный браузер семейства Chromium по CDP (/browser connect)
Вместо облачного провайдера браузерные инструменты Hermes можно подключить к вашему запущенному Chrome, Brave, Chromium или Edge через Chrome DevTools Protocol (CDP). Пригодится, когда хочется в реальном времени видеть, что делает агент, работать со страницами, требующими ваших собственных куки и сессий, или не платить за облачный браузер.
/browser connect — это слэш-команда интерактивного CLI, шлюз её не диспетчеризует. Если попробовать запустить её внутри WebUI, Telegram, Discord или другого чата через шлюз, сообщение уйдёт агенту обычным текстом, и команда не выполнится. Запустите Hermes из терминала (hermes или hermes chat) и выполните /browser connect там.
В CLI используйте:
/browser connect # Auto-launch/connect to a local Chromium-family browser at http://127.0.0.1:9222
/browser connect ws://host:port # Connect to a specific CDP endpoint
/browser status # Check current connection
/browser disconnect # Detach and return to cloud/local mode
Если браузер ещё не запущен с удалённой отладкой, Hermes попытается сам поднять поддерживаемый Chromium-family браузер с флагом --remote-debugging-port=9222. Детектируются Brave, Google Chrome, Chromium и Microsoft Edge, включая типичные пути установки в Linux вроде /opt/brave-bin/brave и /snap/bin/brave.
Чтобы запустить Chromium-family браузер вручную с включённым CDP, используйте отдельный user-data-dir — тогда отладочный порт действительно поднимется, даже если браузер уже запущен с вашим обычным профилем:
# Linux — Brave
brave-browser \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.hermes/chrome-debug \
--no-first-run \
--no-default-browser-check &
# Linux — Google Chrome
google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.hermes/chrome-debug \
--no-first-run \
--no-default-browser-check &
# macOS — Brave
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.hermes/chrome-debug" \
--no-first-run \
--no-default-browser-check &
# macOS — Google Chrome
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.hermes/chrome-debug" \
--no-first-run \
--no-default-browser-check &Затем запустите CLI Hermes и выполните /browser connect.
Зачем нужен --user-data-dir? Без него запуск Chromium-family браузера при уже работающем обычном экземпляре обычно открывает новое окно в существующем процессе — а тот процесс стартовал без --remote-debugging-port, так что порт 9222 не откроется. Отдельный user-data-dir заставляет создать свежий процесс браузера, где отладочный порт реально слушает. Флаги --no-first-run --no-default-browser-check пропускают мастер первого запуска для нового профиля.
При подключении по CDP все браузерные инструменты (browser_navigate, browser_click и т. д.) работают с вашим живым экземпляром браузера, а не поднимают облачную сессию.
WSL2 + Chrome на Windows: лучше MCP, чем /browser connect
Если Hermes работает внутри WSL2, а окно Chrome, которым вы хотите управлять, запущено на хосте Windows, /browser connect часто оказывается не лучшим путём.
Почему:
/browser connectрассчитывает, что Hermes сам доберётся до пригодного CDP-эндпоинта- современные live-debugging сессии Chrome часто публикуют host-local эндпоинт, к которому из WSL не дотянуться так же напрямую, как до классического порта
9222 - даже когда Chrome на Windows доступен для отладки, чище всего отдать дело browser MCP-серверу на стороне Windows: пусть он подключится к Chrome, а Hermes общается с этим MCP-сервером
Для такой схемы предпочтительнее chrome-devtools-mcp через поддержку MCP в Hermes.
Практическую настройку смотрите в руководстве по MCP:
Локальный режим браузера
Если вы не задаёте никаких облачных учётных данных и не используете /browser connect, Hermes всё равно может работать с браузерными инструментами через локально установленный Chromium под управлением agent-browser.
Необязательные переменные окружения
# Residential proxies for better CAPTCHA solving (default: "true")
BROWSERBASE_PROXIES=true
# Advanced stealth with custom Chromium — requires Scale Plan (default: "false")
BROWSERBASE_ADVANCED_STEALTH=false
# Session reconnection after disconnects — requires paid plan (default: "true")
BROWSERBASE_KEEP_ALIVE=true
# Custom session timeout in seconds (max 21600 = 6 hours) (default: project default)
# Examples: 600 (10min), 1800 (30min), 21600 (6h max)
BROWSERBASE_SESSION_TIMEOUT=1800
# Inactivity timeout before auto-cleanup in seconds (default: 120)
BROWSER_INACTIVITY_TIMEOUT=120
# Extra Chromium launch flags (comma- or newline-separated). Hermes auto-injects
# `--no-sandbox,--disable-dev-shm-usage` when it detects root or AppArmor-restricted
# unprivileged user namespaces (Ubuntu 23.10+, DGX Spark, many container images),
# so most users don't need to set this. Set it manually only if you need a flag
# Hermes doesn't add automatically; setting it disables the auto-injection.
AGENT_BROWSER_ARGS=--no-sandbox
Установка CLI agent-browser
npm install -g agent-browser
# Or install locally in the repo:
npm install
Набор инструментов browser должен быть в списке toolsets вашего конфига или включён через hermes config set toolsets '["hermes-cli", "browser"]'.
Доступные инструменты
browser_navigate
Переход по URL. Вызывается раньше любого другого браузерного инструмента. Инициализирует сессию Browserbase.
Navigate to https://github.com/NousResearch
Для простого получения информации лучше брать web_search или web_extract — они быстрее и дешевле. Браузерные инструменты нужны там, где надо взаимодействовать со страницей (нажимать кнопки, заполнять формы, обрабатывать динамический контент).
browser_snapshot
Получить текстовый снимок дерева доступности текущей страницы. Возвращает интерактивные элементы с ref-идентификаторами вроде @e1, @e2 — их используют browser_click и browser_type.
full=false(по умолчанию): компактный вид, только интерактивные элементыfull=true: полное содержимое страницы
Снимки длиннее 8000 символов LLM автоматически сжимает в сводку.
browser_click
Кликнуть по элементу, заданному его ref-идентификатором из снимка.
Click @e5 to press the "Sign In" button
browser_type
Ввести текст в поле ввода. Сначала очищает поле, затем печатает новый текст.
Type "hermes agent" into the search field @e3
browser_scroll
Прокрутить страницу вверх или вниз, чтобы показать больше содержимого.
Scroll down to see more results
browser_press
Нажать клавишу. Полезно для отправки форм и навигации.
Press Enter to submit the form
Поддерживаемые клавиши: Enter, Tab, Escape, ArrowDown, ArrowUp и другие.
browser_back
Вернуться на предыдущую страницу в истории браузера.
browser_get_images
Перечислить все изображения текущей страницы с их URL и alt-текстом. Удобно, чтобы найти изображения для анализа.
browser_vision
Сделать скриншот и проанализировать его с помощью vision-ИИ. Применяйте, когда текстовый снимок не передаёт важную визуальную информацию — особенно для CAPTCHA, сложной вёрстки или визуальных проверок.
Скриншот сохраняется на диск, и путь к файлу возвращается вместе с разбором от ИИ. На мессенджер-платформах (Telegram, Discord, Slack, WhatsApp) можно попросить агента поделиться скриншотом — он отправится нативным фото-вложением через механизм MEDIA:.
What does the chart on this page show?
Скриншоты лежат в ~/.hermes/cache/screenshots/ и автоматически вычищаются через 24 часа.
browser_console
Получить вывод консоли браузера (сообщения log/warn/error) и неперехваченные исключения JavaScript с текущей страницы. Незаменимо для отлова тихих JS-ошибок, которых нет в дереве доступности.
Check the browser console for any JavaScript errors
Передайте clear=True, чтобы очистить консоль после чтения — тогда следующие вызовы покажут только новые сообщения.
browser_console также выполняет JavaScript, если вызвать его с аргументом expression — так же, как консоль DevTools. Результат приходит уже разобранным (JSON-сериализуемые объекты превращаются в dict, примитивные значения остаются примитивными).
browser_console(expression="document.querySelector('h1').textContent")
browser_console(expression="JSON.stringify(performance.timing)")
Когда для текущей сессии активен CDP-супервизор (обычно так у любой сессии, где browser_navigate отработал против бэкенда с поддержкой CDP), вычисление идёт по постоянному WebSocket супервизора — без затрат на запуск подпроцесса. В остальных случаях используется обычный путь через CLI agent-browser. Поведение в обоих случаях одинаковое, различается только задержка.
browser_cdp
Прямой проброс Chrome DevTools Protocol — запасной ход для браузерных операций, не покрытых другими инструментами. Используйте для работы с нативными диалогами, вычислений в области iframe, управления куки и сетью или любого CDP-метода, который понадобится агенту.
Доступен только когда CDP-эндпоинт достижим на старте сессии — то есть когда /browser connect подключился к запущенному Chrome, Brave, Chromium или Edge, либо когда в config.yaml задан browser.cdp_url. Локальный режим agent-browser по умолчанию, Camofox и облачные провайдеры (Browserbase, Browser Use, Firecrawl) пока не выставляют CDP этому инструменту — у облачных провайдеров есть CDP-URL на каждую сессию, но маршрутизация по живой сессии запланирована на потом.
Справочник методов CDP: https://chromedevtools.github.io/devtools-protocol/ — агент может через web_extract открыть страницу конкретного метода и посмотреть его параметры и форму ответа.
Типичные паттерны:
# List tabs (browser-level, no target_id)
browser_cdp(method="Target.getTargets")
# Handle a native JS dialog on a tab
browser_cdp(method="Page.handleJavaScriptDialog",
params={"accept": true, "promptText": ""},
target_id="<tabId>")
# Evaluate JS in a specific tab
browser_cdp(method="Runtime.evaluate",
params={"expression": "document.title", "returnByValue": true},
target_id="<tabId>")
# Get all cookies
browser_cdp(method="Network.getAllCookies")
Методы уровня браузера (Target.*, Browser.*, Storage.*) обходятся без target_id. Методам уровня страницы (Page.*, Runtime.*, DOM.*, Emulation.*) нужен target_id из Target.getTargets. Каждый вызов без состояния независим — сессии между вызовами не сохраняются.
Кросс-доменные iframe: передайте frame_id (из browser_snapshot.frame_tree.children[], где is_oopif=true), чтобы направить CDP-вызов через живую сессию супервизора для этого iframe. Именно так Runtime.evaluate внутри кросс-доменного iframe работает в Browserbase, где stateless-подключения CDP упёрлись бы в истечение подписанного URL. Пример:
browser_cdp(
method="Runtime.evaluate",
params={"expression": "document.title", "returnByValue": True},
frame_id="<frame_id from browser_snapshot>",
)
Для iframe того же домена frame_id не нужен — используйте document.querySelector('iframe').contentDocument из Runtime.evaluate верхнего уровня.
browser_dialog
Отвечает на нативный JS-диалог (alert / confirm / prompt / beforeunload). До появления этого инструмента диалоги молча блокировали JS-поток страницы, и последующие вызовы browser_* зависали или падали; теперь агент видит ожидающие диалоги в выводе browser_snapshot и отвечает на них явно.
Порядок действий:
- Вызовите
browser_snapshot. Если диалог блокирует страницу, он показывается какpending_dialogs: [{"id": "d-1", "type": "alert", "message": "..."}]. - Вызовите
browser_dialog(action="accept")илиbrowser_dialog(action="dismiss"). Для диалоговprompt()передайтеprompt_text="...", чтобы задать ответ. - Снимите снимок повторно —
pending_dialogsпуст, JS-поток страницы возобновился.
Обнаружение происходит автоматически через постоянный CDP-супервизор — один WebSocket на задачу, подписанный на события Page/Runtime/Target. Супервизор ещё и наполняет в снимке поле frame_tree, чтобы агент видел структуру iframe текущей страницы, включая кросс-доменные (OOPIF) iframe.
Матрица доступности:
| Бэкенд | Обнаружение через pending_dialogs | Ответ (инструмент browser_dialog) |
|---|---|---|
Локальный Chrome через /browser connect или browser.cdp_url | ✓ | ✓ полный сценарий |
| Browserbase | ✓ | ✓ полный сценарий (через внедрённый XHR-мост) |
| Camofox / локальный agent-browser по умолчанию | ✗ | ✗ (нет CDP-эндпоинта) |
Как это работает в Browserbase. CDP-прокси Browserbase автоматически закрывает настоящие нативные диалоги на стороне сервера примерно за 10 мс, поэтому Page.handleJavaScriptDialog нам не подходит. Супервизор через Page.addScriptToEvaluateOnNewDocument внедряет небольшой скрипт, который подменяет window.alert/confirm/prompt синхронным XHR. Эти XHR мы перехватываем через Fetch.enable — JS-поток страницы остаётся заблокирован на XHR, пока мы не вызовем Fetch.fulfillRequest с ответом агента. Возвращаемые значения prompt() без изменений уходят обратно в JS страницы.
Политика диалогов настраивается в config.yaml в секции browser.dialog_policy:
| Политика | Поведение |
|---|---|
must_respond (по умолчанию) | Перехватить, показать в снимке, дождаться явного вызова browser_dialog(). Защитное автозакрытие через browser.dialog_timeout_s (по умолчанию 300 с), чтобы забагованный агент не завис навсегда. |
auto_dismiss | Перехватить, тут же закрыть. Диалог агент всё равно видит в истории browser_state, но реагировать не обязан. |
auto_accept | Перехватить, тут же принять. Удобно при навигации по страницам с назойливыми запросами beforeunload. |
Дерево фреймов внутри browser_snapshot.frame_tree ограничено 30 фреймами и глубиной OOPIF 2, чтобы payload не разрастался на страницах, забитых рекламой. При достижении лимитов всплывает флаг truncated: true; если агенту нужно полное дерево, он может вызвать browser_cdp с Page.getFrameTree.
Практические примеры
Заполнение веб-формы
User: Sign up for an account on example.com with my email john@example.com
Agent workflow:
1. browser_navigate("https://example.com/signup")
2. browser_snapshot() → sees form fields with refs
3. browser_type(ref="@e3", text="john@example.com")
4. browser_type(ref="@e5", text="SecurePass123")
5. browser_click(ref="@e8") → clicks "Create Account"
6. browser_snapshot() → confirms success
Изучение динамического контента
User: What are the top trending repos on GitHub right now?
Agent workflow:
1. browser_navigate("https://github.com/trending")
2. browser_snapshot(full=true) → reads trending repo list
3. Returns formatted results
Запись сессий
Браузерные сессии можно автоматически записывать в видеофайлы WebM:
browser:
record_sessions: true # default: false
При включении запись стартует автоматически на первом browser_navigate и сохраняется в ~/.hermes/browser_recordings/, когда сессия закрывается. Работает и в локальном, и в облачном (Browserbase) режиме. Записи старше 72 часов вычищаются автоматически.
Стелс-возможности
Browserbase даёт автоматический стелс:
| Возможность | По умолчанию | Примечания |
|---|---|---|
| Базовый стелс | Всегда включён | Случайные отпечатки, рандомизация viewport, разгадывание CAPTCHA |
| Резидентные прокси | Включены | Маршрутизация через резидентные IP для лучшего доступа |
| Продвинутый стелс | Выключен | Своя сборка Chromium, требуется Scale Plan |
| Keep Alive | Включён | Переподключение сессии после сетевых сбоев |
Если платные функции на вашем тарифе недоступны, Hermes автоматически откатывается — сначала отключает keepAlive, затем прокси — так что браузинг работает и на бесплатных тарифах.
Управление сессиями
- Каждая задача получает изолированную браузерную сессию через Browserbase
- Сессии автоматически вычищаются после простоя (по умолчанию 2 минуты)
- Фоновый поток проверяет устаревшие сессии каждые 30 секунд
- При выходе процесса запускается аварийная очистка, чтобы не оставлять осиротевшие сессии
- Сессии освобождаются через API Browserbase (статус
REQUEST_RELEASE)
Ограничения
- Текстовое взаимодействие — опора на дерево доступности, а не на пиксельные координаты
- Размер снимка — большие страницы могут обрезаться или сжиматься LLM на отметке 8000 символов
- Таймаут сессии — облачные сессии истекают по настройкам тарифа вашего провайдера
- Стоимость — облачные сессии расходуют кредиты провайдера; сессии автоматически вычищаются при завершении беседы или после простоя. Для бесплатного локального браузинга используйте
/browser connect. - Нет скачивания файлов — скачивать файлы из браузера нельзя