본문으로 건너뛰기

브라우저 자동화

Hermes Agent에는 여러 backend option을 지원하는 완전한 browser automation toolset이 포함되어 있습니다.

  • Browserbase cloud mode - Browserbase를 통해 managed cloud browser와 anti-bot tooling을 사용합니다.
  • Browser Use cloud mode - Browser Use를 대체 cloud browser provider로 사용합니다.
  • Firecrawl cloud mode - Firecrawl을 통해 built-in scraping이 있는 cloud browser를 사용합니다.
  • Camofox local mode - Camofox를 통해 local anti-detection browsing을 사용합니다. Firefox 기반 fingerprint spoofing입니다.
  • Local Chrome via CDP - /browser connect로 browser tools를 사용자의 Chrome instance에 연결합니다.
  • Local browser mode - agent-browser CLI와 로컬 Chromium 설치를 사용합니다.

모든 mode에서 agent는 웹사이트를 탐색하고, page element와 상호작용하고, form을 채우고, 정보를 추출할 수 있습니다.

개요

페이지는 accessibility tree(text-based snapshot)로 표현됩니다. 따라서 LLM agent가 다루기 좋습니다. 상호작용 가능한 element에는 @e1, @e2 같은 ref ID가 붙고, agent는 이 ID를 사용해 click과 typing을 수행합니다.

주요 기능:

  • Multi-provider cloud execution - Browserbase, Browser Use, Firecrawl을 사용할 수 있으며 로컬 browser가 필요 없습니다.
  • Local Chrome integration - 실행 중인 Chrome에 CDP로 attach하여 직접 보이는 browser를 조작할 수 있습니다.
  • Built-in stealth - random fingerprint, CAPTCHA solving, residential proxy(Browserbase)
  • Session isolation - 각 task는 고유한 browser session을 사용합니다.
  • Automatic cleanup - inactive session은 timeout 후 닫힙니다.
  • Vision analysis - screenshot + AI analysis로 시각 정보를 이해합니다.

설정

Nous 구독자

유료 Nous Portal 구독이 있다면 별도 API key 없이 **Tool Gateway**를 통해 browser automation을 사용할 수 있습니다. hermes model 또는 hermes tools를 실행해 활성화하세요.

Browserbase cloud mode

Browserbase가 관리하는 cloud browser를 사용하려면 다음을 추가합니다.

# Add to ~/.hermes/.env
BROWSERBASE_API_KEY=***
BROWSERBASE_PROJECT_ID=your-project-id-here

credential은 browserbase.com에서 받을 수 있습니다.

Browser Use cloud mode

Browser Use를 cloud browser provider로 사용하려면 다음을 추가합니다.

# Add to ~/.hermes/.env
BROWSER_USE_API_KEY=***

API key는 browser-use.com에서 받을 수 있습니다. Browser Use는 REST API를 통해 cloud browser를 제공합니다. Browserbase와 Browser Use credential이 모두 설정되어 있으면 Browserbase가 우선합니다.

Firecrawl cloud mode

Firecrawl을 cloud browser provider로 사용하려면 다음을 추가합니다.

# Add to ~/.hermes/.env
FIRECRAWL_API_KEY=fc-***

API key는 firecrawl.dev에서 받을 수 있습니다. 그런 다음 browser provider로 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

Hybrid routing: public URL은 cloud, LAN/localhost는 local

cloud provider가 설정되어 있어도, URL이 private/loopback/LAN address로 resolve되면 Hermes는 local Chromium sidecar를 자동으로 띄웁니다. 대상에는 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가 포함됩니다. public URL은 같은 대화 안에서도 계속 cloud provider를 사용합니다.

이 기능은 "로컬에서 개발 중이지만 Browserbase도 쓰고 있는" 일반적인 workflow를 해결합니다. agent는 provider를 바꾸거나 SSRF guard를 끄지 않고도 http://localhost:3000의 dashboard를 screenshot으로 확인하고, 동시에 https://github.com을 scrape할 수 있습니다. cloud provider는 private URL을 보지 않습니다.

