CodeVetter · Repo Unpack · Behavior traces
browser-use/browser-use
Three flows dominate. Startup brings up logging, the agent object, the browser process or cloud session, and the watchdog set before any model call. The primary step is a fixed phase sequence from DOM snapshot through LLM output to event-bus actions. Persistence is split across the in-memory AgentHistoryList, the on-disk file system and screenshots, optional conversation and GIF files, cookie storage state, and cloud event sync.
- Process startup for the library: importing browser_use runs setup_logging unless BROWSER_USE_SETUP_LOGGING=false, reading CONFIG log file paths, and monkeypatches asyncio BaseSubprocessTransport.__del__ to ignore 'Event loop is closed'.
- Agent construction order after argument validation: resolve llm (DEFAULT_LLM via get_llm_by_name, else ChatBrowserUse), force flash_mode for provider browser-use, build BrowserSession if none was passed, assign task_id and session_id via uuid7str, create AgentState and AgentHistoryList, create the temp agent directory, then _set_file_system and _set_screenshot_service.
- Browser startup order inside on_BrowserStartEvent: attach_all_watchdogs; if no cdp_url and use_cloud, CloudBrowserClient.create_browser and store cdpUrl with is_local False; else if local, dispatch BrowserLaunchEvent and read BrowserLaunchResult.cdp_url from LocalBrowserWatchdog; then connect() under _connection_lock with a 15s timeout; then dispatch BrowserConnectedEvent so storage restore finishes before start returns.
- SecurityWatchdog.on_NavigateToUrlEvent runs before navigation and raises ValueError when _is_url_allowed is false. on_NavigationCompleteEvent sends blocked redirects to about:blank. on_TabCreatedEvent tries to close a disallowed new tab. block_ip_addresses uses ipaddress plus socket.inet_aton so non-standard IPv4 spellings cannot bypass the check. Empty allow and deny lists allow all URLs.
- Primary step trace: step → wait_if_captcha_solving → _prepare_context → get_browser_state_summary → _check_and_update_downloads → _update_action_models_for_page → registry.get_prompt_description → MessageManager.prepare_step_state / maybe_compact_messages / create_state_messages → budget, replan, exploration, and loop nudges → _get_next_action → multi_act → _post_process → _finalize.
- Inside multi_act, each action is executed through Tools.act. Actions registered with terminates_sequence=True (navigate, search, go_back) abort the rest of the queue, and a URL or target change after any action also aborts the remainder so later clicks are not applied to a stale DOM.
- Initial URL handling: when directly_open_url is true, _execute_initial_actions runs the converted initial action list through multi_act before the LLM loop and stores that as history step 0 with a synthetic AgentOutput. The call is wrapped in wait_for(step_timeout) so a dead CDP socket cannot hang startup forever.
- Done path: the done action returns ActionResult(is_done=True). _post_process logs the final result. _execute_step sees history.is_done(), optionally _judge_and_log, invokes register_done_callback, and run() breaks. On consecutive_failures past max_failures (plus one if final_response_after_failure) the loop stops without a successful done.
- CLI startup trace: main → _dispatch. No args and a TTY prints _QUICKSTART and returns 0. Piped stdin is reassigned to a StringIO and passed to _run_browser_harness, which calls browser_harness.run.main. --mcp imports and runs the MCP stdio server. A NameError raised from executed <string> code is rewritten into an unknown-helper message and exit 2.
- Cookie persistence trace: BrowserConnectedEvent triggers StorageStateWatchdog.on_BrowserConnectedEvent → _load_storage_state. On BrowserStopEvent / SaveStorageStateEvent it calls _save_storage_state. The watchdog is not attached at all unless storage_state or user_data_dir is configured.
- Cloud sync auth is a device-code OAuth flow in DeviceAuthClient: POST /api/v1/oauth/device/authorize with scope 'read write', then poll /api/v1/oauth/device/token with grant_type urn:ietf:params:oauth:grant-type:device_code, storing access_token on CloudAuthConfig.
- Rerun trace: load_and_rerun can substitute detected variables via _substitute_variables_in_history, then rerun_history walks stored actions, using detect_variables_in_history (element id, name, type, placeholder, aria-label, then value patterns) to name inputs. save_history dumps the filtered history to AgentHistory.json by default.