deer-flow/docs/guide/browser-control.md
Xinmin Zeng 2a97ec3e58
docs: turn README into an index and move reference detail to docs/guide (#8113)
* docs: turn README into an index and move reference detail to docs/guide

The README had grown to 393 KB because every change appended its notes there. The text moves verbatim into 18 topic guides under docs/guide/; only headings are re-leveled and relative links re-pointed. The README keeps the introduction, a quick start and a guide index. Contributor test notes move to CONTRIBUTING.md.

* docs: send user docs to topic guides and budget the root README

The rule 'update README.md for user-facing changes' is what grew the README. Guidance now points to docs/guide/, and check_agent_guidance.py fails when the root README exceeds 16 KiB (AG003).

* chore: remove unreferenced screenshots and finished plan notes

pr-build/ holds two PR screenshots (3 MB) from #1986. plans/ holds the plan for the merged #4049. docs/SKILL_NAME_CONFLICT_FIX.md is a February change note. Nothing references them.

* docs: route always-loaded AGENTS.md files to scoped guides

* docs(agents): cut scoped guides to scope, verify, traps, decisions

Each AGENTS.md keeps four kinds of content: the scope of the directory, the
verification commands, traps a local test run does not show, and decisions the
code cannot state. Values, field lists, function inventories, test names, issue
numbers and history are deleted, because the code, the tests and git state them.

Search and fetch providers share one community guide. Four guides with no
remaining content are removed. The size check now allows 6 KiB per file (hard
limit 8 KiB) and 24 KiB per chain (hard limit 32 KiB).

* style: format frontend guide table and guidance test imports

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-11-11 13:26:17 +08:00

4.6 KiB

Agentic Browser Control

Browser screenshots and Browserless captures publish complete content atomically. New files use the host's normal creation permissions (typically 0644), and replacements preserve existing permissions, so sandbox code can read captures when those permissions allow it. If saving fails, the original error is preserved even when temporary-file cleanup also fails; the previous output remains intact. Cleanup failures are logged with the temporary-file path for troubleshooting. Logging-handler errors cannot replace the save error or skip remaining cleanup.

Browserless reserves capture names with empty placeholders to prevent concurrent captures from overwriting one another. Failed publication releases the placeholder; if cleanup fails, Gateway logs a warning with its path and preserves the original publication error or interruption.

browser_screenshot never replaces an existing outputs/ file: a taken name moves to the next free one, such as report-1.png.

Browser dependency auto-detection accepts name, group, and use in any order within a tool entry, with either indented or indentless YAML lists.

Reading a page is not the same as using one. Alongside the read-only web_fetch and web_capture tools, DeerFlow ships an optional agentic browser tool group that keeps a live, per-conversation browser session so the agent can actually operate a page — navigate, read the interactive elements, click, type, submit forms, and follow multi-step flows on JavaScript-heavy sites.

Each action returns a fresh snapshot of the page's interactive elements, each addressed by a stable [ref] number, so the agent acts on what it just observed instead of guessing selectors. Outbound URLs are SSRF-screened by default, and the browser's TCP connections go through a local proxy that pins each one to the screened addresses, so a DNS answer that changes after the check cannot redirect them to a private host (WebRTC UDP is not covered). It is powered by Playwright and shipped as an optional extra so the core install stays lean:

cd backend
uv sync --extra browser
uv run playwright install chromium

Then uncomment the group: browser tool entries in config.yaml (browser_navigate, browser_snapshot, browser_click, browser_type, browser_get_text, browser_back, browser_screenshot, browser_close). make dev / Docker startup detects an enabled browser_navigate tool and preserves the browser extra on dependency syncs. The Gateway fails startup if browser control is configured but Playwright is missing, and /api/features hides the Browser UI unless the backend can actually serve it. Keep headless: true and allow_private_addresses: false for anything but local, trusted debugging. Attaching to an existing Chrome with cdp_url cannot enforce DeerFlow's subresource/redirect SSRF guard and therefore fails closed unless allow_unguarded_cdp: true explicitly acknowledges that risk; use it only with a trusted local browser. Browser sessions are process-local; keep the Gateway to a single worker process while this tool group is enabled because ordinary uvicorn worker dispatch does not provide thread affinity. That means GATEWAY_WORKERS=1, and on the launches that pass uvicorn no worker count at all (backend/Dockerfile, scripts/serve.sh) also WEB_CONCURRENCY unset or 1, since uvicorn takes the process count from it.

Existing, non-mock Custom Agent chats expose the same Browser Live controls when browser control is available and the agent either leaves tool_groups unrestricted or includes the browser group. An explicit tool-group allowlist without browser keeps those controls hidden.

Closing a login popup returns browser control to a surviving tab in the same session, preserving cookies and site storage. If every tab closes, the next browser action opens a tab in that same session. Recovered tabs are brought to the front in DeerFlow-managed browsers; CDP-attached Chrome keeps the user's current tab focus.

The workspace Browser Live client negotiates binary JPEG WebSocket frames, keeps only the newest pending frame per display refresh, and revokes replaced object URLs. Gateway control messages remain JSON, and clients that do not request the binary capability retain the legacy JSON/base64 frame protocol. Opening a Live connection has a 10-second handshake deadline. A stalled handshake enters the existing capped backoff, with up to six reconnects; successful connections reset that retry budget. The panel distinguishes connection timeouts from other connection failures and shows recovery guidance, including when retries are exhausted. Turn Live off and on to start a fresh retry budget.