이 기능은 기본으로 켜져 있습니다. 끄려면, 즉 모든 URL을 이전처럼 설정된 cloud provider로 보내려면 다음을 설정합니다.

# ~/.hermes/config.yaml
browser:
cloud_provider: browserbase
auto_local_for_private_urls: false

auto-routing을 끄면 private URL은 "Blocked: URL targets a private or internal address"로 거부됩니다. browser.allow_private_urls: true도 설정하면 cloud provider가 접근을 시도하게 할 수 있지만, Browserbase 같은 provider는 보통 사용자의 LAN에 도달할 수 없습니다.

요구 사항: local sidecar는 순수 local mode와 같은 agent-browser CLI를 사용하므로 설치되어 있어야 합니다. (hermes setup tools → Browser Automation이 자동 설치합니다.) public URL에서 private address로 redirect되는 경우는 여전히 차단됩니다. redirect-to-internal trick으로 public path를 통해 LAN에 접근할 수는 없습니다.

Camofox local mode

Camofox는 Camoufox(C++ fingerprint spoofing이 들어간 Firefox fork)를 감싼 self-hosted Node.js server입니다. cloud dependency 없이 local anti-detection browsing을 제공합니다.

# 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은 default container를 즉시 시작합니다. 더 큰 Node heap, VNC, persistent profile directory 같은 custom runtime setting이 필요하면 먼저 image만 build한 뒤 직접 실행합니다.

# 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가 켜져 있으면 browser는 headed mode로 실행되며, http://localhost:6080(noVNC)에서 browser를 실시간으로 볼 수 있습니다. native VNC client로 localhost:5901에 연결할 수도 있습니다.

이미 make up을 실행했다면 custom container를 시작하기 전에 default container를 중지하고 제거하세요.

make down
# then run the custom docker run command above

그런 다음 ~/.hermes/.env에 설정합니다.

CAMOFOX_URL=http://localhost:9377

또는 hermes tools → Browser Automation → Camofox에서 설정합니다.

CAMOFOX_URL이 설정되어 있으면 모든 browser tool은 Browserbase나 agent-browser 대신 Camofox를 통해 route됩니다.

Persistent browser sessions

기본적으로 각 Camofox session은 random identity를 받습니다. cookie와 login은 agent restart를 넘어 유지되지 않습니다. persistent browser session을 활성화하려면 ~/.hermes/config.yaml에 다음을 추가합니다.

browser:
camofox:
managed_persistence: true

그런 다음 Hermes를 완전히 재시작해 새 config가 반영되게 합니다.

nested path가 중요합니다

Hermes는 top-level managed_persistence가 아니라 browser.camofox.managed_persistence를 읽습니다. 흔한 실수는 다음처럼 쓰는 것입니다.

# ❌ Wrong — Hermes ignores this
managed_persistence: true

flag가 잘못된 path에 있으면 Hermes는 조용히 random ephemeral userId로 fallback하며, 매 session마다 login state가 사라집니다.

Hermes가 하는 일
  • Camofox가 session 간 같은 Firefox profile을 재사용할 수 있도록 deterministic profile-scoped userId를 보냅니다.
  • cleanup 때 server-side context destruction을 건너뛰어 cookie와 login이 agent task 사이에 유지되게 합니다.
  • userId를 active Hermes profile에 scope하므로, 서로 다른 Hermes profile은 서로 다른 browser profile을 갖습니다(profile isolation).
Hermes가 하지 않는 일
  • Camofox server에 persistence를 강제하지 않습니다. Hermes는 stable userId만 보냅니다. server가 그 userId를 persistent Firefox profile directory에 매핑해 주어야 합니다.
  • Camofox server build가 모든 request를 ephemeral로 처리한다면(예: 저장된 profile을 불러오지 않고 항상 browser.newContext()를 호출), Hermes만으로 session을 persist시킬 수 없습니다. userId-based profile persistence를 구현한 Camofox build를 실행 중인지 확인하세요.
