# Data flow — browser-use/browser-use

> Canonical page: https://codevetter.com/unpack/browser-use/data-flow

# Data flow — browser-use/browser-use

Scanned commit d8110c5ff87ccba887aaa726cdb780f2f84bef8d (2026-09-15). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

A task string enters Agent.__init__, which picks an LLM, builds a system prompt, a MessageManager, a FileSystem, and a BrowserSession. Each step pulls a BrowserStateSummary (DOM text, selector map, screenshot) from the browser, redacts secrets, and sends the message list to the LLM. The model returns an AgentOutput whose action list is validated by Pydantic and executed one by one; ActionResult objects are written back into history and into the next prompt. Side effects leave the process through CDP commands, local files under the agent temp dir, optional conversation and GIF dumps, PostHog, and authenticated POSTs to the Browser Use events API.
- Agent.run emits CreateAgentSessionEvent once and CreateAgentTaskEvent at start, then BrowserSession.start, _register_skills_as_actions, and _execute_initial_actions before the step loop. On the way out it records token usage, dispatches UpdateAgentTaskEvent, optionally writes a GIF, and calls close(). — [browser_use/agent/service.py#L2548-L2726](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L2548-L2726)
- step() order is: optional captcha wait, _prepare_context, _get_next_action, _execute_actions, _post_process, and _finalize in a finally block. _prepare_context always requests get_browser_state_summary(include_screenshot=True), refreshes page-scoped actions, and calls MessageManager.create_state_messages. — [browser_use/agent/service.py#L1035-L1160](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1035-L1160)
- _get_next_action wraps _get_model_output_with_retry in asyncio.wait_for using settings.llm_timeout (auto-chosen from the model name when the caller passes None: 30s groq, 75s default, 90s for o3/claude/deepseek/gemini-3-pro). The parsed AgentOutput is stored on state.last_model_output. — [browser_use/agent/service.py#L260-L277](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L260-L277) [browser_use/agent/service.py#L1175-L1217](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1175-L1217)
- multi_act walks the action list. Tools.act applies a per-action timeout (argument, or BROWSER_USE_ACTION_TIMEOUT_S, default 180s) and calls Registry.execute_action. The registry builds the action's Pydantic param model, substitutes <secret> placeholders, and injects browser_session, page_url, cdp_client, file_system, page_extraction_llm, available_file_paths, and extraction_schema by parameter name. — [browser_use/agent/service.py#L2728-L2758](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L2728-L2758) [browser_use/tools/service.py#L2176-L2232](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2176-L2232) [browser_use/tools/registry/service.py#L57-L73](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L57-L73) [browser_use/tools/registry/service.py#L331-L395](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L331-L395)
- Browser actions do not call CDP directly from the tool in the navigation case: they dispatch bubus events (NavigateToUrlEvent, GoBackEvent, Click, Type, and others). BrowserSession.on_NavigateToUrlEvent performs the CDP navigation; DefaultActionWatchdog handles the element-level events after attach_all_watchdogs. — [browser_use/tools/service.py#L484-L594](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L484-L594) [browser_use/browser/session.py#L905-L914](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L905-L914) [browser_use/browser/session.py#L1789-L1802](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L1789-L1802)
- DOM state is produced by DomService.get_dom_tree and get_serialized_dom_tree (accessibility tree plus DOM snapshot, visibility and iframe filtering) and cached on the session as a selector map keyed by integer index. Tools resolve click and dropdown targets with browser_session.get_element_by_index. — [browser_use/dom/service.py#L703-L1111](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/dom/service.py#L703-L1111) [browser_use/tools/service.py#L1683-L1696](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L1683-L1696) [browser_use/browser/session.py#L1595-L1600](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L1595-L1600)
- MessageManager._filter_sensitive_data redacts secret values out of prompts via redact_sensitive_string. At execution time, domain-keyed sensitive_data dicts are applied only when match_url_with_domain_pattern matches the current URL; a flat {key: value} dict is applied on every domain. — [browser_use/agent/message_manager/service.py#L564-L591](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/message_manager/service.py#L564-L591) [browser_use/tools/registry/service.py#L427-L462](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L427-L462)
- File tools write under FileSystem.data_dir, which is base_dir/browseruse_agent_data. The default base_dir is the per-agent temp directory. _resolve_filename strips directories with basename to block traversal. External reads happen only when read_file is called with a name that is an exact member of available_file_paths, and then the path is opened as given. — [browser_use/filesystem/file_system.py#L117-L117](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L117-L117) [browser_use/filesystem/file_system.py#L506-L625](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L506-L625) [browser_use/filesystem/file_system.py#L671-L690](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L671-L690) [browser_use/tools/service.py#L1754-L1802](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L1754-L1802) [browser_use/agent/service.py#L444-L452](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L444-L452)
- Downloads discovered by the agent are merged into available_file_paths inside _check_and_update_downloads, which runs after the browser-state fetch and again after actions. upload_file refuses paths that are not in that list and not a fresh download. — [browser_use/agent/service.py#L657-L675](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L657-L675) [browser_use/agent/service.py#L1105-L1106](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1105-L1106) [browser_use/agent/service.py#L1219-L1224](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1219-L1224) [browser_use/tools/service.py#L864-L909](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L864-L909)
- When BROWSER_USE_CLOUD_SYNC is on and DeviceAuthClient is authenticated, CloudSync.handle_event POSTs each event as JSON to {BROWSER_USE_CLOUD_API_URL}/api/v1/events with a 10s timeout and swallows HTTP failures. Unauthenticated runs skip the send unless allow_session_events_for_auth is set. — [browser_use/sync/service.py#L19-L105](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/sync/service.py#L19-L105) [browser_use/config.py#L62-L69](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/config.py#L62-L69)
- ChatBrowserUse.ainvoke serializes messages, optional output_format JSON schema, request_type (browser_agent or judge), anonymized_telemetry, and session_id, then retries HTTP 429/500/502/503/504 with exponential backoff. Observability spans are optional Laminar decorators from browser_use/observability.py and no-op if lmnr is absent. — [browser_use/llm/browser_use/chat.py#L128-L179](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/llm/browser_use/chat.py#L128-L179) [browser_use/observability.py#L1-L39](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/observability.py#L1-L39)
- save_history writes AgentHistory JSON through history.save_to_file with sensitive_data filtering. If save_conversation_path is set, each step's messages are appended via save_conversation. generate_gif calls create_history_gif and emits CreateAgentOutputFileEvent when the file exists. Cookie persistence is StorageStateWatchdog._save_storage_state, enabled only when storage_state or user_data_dir is set, defaulting to save on shutdown (auto_save_interval 60s, save_on_change False). — [browser_use/agent/service.py#L3911-L3915](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L3911-L3915) [browser_use/agent/service.py#L1726-L1735](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1726-L1735) [browser_use/agent/service.py#L2704-L2717](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L2704-L2717) [browser_use/browser/session.py#L1730-L1750](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L1730-L1750) [browser_use/browser/watchdogs/storage_state_watchdog.py#L49-L158](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/watchdogs/storage_state_watchdog.py#L49-L158)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