동작 확인
  1. Hermes와 Camofox server를 시작합니다.
  2. browser task에서 Google 또는 login site를 열고 직접 sign in합니다.
  3. browser task를 정상 종료합니다.
  4. 새 browser task를 시작합니다.
  5. 같은 site를 다시 엽니다. 여전히 sign in 상태여야 합니다.

5단계에서 logout되어 있다면 Camofox server가 stable userId를 반영하지 않는 것입니다. config path를 다시 확인하고, config.yaml 수정 후 Hermes를 완전히 재시작했는지 확인하고, Camofox server version이 persistent per-user profile을 지원하는지 검증하세요.

state 위치

Hermes는 profile-scoped directory인 ~/.hermes/browser_auth/camofox/에서 stable userId를 파생합니다. default profile이 아니면 $HERMES_HOME 아래의 동등한 경로를 사용합니다. 실제 browser profile data는 Camofox server 쪽에 있으며 해당 userId를 key로 합니다. persistent profile을 완전히 reset하려면 Camofox server에서 profile을 지우고, 해당 Hermes profile의 state directory도 제거합니다.

외부에서 관리되는 Camofox session

다른 app(Desktop assistant, custom integration, 다른 agent)이 visible Camofox browser를 조작하고 있다면, Hermes가 자체 isolated profile을 만들지 않고 같은 identity 안에서 동작하도록 설정할 수 있습니다.

세 가지 knob이 동작을 제어합니다.

SettingEnv varEffect
browser.camofox.user_idCAMOFOX_USER_IDtab을 만들 때 Hermes가 사용하는 Camofox userId. 이 값을 설정하면 session이 "externally managed" mode로 들어갑니다.
browser.camofox.session_keyCAMOFOX_SESSION_KEYtab 생성 시 보내는 sessionKey(a.k.a. listItemId). adoption 시 기존 tab을 matching하는 데 사용됩니다. 설정하지 않으면 task별 값이 기본값입니다.
browser.camofox.adopt_existing_tabCAMOFOX_ADOPT_EXISTING_TABtrue이면 Hermes가 첫 사용 시 GET /tabs?userId=<user_id>를 호출하고, 새 tab을 만들기 전에 기존 tab을 재사용합니다.

env var가 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는 task 종료 시 destructive cleanup을 건너뜁니다. (managed_persistence: true와 동일) 다른 app의 tab/cookie/profile이 유지됩니다.
  • Hermes는 DELETE /sessions/<user_id>를 호출하지 않습니다. 이 endpoint는 모든 user data를 지우므로, 호출되면 외부 app의 session까지 제거됩니다.

tab adoption 동작(adopt_existing_tab: true일 때):

  1. process start 후 첫 browser tool call에서 Hermes가 GET /tabs?userId=<user_id>를 호출합니다. timeout은 5초입니다.
  2. response 안에 listItemId == session_key인 tab이 있으면, Hermes는 그 group에서 가장 최근에 생성된 tab을 adopt합니다.
  3. 없으면 해당 user의 가장 최근 tab을 adopt합니다. listItemId 값은 상관없습니다.
  4. tab이 없거나 request가 실패하면, 다음 operation에서 새 tab을 만드는 방식으로 fallback합니다.

adoption은 session에 tab_id가 채워질 때까지만 실행됩니다. 외부 app이 실행 중간에 adopted tab을 닫으면 다음 browser tool call에서 Camofox error가 드러납니다. Hermes는 매 call마다 새 tab을 찾기 위해 다시 poll하지 않습니다.

session_key 선택: Hermes가 특정 기존 tab에 안정적으로 attach하길 원하면, 외부 app이 그 tab을 만들 때 사용한 listItemIdsession_key로 설정하세요. session_key를 비워 두고 user_id만 설정하면 Hermes는 task별 session_key(task_<id>)를 생성합니다. 이 경우 외부 app과 cookie/profile은 공유하지만, 기존 tab을 재사용하지 않고 자기 tab을 따로 엽니다.

Concurrency note: 외부 app과 Hermes가 같은 Camofox userId를 동시에 drive할 수는 있지만, Camofox는 client 간 per-tab focus를 조정하지 않습니다. application layer에서 ownership을 조정하세요. 예를 들어 Hermes가 실행되는 동안 외부 app을 pause합니다.

VNC live view

Camofox가 headed mode(보이는 browser window)로 실행되면 health check response에 VNC port를 노출합니다. Hermes는 이를 자동으로 발견하고 navigation response에 VNC URL을 포함하므로, agent가 사용자가 live browser를 볼 수 있는 link를 공유할 수 있습니다.

Local Chrome via CDP(/browser connect)

cloud provider 대신 Chrome DevTools Protocol(CDP)을 통해 Hermes browser tools를 사용자의 실행 중인 Chrome instance에 attach할 수 있습니다. agent가 무엇을 하는지 실시간으로 보고 싶거나, 사용자의 cookie/session이 필요한 page와 상호작용하거나, cloud browser 비용을 피하고 싶을 때 유용합니다.

노트

/browser connectinteractive-CLI slash command입니다. gateway가 dispatch하지 않습니다. WebUI, Telegram, Discord 또는 다른 gateway chat 안에서 실행하려고 하면 메시지가 plain text로 agent에게 전달되고 command는 실행되지 않습니다. terminal에서 Hermes(hermes 또는 hermes chat)를 시작한 뒤 거기서 /browser connect를 실행하세요.

CLI에서 다음을 사용합니다.

/browser connect              # Connect to Chrome at ws://localhost: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

Chrome이 remote debugging으로 이미 실행 중이 아니라면 Hermes가 --remote-debugging-port=9222로 자동 launch를 시도합니다.

CDP를 켜고 Chrome을 수동 시작하려면 dedicated user-data-dir를 사용하세요. 일반 profile로 이미 Chrome이 실행 중이어도 debug port가 실제로 열리게 하기 위해서입니다.

# Linux
google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=$HOME/.hermes/chrome-debug \
--no-first-run \
--no-default-browser-check &

# macOS
"/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 &

그런 다음 Hermes CLI를 실행하고 /browser connect를 실행합니다.

--user-data-dir가 필요한가요? 이 옵션 없이 일반 Chrome instance가 이미 실행 중인 상태에서 Chrome을 launch하면, 보통 기존 process에 새 window만 열립니다. 기존 process는 --remote-debugging-port로 시작되지 않았으므로 port 9222가 열리지 않습니다. dedicated user-data-dir는 debug port가 실제로 listen하는 새 Chrome process를 강제로 만듭니다. --no-first-run --no-default-browser-check는 fresh profile의 first-launch wizard를 건너뜁니다.

CDP로 연결되어 있으면 모든 browser tool(browser_navigate, browser_click 등)은 cloud session을 새로 띄우지 않고 사용자의 live Chrome instance에서 동작합니다.

WSL2 + Windows Chrome: /browser connect보다 MCP 권장

Hermes는 WSL2 안에서 실행 중이고 제어하려는 Chrome window는 Windows host에서 실행 중이라면, /browser connect가 가장 좋은 경로가 아닌 경우가 많습니다.

이유:

  • /browser connect는 Hermes 자체가 usable CDP endpoint에 접근할 수 있다고 가정합니다.
  • modern Chrome live-debugging session은 종종 host-local endpoint를 노출하며, classic 9222 port처럼 WSL에서 직접 접근되지 않을 수 있습니다.
  • Windows Chrome이 debuggable하더라도, Windows-side browser MCP server가 Chrome에 attach하고 Hermes가 그 MCP server와 통신하게 하는 방식이 가장 깔끔한 경우가 많습니다.

이 설정에서는 Hermes MCP support를 통해 chrome-devtools-mcp를 사용하는 것을 권장합니다.

실제 setup은 MCP guide를 참고하세요.

Local browser mode

cloud credential을 설정하지 않았고 /browser connect도 사용하지 않는다면, Hermes는 agent-browser가 drive하는 local Chromium 설치를 통해 browser tools를 사용할 수 있습니다.

Optional Environment Variables

# 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 milliseconds (default: project default)
# Examples: 600000 (10min), 1800000 (30min)
BROWSERBASE_SESSION_TIMEOUT=600000

# 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

agent-browser CLI 설치

npm install -g agent-browser
# Or install locally in the repo:
npm install
정보

browser toolset은 config의 toolsets list에 포함되어 있거나 hermes config set toolsets '["hermes-cli", "browser"]'로 활성화되어 있어야 합니다.

사용 가능한 도구

browser_navigate

URL로 이동합니다. 다른 browser tool보다 먼저 호출해야 합니다. Browserbase session을 초기화합니다.

Navigate to https://github.com/NousResearch

단순한 정보 retrieval에는 web_search 또는 web_extract가 더 빠르고 저렴합니다. page와 상호작용해야 할 때(click button, form 입력, dynamic content 처리) browser tools를 사용하세요.

browser_snapshot

현재 page의 accessibility tree를 text-based snapshot으로 가져옵니다. browser_click, browser_type에서 사용할 수 있도록 @e1, @e2 같은 ref ID가 붙은 interactive element를 반환합니다.

  • full=false(기본값): interactive element만 보여 주는 compact view
  • full=true: 전체 page content

8000자를 넘는 snapshot은 LLM이 자동으로 summarize합니다.

browser_click

snapshot의 ref ID로 식별되는 element를 click합니다.

Click @e5 to press the "Sign In" button

browser_type

input field에 text를 입력합니다. 먼저 field를 clear한 뒤 새 text를 입력합니다.

Type "hermes agent" into the search field @e3

browser_scroll

page를 위 또는 아래로 scroll하여 더 많은 content를 표시합니다.

Scroll down to see more results

browser_press

keyboard key를 누릅니다. form submit이나 navigation에 유용합니다.

Press Enter to submit the form

지원 key: Enter, Tab, Escape, ArrowDown, ArrowUp 등.

browser_back

browser history에서 이전 page로 돌아갑니다.

browser_get_images

현재 page의 모든 image를 URL과 alt text와 함께 나열합니다. 분석할 image를 찾을 때 유용합니다.

browser_vision

screenshot을 찍고 vision AI로 분석합니다. text snapshot이 중요한 시각 정보를 담지 못할 때 사용합니다. CAPTCHA, 복잡한 layout, visual verification challenge에 특히 유용합니다.

screenshot은 영구 저장되며 AI analysis와 함께 file path가 반환됩니다. messaging platform(Telegram, Discord, Slack, WhatsApp)에서는 agent에게 screenshot을 공유해 달라고 요청할 수 있습니다. agent는 MEDIA: mechanism을 통해 native photo attachment로 전송합니다.

What does the chart on this page show?

screenshot은 ~/.hermes/cache/screenshots/에 저장되고 24시간 뒤 자동 정리됩니다.

browser_console

현재 page의 browser console output(log/warn/error message)과 uncaught JavaScript exception을 가져옵니다. accessibility tree에 나타나지 않는 silent JS error를 감지하는 데 필수적입니다.

Check the browser console for any JavaScript errors

읽은 뒤 console을 clear하려면 clear=True를 사용합니다. 이후 call에서는 새 message만 보입니다.

browser_consoleexpression argument와 함께 호출하면 JavaScript도 evaluate합니다. DevTools console과 같은 형태이며, result는 parsed 형태로 돌아옵니다. JSON-serialized object는 dict가 되고 primitive value는 그대로 유지됩니다.

browser_console(expression="document.querySelector('h1').textContent")
browser_console(expression="JSON.stringify(performance.timing)")

현재 session에 CDP supervisor가 활성화되어 있으면(CDP-capable backend에 대해 browser_navigate가 실행된 session에서 일반적), evaluation은 supervisor의 persistent WebSocket으로 실행됩니다. subprocess startup cost가 없습니다. 그렇지 않으면 standard agent-browser CLI path로 fallback합니다. 두 경로의 behavior는 같고 latency만 달라집니다.

browser_cdp

raw Chrome DevTools Protocol passthrough입니다. 다른 tool이 다루지 않는 browser operation을 위한 escape hatch입니다. native dialog handling, iframe-scoped evaluation, cookie/network control, 기타 agent가 필요한 CDP verb에 사용합니다.

session 시작 시 CDP endpoint에 접근할 수 있을 때만 사용 가능합니다./browser connect가 running Chrome에 attach했거나 config.yamlbrowser.cdp_url이 설정되어 있어야 합니다. default local agent-browser mode, Camofox, cloud provider(Browserbase, Browser Use, Firecrawl)는 현재 이 tool에 CDP를 노출하지 않습니다. cloud provider에는 per-session CDP URL이 있지만 live-session routing은 후속 작업입니다.

CDP method reference: https://chromedevtools.github.io/devtools-protocol/ - agent는 특정 method page를 web_extract로 가져와 parameter와 return shape를 확인할 수 있습니다.

일반적인 pattern:

# 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")

browser-level method(Target.*, Browser.*, Storage.*)는 target_id를 생략합니다. page-level method(Page.*, Runtime.*, DOM.*, Emulation.*)는 Target.getTargets에서 얻은 target_id가 필요합니다. 각 stateless call은 독립적입니다. session은 call 사이에 persist되지 않습니다.

Cross-origin iframes: frame_id를 전달하면(browser_snapshot.frame_tree.children[]에서 is_oopif=true인 값) 해당 iframe을 위해 supervisor의 live session을 통해 CDP call을 route합니다. Browserbase에서 cross-origin iframe 안의 Runtime.evaluate가 동작하는 방식입니다. stateless CDP connection은 signed-URL expiry에 걸릴 수 있기 때문입니다. 예:

browser_cdp(
method="Runtime.evaluate",
params={"expression": "document.title", "returnByValue": True},
frame_id="<frame_id from browser_snapshot>",
)

same-origin iframe에는 frame_id가 필요 없습니다. 대신 top-level Runtime.evaluate에서 document.querySelector('iframe').contentDocument를 사용하세요.

browser_dialog

native JS dialog(alert / confirm / prompt / beforeunload)에 응답합니다. 이 tool이 생기기 전에는 dialog가 page의 JavaScript thread를 조용히 막아 이후 browser_* call이 hang되거나 throw될 수 있었습니다. 이제 agent는 browser_snapshot output에서 pending dialog를 보고 명시적으로 응답합니다.

Workflow:

  1. browser_snapshot을 호출합니다. dialog가 page를 막고 있으면 pending_dialogs: [{"id": "d-1", "type": "alert", "message": "..."}]처럼 표시됩니다.
  2. browser_dialog(action="accept") 또는 browser_dialog(action="dismiss")를 호출합니다. prompt() dialog에는 prompt_text="..."를 전달해 응답값을 제공합니다.
  3. 다시 snapshot을 가져옵니다. pending_dialogs가 비어 있고 page의 JS thread가 재개됩니다.

Detection은 persistent CDP supervisor를 통해 자동으로 이루어집니다. task마다 하나의 WebSocket이 Page/Runtime/Target event를 subscribe합니다. supervisor는 snapshot의 frame_tree field도 채워 agent가 현재 page의 iframe structure를 볼 수 있게 합니다. cross-origin(OOPIF) iframe도 포함됩니다.

Availability matrix:

BackendDetection via pending_dialogsResponse (browser_dialog tool)
Local Chrome via /browser connect 또는 browser.cdp_url✓ full workflow
Browserbase✓ full workflow(injected XHR bridge 사용)
Camofox / default local agent-browser✗(CDP endpoint 없음)

Browserbase에서의 동작. Browserbase의 CDP proxy는 실제 native dialog를 server-side에서 약 10ms 안에 auto-dismiss하므로 Page.handleJavaScriptDialog를 사용할 수 없습니다. supervisor는 Page.addScriptToEvaluateOnNewDocument로 작은 script를 주입해 window.alert/confirm/prompt를 synchronous XHR로 override합니다. 우리는 Fetch.enable로 이 XHR을 intercept합니다. page의 JS thread는 agent response로 Fetch.fulfillRequest를 호출할 때까지 XHR에서 block된 상태로 남습니다. prompt() return value는 page JS로 그대로 round-trip됩니다.

Dialog policyconfig.yamlbrowser.dialog_policy 아래에서 설정합니다.

PolicyBehavior
must_respond(기본값)capture하고 snapshot에 표시한 뒤 명시적인 browser_dialog() call을 기다립니다. buggy agent가 영원히 stall하지 않도록 browser.dialog_timeout_s(기본 300s) 뒤 safety auto-dismiss합니다.
auto_dismisscapture 후 즉시 dismiss합니다. agent는 여전히 browser_state history에서 dialog를 볼 수 있지만 별도 action은 필요 없습니다.
auto_acceptcapture 후 즉시 accept합니다. aggressive beforeunload prompt가 있는 page를 탐색할 때 유용합니다.

browser_snapshot.frame_tree 안의 Frame tree는 ad-heavy page에서 payload가 커지지 않도록 30 frame, OOPIF depth 2로 제한됩니다. limit에 걸리면 truncated: true flag가 표시됩니다. 전체 tree가 필요한 agent는 browser_cdpPage.getFrameTree를 사용할 수 있습니다.

Practical Examples

웹 form 채우기

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

동적 content 조사

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

Session Recording

browser session을 WebM video file로 자동 기록합니다.

browser:
record_sessions: true # default: false

활성화하면 첫 browser_navigate에서 recording이 자동으로 시작되고 session이 닫힐 때 ~/.hermes/browser_recordings/에 저장됩니다. local mode와 cloud(Browserbase) mode 모두에서 동작합니다. 72시간보다 오래된 recording은 자동 정리됩니다.

Stealth Features

Browserbase는 자동 stealth capability를 제공합니다.

FeatureDefaultNotes
Basic StealthAlways onrandom fingerprint, viewport randomization, CAPTCHA solving
Residential ProxiesOn더 나은 access를 위해 residential IP를 통해 route
Advanced StealthOffcustom Chromium build, Scale Plan 필요
Keep AliveOnnetwork hiccup 뒤 session reconnection
노트

사용 중인 plan에서 paid feature를 사용할 수 없으면 Hermes는 자동으로 fallback합니다. 먼저 keepAlive를 끄고, 그다음 proxy를 끕니다. 그래서 free plan에서도 browsing은 계속 동작합니다.

Session Management

  • 각 task는 Browserbase를 통해 isolated browser session을 받습니다.
  • session은 inactivity 후 자동 정리됩니다. 기본값은 2분입니다.
  • background thread가 30초마다 stale session을 확인합니다.
  • orphaned session을 막기 위해 process exit 때 emergency cleanup이 실행됩니다.
  • session은 Browserbase API를 통해 release됩니다. (REQUEST_RELEASE status)

제한 사항

  • Text-based interaction - pixel coordinate가 아니라 accessibility tree에 의존합니다.
  • Snapshot size - 큰 page는 8000자 기준으로 truncate되거나 LLM summarize될 수 있습니다.
  • Session timeout - cloud session은 provider plan setting에 따라 만료됩니다.
  • Cost - cloud session은 provider credit을 사용합니다. session은 대화가 끝나거나 inactivity가 발생하면 자동 정리됩니다. 무료 local browsing에는 /browser connect를 사용하세요.
  • No file downloads - browser에서 file을 download할 수 없습니다.