browser-use: who decides what
What will it click or submit on its own, and what stops it?
Nothing asks first. The model's chosen actions run as soon as they are parsed, so no person approves a form submit, a purchase or a page script D17. The ordinary built-in actions are offered on every page, evaluate among them, which runs JavaScript the model writes B10.
Some page events are answered by code before the model sees them: it clicks OK on alerts and confirm dialogs the moment they open D7, grants clipboard and notification permissions to every site D8, and saves offered PDFs and attachments without a click D9.
A run normally ends when the model calls done G1. The automatic stops are counts, not judgments: 500 steps F1, or 5 failed steps in a row followed by one last forced answer F5. On Mac and Linux a person at the terminal can pause it with Ctrl+C; on Windows the first press quits D18. An integrator who wants an approval step adds it in their own code, through the step callback D17.
How to read this page
A seat is a judgment the agent makes over and over: what the model sees of the page, which action runs next, may this page be opened, is the task done. Each card records the question, how it is answered, and who or what holds it, with the code that implements or exposes that decision. Seat ids (A1, B12 …) are links.
Each answer describes what browser-use does by default. Exceptions named are the main ones, not a complete list.
The chip on each card has two words. The first is about the question: a RULE has one right answer given its inputs, so a run that answers differently is a bug; a RULING is one that competent people could answer differently. Enforcing a limit someone set is a RULE; choosing what to keep, what to trust or when the work is done is a RULING, even when code holds it.
The second word is who holds it: llm = a language-model call; model = another learned model; code = code in their repository; human = a person; external = code outside the repository that the agent hands the decision to.
Paths are relative to the repository root. A bare :120-140 or (323) means lines in the file named just before it.
Counts
90 seats across 9 stages: A 10, B 12, C 7, D 18, E 17, F 15, G 6, H 1, I 4.
| Kind of question · holder | Seats |
|---|---|
| RULING · code | 48 |
| RULE · code | 27 |
| RULING · llm | 11 |
| RULING · external | 3 |
| RULING · human | 1 |
What this edition does not have
There is no list of gaps. No coverage figure: this edition does not say how many of browser-use's model calls and decision points the seats leave out. Each card shows the question, the answer and its holder; for most seats we also recorded what checks the judgment and how it has failed, but those notes are not shown here.
What is left out of this edition
5 of the 90 cards are left out of this edition. The counts above include them.
A. Intake and routing
A1 When an agent is built without a model, which model answers its steps? RULING · code
- Answered how
With no model passed and no
DEFAULT_LLMenvironment variable, code builds Browser Use's own hosted modelbu-2-0, which needs aBROWSER_USE_API_KEYor construction fails;DEFAULT_LLMcan name a different model instead.- Held by
browser_use/agent/service.py:226-236(llm is None->CONFIG.DEFAULT_LLMenv name viaget_llm_by_name, elseChatBrowserUse());ChatBrowserUsedefault modelbu-2-0athttps://llm.api.browser-use.com(browser_use/llm/browser_use/chat.py:47,97).
A2 Does the agent ask the model for the short memory-plus-action reply (no thinking, no evaluation, no plan), and is planning switched off? RULE · code
- Answered how
Code forces flash mode for any model from the
browser-useprovider, the default included, so the model writes only a memory note and actions and planning is off; with another provider, the developer'sflash_mode(default off) decides.- Held by
browser_use/agent/service.py:238-244:llm.provider == 'browser-use'forcesflash_mode = True, andflash_modeforcesenable_planning = False; the reply schema follows at:786-791(AgentOutput.type_with_custom_actions_flash_mode,browser_use/agent/views.py:458-473, required['memory','action']).
A3 Which of the eight standing instruction files does this run's model receive? RULE · code
- Answered how
Code picks the file once at construction: the default hosted model, always in flash mode, gets
system_prompt_flash.md. Other files go to Claude models in flash mode, tobrowser-use/open-weights ids, or when flash is off;override_system_messagereplaces the file.- Held by
browser_use/agent/prompts.py:60-92SystemPrompt._load_prompt_template, keyed onis_browser_use_model('browser-use/' in model,browser_use/agent/service.py:503),is_anthropic(isinstance(llm, ChatAnthropic),browser_use/agent/service.py:498-500), Opus/Haiku 4.5 by name (browser_use/agent/prompts.py:17-25),flash_mode,use_thinking; built once in__init__(browser_use/agent/service.py:507-518) and sent withcache=True(browser_use/agent/prompts.py:58); not called whenoverride_system_messageis set (browser_use/agent/prompts.py:49-50).
A4 When the agent extracts page content, judges its own run or compacts its history, which model does it ask? RULE · code
- Answered how
Code sends page extraction, the end-of-run judge and history compaction to the same model object as the main loop unless the developer passes another; a later switch to
fallback_llmmoves only the main loop.- Held by
browser_use/agent/service.py:254-257(page_extraction_llmandjudge_llmdefault to the mainllmobject); compactionsettings.compaction_llm or self.settings.page_extraction_llm or self.llm(browser_use/agent/service.py:1169), wheresettings.page_extraction_llmis always set by__init__(browser_use/agent/service.py:408), so compaction uses the ORIGINAL main model unlesscompaction_llmis given (browser_use/agent/views.py:46, default None).
A5 After a rate limit or provider error, does the agent switch to a backup model, and for which errors? RULING · code
- Answered how
With no
fallback_llm(the default), a provider error fails the step. With one set, code moves the rest of the run to it on the first rate limit, truncated reply, or 401/402/429/500/502/503/504 error; others, such as a 400, do not switch.- Held by
browser_use/agent/service.py:1973-1979(catch inget_model_output) and_try_switch_to_fallback_llm:1981-2023: switch once, onModelRateLimitError,ModelOutputTruncatedError, or status in{401, 402, 429, 500, 502, 503, 504}(:2001-2004), only iffallback_llmis set (:2010-2012); sticky for the rest of the run (:2017-2018).
A6 Does the agent navigate somewhere before asking the model anything, and which URL does it pick from the task text? RULING · code
- Answered how
By default (
directly_open_url=True) code opens the one web address it finds in the task text before the model's first turn, and tells the model; with none, several, a file-like name, or a negation such as "never go to" just before it, nothing opens.- Held by
browser_use/agent/service.py:463-467(whendirectly_open_urlis True, the default at:200, with no follow-up and noinitial_actions) ->_extract_start_urlbrowser_use/agent/service.py:2307-2454: strip e-mail addresses (:2313), match two URL patterns (:2316-2319), drop placeholders (:2410), drop any candidate containing a listed file extension anywhere (.{ext}substring test, list:2323-2392, test:2418-2423) or.htmwithout a scheme (:2424-2425), drop URLs negated within 20 characters before them (:2431-2436), addhttps://(:2439-2440), and navigate only when exactly ONE unique URL remains (:2444-2452). Executed with no model call by_execute_initial_actions(:3309-3317) understep_timeout(:2599-2613); integratorinitial_actionsrun the same way instead.
A7 When a structured result type is declared, what is added to the task the model reads? RULE · code
- Answered how
With no output schema (the default), the task is unchanged; with one set on the agent or its tools, code appends
Expected output format:and the full JSON schema to the task text the model reads every step.- Held by
browser_use/agent/service.py:351-365(agentoutput_model_schemawins over theToolsone, with a warning) and_enhance_task_with_schema:612-628(appendsExpected output format: <Name>and the full JSON schema to the task text,:623-624); the done action is swapped for a structured one (:364-365, G5).
A8 When the developer passes passwords or keys for the agent to type, does the run proceed if the browser may visit any site, or if a secret's site is not on the allowed list? RULING · code
- Answered how
Code accepts the secrets in every case and only logs a warning: when
allowed_domainsis unset (the default) or when a per-site secret's domain is not covered by it. The run is never stopped.- Held by
browser_use/agent/service.py:534-581: noallowed_domains-> a warning ("your sensitive_data may be exposed",:539-544); per-domain secrets not covered byallowed_domains-> a warning (:577-581); the run proceeds in both cases (no raise, no flag).
A9 When the developer adds a new task to the same agent, how does the model see the old and the new one? RULE · code
- Answered how
When the developer calls
add_new_task, code wraps the first task as<initial_user_request>and appends the new one as<follow_up_user_request>; the agent keeps its history, browser settings and step count, and nothing re-opens a page (a finished run may already have closed the browser).- Held by
browser_use/agent/service.py:998-1012add_new_task(setsfollow_up_task, clears stop/pause, new event bus) andbrowser_use/agent/message_manager/service.py:191-197(wraps as<initial_user_request>+<follow_up_user_request>and adds a history item); initial actions and URL auto-open are skipped for follow-ups (browser_use/agent/service.py:463,:3311).
A10 From the model's name, does the agent turn screenshots off, turn coordinate clicking on, or shrink screenshots? RULING · code
- Answered how
Code matches the model's name: the default
bu-2-0matches none, so it gets no coordinate clicking and full-size screenshots. Names containing e.g.claude-sonnet-4turn coordinate clicking on, Sonnet screenshots are shrunk, and DeepSeek or Grok-3 names lose vision.- Held by
browser_use/agent/service.py:327-334coordinate clicking on when the lower-cased model name containsclaude-sonnet-4,claude-opus-4,claude-fable-5,gemini-3-proorbrowser-use/; screenshots resized to 1400x850 when the name after anyprovider/prefix startsclaude-sonnetand nollm_screenshot_sizewas given (browser_use/agent/service.py:246-252); vision forced off for names containingdeepseek(browser_use/agent/service.py:476-479) orgrok-3/grok-code(browser_use/agent/service.py:481-486).
B. Context: what the model sees
B1 Which sections make up the message the model reads every step, and in what order? RULE · code
- Answered how
Code builds one fresh message each step: the task, the run's history notes, files and plan, the page as a numbered element list, any one-step read results, then step number and date last; a screenshot follows when vision applies (B7).
- Held by
browser_use/agent/prompts.py:404-506AgentMessagePrompt.get_user_message:<user_request>(:361-362) -><agent_history>-><agent_state>(file system,todo.md, plan, sensitive-data placeholders, available file paths,:337-359) -><browser_state>(:224-335) -><read_state>if any -><page_specific_actions>if any -> unavailable-skills text if any -><step_info>(step N of max, today's date,:364-373) last for caching; then sample images, screenshot(s), read-file images, only when a screenshot or read-file image is present (:444-504). Context messages are appended after it (browser_use/agent/message_manager/service.py:570-574).
B2 From the live page, which elements appear in the model's view, and which get a number it can click or type into? RULING · code
- Answered how
Code shows the model visible text and controls within about 1,000 px above and below the current view, and numbers only the elements its heuristics judge interactive (click listeners, form controls and the like); scripts, styles and SVG innards are dropped.
- Held by
browser_use/dom/serializer/serializer.py:455-560_create_simplified_tree(dropsstyle,script,head,meta,link,title,browser_use/dom/serializer/serializer.py:18, and SVG children,:485-486; keeps visible, scrollable or shadow-hosting nodes; forces "visible" foraria-*/pseudoattributes and hidden file inputs,:519-531), visibility frombrowser_use/dom/service.py:252-343(CSS display/visibility/opacity, then inside the viewport plusviewport_threshold=1000px vertically,browser_use/dom/service.py:64, never set from the profile,browser_use/browser/watchdogs/dom_watchdog.py:558-565), interactivity frombrowser_use/dom/serializer/clickable_elements.py:6-246ClickableElementDetector.is_interactive(JS click listeners, form controls, roles, search-class hints, iframes larger than 100x100 px), numbering in_assign_interactive_indices_and_mark_new_nodes(browser_use/dom/serializer/serializer.py:660-770; scrollable containers get a number only if they have no interactive child, unless they look like a dropdown,:716-746; new-since-last-step elements get*,:759-766).
B3 Does the model lose sight of text or controls painted over by another element, or nested inside a larger button or link? RULING · code
- Answered how
By default code drops text painted under another element (an open modal or dropdown) and unnumbers covered controls; a child 99% inside a link or button loses its own number but keeps its text, unless it is a form field or labelled control.
- Held by
paint order:
browser_use/dom/serializer/serializer.py:135-136PaintOrderRemover.calculate_paint_order(browser_use/dom/serializer/paint_order.py:165-219: a node fully inside the union of opaque rects painted above it is markedignored_by_paint_order), on byBrowserProfile.paint_order_filtering=True(browser_use/browser/profile.py:704, "Slightly experimental"); covered text is skipped (browser_use/dom/serializer/serializer.py:1163-1175) and covered elements get no number (browser_use/dom/serializer/serializer.py:666). Containment:_apply_bounding_box_filtering(browser_use/dom/serializer/serializer.py:147-153,:772-881; on by default,browser_use/dom/service.py:1140-1141passes noenable_bbox_filtering) marks a child 99% inside a propagating parent (a,button, button/combobox roles,:46-58) unless it is a form control, itself propagating, hasonclick, anaria-labelor an interactive role (:854-878); a marked element gets no line and no number, but its children, text included, are still rendered (:994-1001).
B4 Does an attribute in the page's own markup remove an element from what the model sees? RULE · code
- Answered how
Code drops any element, with everything inside it, whose
data-browser-use-excludeattribute (or the per-session variant the demo panel sets) istrue; any website can set the plain one, and the element is then missing from the element list the model reads (a screenshot can still show it).- Held by
browser_use/dom/serializer/serializer.py:489-501: any element whosedata-browser-use-exclude-<session>OR legacydata-browser-use-excludeattribute is"true"is dropped with its whole subtree.
B5 Is content inside iframes (including frames from other websites) and inside web components shown to the model? RULING · code
- Answered how
By default code reads frames from other websites into the model's view alongside the page (up to 100 frame documents; cross-origin frames five levels deep, visible and at least 10x10 px); web-component (shadow) content is always included.
- Held by
browser_use/browser/profile.py:675-678cross_origin_iframes=True(DomService's own default is False,browser_use/dom/service.py:60, but the watchdog passes the profile value,browser_use/browser/watchdogs/dom_watchdog.py:561),max_iframes=100(browser_use/browser/profile.py:679-681, snapshot documents cut atbrowser_use/dom/service.py:669-674),max_iframe_depth=5(browser_use/browser/profile.py:683-686,browser_use/dom/service.py:981-984), cross-origin frames only when the frame element is visible and at least 10x10 px (browser_use/dom/service.py:37-42,:989-999); frame documents are walked (browser_use/dom/serializer/serializer.py:503-510); shadow roots always included, closed ones labelled|SHADOW(closed)|(browser_use/dom/serializer/serializer.py:467-477,:1018-1026); hidden-below-the-fold hint inside frames (:1184-1199).
B6 When the page's element list is long, where is it cut, and what is the model told? RULING · code
- Answered how
Code gives the model the first 40,000 characters of the element list (the
max_clickable_elements_lengthdefault), cut mid-element, and says so; the rest is not in that list, though scrolling, extraction or the screenshot can show it. Each attribute value is cut to 100 characters.- Held by
browser_use/agent/prompts.py:252-258: the serialized element text is cut atmax_clickable_elements_lengthcharacters (default 40000,browser_use/agent/service.py:211), mid-element, and the header says "(truncated to 40000 characters)" (browser_use/agent/prompts.py:332); each attribute value capped at 100 characters (browser_use/dom/serializer/serializer.py:1398) and interactive images' alt/title/label/src at 100 (browser_use/dom/serializer/serializer.py:957,961); first 4<select>options at 30 characters (browser_use/dom/serializer/serializer.py:407-412); scroll position as "pages above/below" (browser_use/agent/prompts.py:264-275).
B7 Is a picture of the page attached to this step's message? RULE · code
- Answered how
With
use_vision=True(the default) code attaches a fresh screenshot to every step on a web page; with'auto'only after an action asks, withFalsenever. Blank new-tab pages, non-web pages, DeepSeek or Grok-3 models and failed captures get none.- Held by
browser_use/agent/message_manager/service.py:461-478:use_vision=True(default,browser_use/agent/service.py:170) always;'auto'only after an action result asks (include_screenshotmetadata,browser_use/agent/message_manager/service.py:454-459; thescreenshotaction exists only in'auto',browser_use/agent/service.py:319-325);Falsenever. Overrides: new-tab pages never (browser_use/agent/prompts.py:406-408); non-http(s) pages capture none (browser_use/browser/watchdogs/dom_watchdog.py:266,:319); placeholder screenshots dropped (browser_use/agent/prompts.py:442); DeepSeek and some Grok models forced off (A10); resized whenllm_screenshot_sizeis set (browser_use/agent/prompts.py:375-401);vision_detail_level='auto'(browser_use/agent/service.py:197). A screenshot is captured every step even with vision off (browser_use/agent/service.py:1097-1100).
B8 Of the steps already taken, which ones does the model see, and in what form? RULING · code
- Answered how
By default (
max_history_items=None) code shows the model a short record of every earlier step; compaction, also on by default, swaps older steps for a summary once 25 steps pass and the record exceeds 40,000 characters. Long errors keep only their ends.- Held by
browser_use/agent/message_manager/service.py:152-189agent_history_description: by default (max_history_items=None,browser_use/agent/service.py:183) EVERY step's note and result; with a limit, the first item, an "N previous steps omitted" line and the last N-1 (:176-187); a compacted summary is prefixed as<compacted_memory>with "Treat as unverified context" (:155-163). Each step's errors are cut to first and last 100 characters when over 200 (:342-347); results capped at 60,000 characters (:350-367).
B9 When an action returns text, images or an error, does the model see it once, keep seeing it, or not see it? RULE · code
- Answered how
Code shows content flagged show-once (such as long page extracts) only on the next step, keeps each action's short memory line in the history for the run, and keeps errors there too, cut to their first and last 100 characters.
- Held by
browser_use/agent/message_manager/service.py:304-367_update_agent_history_description: results flaggedinclude_extracted_content_only_oncego to<read_state>for the NEXT step only (:323-328, cleared:316-317);long_term_memory, elseextracted_content, goes into the permanent history line (:335-340); images ride along once (:331-333); a step with no parsed output becomes "Agent failed to output in the right format." (:377-380).
B10 Which tools is the model offered this step, and how are they described to it? RULE · code
- Answered how
Each step code offers every built-in action on every page, including
evaluate(runs any page JavaScript;screenshotis dropped at the defaultuse_vision=True), except any the integrator excluded, plus custom actions whose site filter matches; on the last step or after repeated failures onlydoneis offered.- Held by
browser_use/agent/service.py:4049-4068_update_action_models_for_pagerebuilds the reply schema every step fromRegistry.create_action_model(page_url=...)(browser_use/tools/registry/service.py:519-605: actions with no domain filter plus those whosedomainsmatch the URL; a restricted action is hidden on an empty URL,browser_use/tools/registry/views.py:110-118); domain-limited actions are also listed in<page_specific_actions>(browser_use/agent/service.py:1117,browser_use/tools/registry/views.py:128-154); actions named inexclude_actionsare never registered (browser_use/tools/registry/service.py:307-309);screenshotremoved unlessuse_vision='auto'(browser_use/agent/service.py:319-325); coordinate click per A10; on the last step, or aftermax_failureswithfinal_response_after_failure=True(the default), the schema isdoneonly (browser_use/agent/service.py:1569-1591, F3, F6).
B12 When building the page view fails, does the model learn that, or does it see an empty page? RULE · code
- Answered how
If reading the page times out, code tells the model so and that no element numbers are safe; if reading the page throws instead, the model is shown an empty element list and told to consider waiting, with nothing saying the read failed (a screenshot may still show the page).
- Held by
two paths with different answers. Timeout:
browser_use/browser/session.py:1649-1694setsstate_error("no element indices are safe to use"), clears the cached selector maps (:1659-1661), and the prompt shows it as<browser_state_error>(browser_use/agent/prompts.py:301-303). Exception:browser_use/browser/watchdogs/dom_watchdog.py:394-400(DOM build raised: empty DOM,browser_errors=[], the rest of the state built normally,:488-506) and:515-547(any other failure: empty DOM, title 'Error',browser_errors=[str(e)]) set NOstate_error; nothing readsbrowser_errors(Grepbrowser_errorsoverbrowser_use/: 5 hits, all writes or the field atbrowser_use/browser/views.py:106), so the model seesPage appears empty - consider waitingandempty page(browser_use/agent/prompts.py:230-231,:281-282).
B13 Does the agent tell the model that the page looks empty, still loading, scrollable, a PDF, or that a dialog was closed for it? RULING · code
- Answered how
Code adds short status hints above the element list: "appears empty" under 10 elements, "may still be loading" when requests are pending and text is sparse, pages above and below, a PDF warning judged by the address, and dialogs it auto-closed.
- Held by
browser_use/agent/prompts.py:224-335: fewer than 10 elements -> "Page appears empty - consider waiting" (:230-231); pending requests and more than 20 elements with under 5 text characters per element -> "page may still be loading" (:233-242); pages above/below and "scroll down" past 0.2 pages (:264-275); PDF viewer by URL suffix or/pdf/(browser_use/browser/watchdogs/dom_watchdog.py:471) -> "DO NOT use the extract action" (prompts.py:306-313); auto-closed JavaScript dialogs listed (:321-326); current tab marked only when exactly one tab matches URL and title (:287-299). Non-http(s) pages skip the DOM build and screenshot (dom_watchdog.py:266,:311-356).
C. Choosing the next action
C1 Given the task, the page and its history, what should the agent do next (which actions, with which arguments)? RULING · llm
- Answered how
Every step, the hosted Browser Use model (default
bu-2-0) reads the task, the page state and the history and returns up to five actions as JSON; code runs them in order. Another model is used only if the integrator passes one.- Held by
browser_use/agent/service.py:1953(get_model_output): the agent'sllm, by defaultChatBrowserUse()modelbu-2-0on the hosted gateway (browser_use/agent/service.py:226-236unless configDEFAULT_LLMnames another;browser_use/llm/browser_use/chat.py:47), called once per step via_get_model_output_with_retry(browser_use/agent/service.py:1668-1702) underasyncio.wait_for(..., llm_timeout)(browser_use/agent/service.py:1185-1187).
C2 What structured action list does the model's reply mean? RULE · code
- Answered how
The Browser Use gateway returns the reply as structured data, and code validates it against the actions available on the current page; a reply that does not fit fails the step.
- Held by
browser_use/llm/browser_use/chat.py:228-248(default path): the gateway returnscompletionas a dict; action dicts are validated one by one into the UnionActionModel, then the whole reply viaoutput_format.model_validate(completion_data). Other providers: provider-side JSON-schema mode plusoutput_format.model_validate_json(...)(e.g.browser_use/llm/openai/chat.py:225-233,:253-258,:301). Schema prepared bySchemaOptimizer.create_optimized_json_schema(browser_use/llm/schema.py:12, addsadditionalProperties: false:128-152).
C3 When Claude returns a malformed tool call, what output did it mean to give? RULING · code
- Answered how
Not on the default path: only when the integrator uses
ChatAnthropic, code tries several repairs of a malformed tool call (decoding stringified fields, parsing a call written into text) before failing the step.- Held by
browser_use/llm/anthropic/chat.py:470-509: validate tool input; on failure decode double-serialized string fields (_repair_serialized_fields:287-299); then recover a whole call written into thethinkingstring as<parameter>markup or JSON (_completion_from_serialized_tool_input:306-350); with auto tool choice, parse JSON out of plain text (_completion_from_text_response:352-372,:503-506).
C4 When the model returns no action at all, what happens? RULING · code
- Answered how
Code asks the model once more; if the reply is still empty it tries to insert a failed
done, but by the code and upstream #5360 that fallback raises instead, so the step fails and counts as a failure.- Held by
browser_use/agent/service.py:1675-1700(_get_model_output_with_retry): re-asks once with "You forgot to return an action..." (:1682-1687); if still empty, intends to insertdone(success=False, text='No next action returned by LLM!')(:1690-1700).
C5 If the model asks for more actions than the per-step limit, which ones run? RULE · code
- Answered how
Only the first five actions of a reply run (the
max_actions_per_stepdefault); the rest are dropped and the model is not told which.- Held by
browser_use/agent/service.py:1960-1962:parsed.action = parsed.action[: max_actions_per_step].
C6 Which real URL does a shortened URL in the model's reply stand for? RULE · code
- Answered how
Before each model call, code shortens long URL query strings in user and assistant messages; afterwards it puts the full URL back into every string of the model's reply. A URL the model alters slightly is not restored.
- Held by
shortening before the call
browser_use/agent/service.py:1791-1865(query+fragment over_url_shortening_limit=25chars cut and suffixed with a 7-char md5,:1818-1832); restoration in every string of the parsed reply:1956-1958,:1867-1937.
C7 Does the model's plan update change the plan the agent tracks? RULE · code
- Answered how
Not at defaults: the default Browser Use model forces flash mode, which turns planning off. With planning on, code replaces the plan when the model sends a new one and moves the current item when the model names one.
- Held by
browser_use/agent/service.py:1418-1451(_update_plan_from_model_output):plan_updatereplaces the plan;current_plan_itemis clamped into range and earlier items are marked done.
D. Gatekeeping: may this action run?
D2 After a tab lands on a page or a new tab opens, does that page pass the domain policy, and if not, is it sent away? RULE · code
- Answered how
With no domain lists set (the default), a page with a host name is never sent away; one with no host name, such as a
file:page, can be. With lists set, a page reached by redirect or by the page itself is caught only at the next browser-state read, after it has loaded and run, and its tab is sent to about:blank.- Held by
browser_use/browser/watchdogs/security_watchdog.py:50-71(on_NavigationCompleteEvent: navigate the tab to about:blank) and:73-92(on_TabCreatedEvent: close the tab), both via_is_url_allowed:176. The current-URL re-check fires frombrowser_use/browser/watchdogs/downloads_watchdog.py:219-249, which on each browser-state request dispatches (without awaiting,:241) aNavigationCompleteEventcarrying the current page URL.
D5 Which secret values are hidden from the model, and on which channels? RULE · code
- Answered how
With no
sensitive_data(the default) there is nothing to hide. When secrets are given, the model sees placeholder names, and real values are scrubbed from the per-step state message; extra context messages and screenshots, sent every step by default, are not scrubbed.- Held by
placeholder list shown to the model
browser_use/agent/message_manager/service.py:391-418(only names for the current page's domain,:399-406); value redaction on the per-step state message:556-566via_filter_sensitive_data:576-600(browser_use/utils.pyredact_sensitive_string); context messages are NOT filtered:570-574; history saved to file filters onlyinputactionsbrowser_use/agent/views.py:545-556.
D7 When a page opens a JavaScript dialog, who decides OK or Cancel? RULING · code
- Answered how
Code clicks OK on every alert, confirm and leave-page dialog the moment it opens, and Cancel on every text prompt, before the model sees it; the model is told afterwards through the next browser state.
- Held by
browser_use/browser/watchdogs/popups_watchdog.py:62-123; the choice isshould_accept = dialog_type in ('alert', 'confirm', 'beforeunload')at:79(prompt → Cancel). The dialog text is queued for the next browser state:68-72.
D8 Which browser permissions (clipboard, notifications, camera...) are granted to the sites the agent visits? RULING · code
- Answered how
When the browser connects, code grants clipboard read/write and notifications to every site (the default
permissionslist); any other permission a page asks for is left to Chrome.- Held by
browser_use/browser/watchdogs/permissions_watchdog.py:23-43(Browser.grantPermissionswith no origin, i.e. every origin,:35-39); default listbrowser_use/browser/profile.py:363-368(clipboardReadWrite,notifications).
D9 When a page offers a file (PDF, attachment, download link), is it saved to disk? RULING · code
- Answered how
Yes. Downloads are always allowed, into a fresh temp folder, and with
auto_download_pdfson (the default) PDFs and attachment responses are also fetched and saved without a click. Settingaccept_downloads=Falsechanges nothing.- Held by
browser_use/browser/watchdogs/downloads_watchdog.py:500-513(Browser.setDownloadBehaviorbehavior: 'allow', intodownloads_path, by default a fresh temp folderbrowser_use/browser/profile.py:475-491); whenauto_download_pdfs(default True,browser_use/browser/profile.py:712; checkedbrowser_use/browser/watchdogs/downloads_watchdog.py:286-288,547-549): network auto-download:557-712with the rule_should_auto_download_network_response:91-104(PDF → yes; attachment → yes unless a generic text name:77-88), and PDF-viewer auto-download:277-301. Downloads are then added to the agent's uploadable/readable filesbrowser_use/agent/service.py:658-693.
D10 Is the file name a page supplies safe to write, and does the path stay inside the downloads folder? RULE · code
- Answered how
When the library itself saves a file, code cuts the page-supplied name down to a bare name and refuses the write if its real path would leave the downloads folder. Files Chrome downloads on its own are named by Chrome (not traced).
- Held by
browser_use/browser/watchdogs/downloads_watchdog.py:1482-1493(_sanitize_download_filename, called at:317,:770,:956,:1051) and:1495-1500(_is_path_contained, applied at:838-840,:1063,:1411).
D11 When the model asks to upload a file, is that file one the agent may hand to a website? RULE · code
- Answered how
Code allows only files the integrator listed, files downloaded in this run, or files the agent itself wrote, and does not check which site receives the upload; on a remote browser any path passes.
- Held by
browser_use/tools/service.py:864-910: allowed if inavailable_file_paths(:869), or a file downloaded this session (:871-872), or a FileSystem-managed file resolved by basename with a realpath containment check (:879-899, GHSA-j9hj-92j8-jv9h cited at:890); on a remote browser any path passes (:905-907).
D12 When the model reads or writes a file, which names and places are allowed? RULE · code
- Answered how
The agent may write only plainly named files with a supported extension, in its own folder in a new temporary directory that is emptied at start (a bad name is auto-corrected or refused), and may read an outside file only when its exact path is in
available_file_paths, which includes this run's downloads.- Held by
browser_use/filesystem/file_system.py:562-576(_is_valid_filename: basename, character class, extension allow-list),:606-625(_resolve_filename: basename first); outside files only when listed inavailable_file_pathsbrowser_use/tools/service.py:1798-1802.
D13 When a site puts up a CAPTCHA, who solves it, and how long does the agent wait? RULING · external
- Answered how
On a local browser (the default) nobody solves a CAPTCHA and the agent does not wait. On Browser Use cloud browsers their service solves it and the agent pauses at the start of its next step, up to 120 seconds.
- Held by
browser_use/browser/watchdogs/captcha_watchdog.py:80-155(registers for the cloud browser'sBrowserUse.captchaSolverStarted/FinishedCDP events; the solver itself is outside the repo) andbrowser_use/browser/watchdogs/captcha_watchdog.py:170-207(the wait); the agent waits at the start of each stepbrowser_use/agent/service.py:1047-1062; watchdog attached whencaptcha_solver(default True,browser_use/browser/profile.py:652-655)browser_use/browser/session.py:1848-1852.
D14 When a site asks for cookie consent, who answers it? RULING · external
- Answered how
By default code downloads a third-party extension ("I still don't care about cookies"), caches it, and loads it through the browser's launch arguments to dismiss cookie banners, with two sites configured as exceptions; if that setup fails the browser starts without it; with
enable_default_extensions=Falsethe banner is just part of the page and the model handles it.- Held by
the third-party extension "I still don't care about cookies" (
browser_use/browser/profile.py:1036-1040), downloaded and loaded whenenable_default_extensions(default True,:648-651, env override:19-25) via:939,987-1001; exempt sitescookie_whitelist_domains(defaultnature.com,qatarairways.com,:660-663) patched in at:1106-1109,1118-1139.
D15 Which of the browser's built-in protections and prompts does the agent's browser run with? RULING · code
- Answered how
When browser-use launches Chrome, it keeps normal web security and certificate checks but turns off popup blocking, the form-resubmit prompt and client-side phishing detection;
disable_security=Truealso removes web security and certificate checks.- Held by
browser_use/browser/profile.py:162-230(CHROME_DEFAULT_ARGS:--disable-popup-blocking:181,--disable-prompt-on-repost:182,--disable-client-side-phishing-detection:170,--safebrowsing-disable-auto-update:220,--disable-external-intent-requests:221);disable_security(default False:626) addsCHROME_DISABLE_SECURITY_ARGS(:141-149: web security off, certificate errors ignored) at:927; assembled inget_args:906-985.
D16 Is the browser started with Chromium's process sandbox on? RULING · code
- Answered how
Chrome's sandbox is on unless the library guesses it is inside a container (for example, PID 1's command line contains
py,uvorapp); then it is off, andchromium_sandbox=Truecannot turn it back on.- Held by
browser_use/browser/profile.py:447-449(chromium_sandboxdefaultnot CONFIG.IN_DOCKER) and:925(--no-sandboxetc. whenCONFIG.IN_DOCKER or not self.chromium_sandbox); Docker guessbrowser_use/config.py:20-44(/.dockerenv, cgroup, PID 1 command line containingpy,uvorapp:31-33, fewer than 10 processes:39-40); envIN_DOCKER=truecan force the guess on, never off (browser_use/config.py:175-176).
D17 Before the agent submits, buys, sends, deletes or runs page JavaScript, does anyone approve it? RULING · code
- Answered how
Nobody is asked: the model's chosen actions run as soon as they are parsed. An integrator can add a gate in code through
register_new_step_callback, which sees the proposed actions before they run.- Held by
nobody is asked by default: the step goes from model output straight to execution,
browser_use/agent/service.py:1201-1217(_get_next_action→_execute_actions→multi_act), andmulti_actruns each action after only a stop/pause check (browser_use/agent/service.py:2797-2815). No ask-a-person action is registered inTools(Grep(?i)ask_human|ask_user|approval|approve|confirm_actionoverbrowser_use/→ 3 files, none on the default path:integrations/openai/browser_use.py,integrations/anthropic/browser_use.py,skills/browser-use/SKILL.md).
D18 While the agent runs, may a person at the terminal halt it, and how does it resume? RULING · human
- Answered how
On Mac and Linux a person at the terminal can press Ctrl+C to pause the run and press it again to quit; on Windows the first press quits. A pause is checked between steps and between queued actions. Pressing Enter does not resume, despite the printed hint: only code calling
agent.resume()does.- Held by
the person running the script, by Ctrl+C:
browser_use/utils.py:324-360(first Ctrl+C cancels the step and callspause),:362-377(SIGTERM exits), registered bybrowser_use/agent/service.py:2547-2555whenenable_signal_handler(default True,:213);Agent.pauseprints "Press [Enter] to resume or [Ctrl+C] again to quit"browser_use/agent/service.py:3942-3946; the loop waits on_external_pause_event:2624-2627.
D19 Is this element one the click action may press, or must it be handled another way? RULE · code
- Answered how
Code refuses clicks on file-upload inputs and
<select>dropdowns and tells the model which action to use instead; an element whoseonclickmentions print is saved as a PDF instead of opening the print dialog. Everything else may be clicked.- Held by
browser_use/browser/watchdogs/default_action_watchdog.py:712-725(<select>and file inputs refused, the model told which action to use), also:352-355(file input, index click) and:417-428(file input and<select>, coordinate click; skipped whenforce=True:400-404); elements whoseonclickcontains "print" (:225-237) are saved as a PDF instead:357-369,430-439.
E. Execution and observation
E2 Did this action succeed or fail, as reported back to the loop and the model? RULING · code
- Answered how
Each action handler decides what counts as an error. Several failures, such as a missing element for click or input and every file-system failure, come back as ordinary text, so the loop treats them as successes.
- Held by
browser_use/tools/service.py:714-718(click: element-not-found returned asextracted_content, noterror) and each other handler's choice betweenActionResult(error=...)andActionResult(extracted_content=...)inbrowser_use/tools/service.py. Element-not-found is NOT an error for input (:785-789), dropdown_options (:1686-1690), select_dropdown (:1714-1718); IS an error for scroll (:1389-1393) and upload (:924-926). find_text not found is not an error (:1515-1522); a multi-page scroll whose every attempt failed still reports success (:1441-1465); close tab always succeeds (:1058-1065); every file-system failure comes back as plain text (browser_use/filesystem/file_system.py:883,:904-907,:921,:952) wrapped asextracted_content(browser_use/tools/service.py:1785,:1793).
E4 After each action, should the rest of the queued actions still run? RULING · code
- Answered how
Code runs a reply's actions in order and stops the queue at an error, a
done, a navigation, search, back, tab switch orevaluate, or any URL or focused-tab change. A page change without a URL change does not stop it.- Held by
browser_use/agent/service.py:2755-2873(multi_act):doneafter the first action stops the queue (:2785-2790); stop after done, error or last action (:2834-2835); stop after an action flaggedterminates_sequence(navigate, search, go_back, switch, evaluate:browser_use/tools/service.py:461,:505,:583,:1007,:1835; checkbrowser_use/agent/service.py:2840-2845); stop when the URL or focused tab changed (:2847-2853);wait_between_actions0.1 s between actions (:2793-2795,browser_use/browser/profile.py:694).
E5 How is a click carried out, and what is clicked instead when the target is special? RULING · code
- Answered how
Code clicks the centre of the element the model named by its number, using a JavaScript click when something covers it. It refuses file inputs and turns a click on a
<select>or a print button into a different action.- Held by
index → node from the cached selector map of the last observation (
browser_use/browser/session.py:2501-2516, via the alias:2544-2546);_click_by_indexbrowser_use/tools/service.py:704-765(index 0 refused byassert:709-711; a<select>is turned into a dropdown_options read:740-748);on_ClickElementEventbrowser_use/browser/watchdogs/default_action_watchdog.py:338-388(file input refused:352-355; a "print" button is replaced by a PDF save:357-369);_click_element_node_impl:703-1060(select refused:718, occlusion check:877, JS click fallback:880-902, checkbox JS fallback:975). Coordinate clicks are enabled only for model names matchingclaude-sonnet-4,claude-opus-4,claude-fable-5,gemini-3-proorbrowser-use/(browser_use/agent/service.py:328-334), so NOT for the defaultbu-2-0; when on they dispatchforce=True(browser_use/tools/service.py:678-680), which skips the file-input, select and print checks (default_action_watchdog.py:399-404).
E7 When a click opens a new tab, does the agent move to it? RULING · code
- Answered how
Yes: 50 ms after a click, code switches to the first new tab it finds and tells the model so. A tab that opens later than that is not caught here.
- Held by
browser_use/tools/service.py:629-654(_detect_new_tab_opened): after 50 ms, any new tab is switched to automatically (first new one).
E8 Has the page finished loading after a navigation? RULING · code
- Answered how
Code waits up to 3 seconds (same site) or 8 seconds (other site) for a load or network-idle signal, then carries on either way; the model is told it navigated, not that the wait ran out.
- Held by
browser_use/browser/session.py:1034-1155(_navigate_and_wait):Page.navigatecapped atnav_timeout, which the caller sets fromNavigateToUrlEvent.event_timeout(browser_use/browser/session.py:990-996), default 30 s (TIMEOUT_NavigateToUrlEvent,browser_use/browser/events.py:122; the 20 s atbrowser_use/browser/session.py:1070-1071applies only when none is passed); then wait forloadornetworkIdlelifecycle events (defaultwait_until='load',browser_use/browser/events.py:114) for 3 s on the same domain, 8 s otherwise (browser_use/browser/session.py:1056-1064,:1110-1145); same-document navigations return at once (:1098-1101).
E9 Did the page come back empty, and should it be reloaded? RULING · code
- Answered how
After navigating in the current tab, code checks whether the page looks empty, waits 3 seconds, then reloads once; it reports an error only if the page still has no document root.
- Held by
browser_use/tools/service.py:514-544(insidenavigate): if an http(s) page has no DOM root or an empty LLM view, wait 3 s and recheck; still empty → navigate to the same URL again, wait 5 s; error only if the DOM root is still None (:539-544).
E10 Into which file input does an upload go? RULING · code
- Answered how
Code uploads into the file input next to the element the model named or, if there is none, into the file input nearest the current scroll position; the model is told it uploaded to the index it named.
- Held by
browser_use/tools/service.py:928-985: a file input "near" the element the model named (browser_session.find_file_input_near_element,browser_use/browser/session.py:2717); else the file input in the selector map closest to the current scroll position (browser_use/tools/service.py:941-980). Which files may be uploaded is D11 (:869-920).
E11 What does the current page say in answer to the model's extraction query? RULING · llm
- Answered how
When the agent calls
extract, the same Browser Use model reads the page as text (up to 100,000 characters per call) and answers the query in its own words; nothing checks the answer against the page.- Held by
browser_use/agent/service.py:254-255(page_extraction_llmdefaults to the agent'sllm), called atbrowser_use/tools/service.py:1275-1278(free text) or:1196-1202(structured, when the model passesoutput_schemaor the integrator setsextraction_schema), each under a 120 s cap.
E12 Which part of the page does the extraction model get to read? RULING · code
- Answered how
Code converts the page to markdown, strips scripts, styles and JSON-like blobs, and hands the extraction model a first chunk of about 100,000 characters with a note on how to ask for the next.
- Held by
browser_use/dom/markdown_extractor.py:113-191(markdownify with script/style stripped; regex removal of JSON-like blobs, including any inline code span that starts with{:163-165; long lines that parse as JSON dropped:177-184);chunk_markdown_by_structure:410withmax_chunk_chars=100000(browser_use/tools/service.py:1079,:1125); image URLs auto-included when the query contains words like "image" or "photo" (:1090-1092).
E13 How much of an action's output stays in the model's memory, and for how long? RULING · code
- Answered how
Each action decides: large extract or evaluate output (evaluate is first cut at 20,000 characters), file reads and dropdown lists are shown once, then kept only as a short note or a saved file the agent can read back.
- Held by
browser_use/tools/service.py:1222-1229(extract, structured path; free-text path:1286-1293): output over 10,000 chars is saved toextracted_content_N.mdand shown once; evaluate output is cut at 20,000 chars and over 10,000 shown once (:1913-1927); read_file keeps about 1,000 chars in memory and shows the full text once (:1807-1831); dropdown options shown once (:1701-1705). The flagslong_term_memory/include_extracted_content_only_onceare defined atbrowser_use/agent/views.py:327-332; how the message manager uses them is B9.
E14 Should the model's JavaScript be rewritten before it runs? RULING · code
- Answered how
Before running the model's JavaScript, code rewrites some quoting and escaping patterns it treats as mistakes, across the whole code, so a legitimately escaped quote inside a string is changed too.
- Held by
browser_use/tools/service.py:1943-2006(_validate_and_fix_javascript): unescape\"everywhere (:1949), collapse double-escaped regex escapes (:1953-1954), turn double-quoted arguments ofdocument.evaluate,querySelector(All),.closest,.matchesinto template literals (:1957-1991); applied at:1844, run withRuntime.evaluate(:1847-1850).
E16 How is a dropdown option chosen, and what if the page undoes it? RULING · code
- Answered how
Code picks the option whose text or value matches the model's text, ignoring case; if the page reverts it, it tries clicking the option. A failed selection usually comes back as text, not as an error.
- Held by
browser_use/tools/service.py:1711-1750→on_SelectDropdownOptionEventbrowser_use/browser/watchdogs/default_action_watchdog.py:3300(native<select>: case-insensitive exact match on trimmed option text or on value:3332-3341; if the page framework reverts the selection, a click fallback:3608-3690); options read byon_GetDropdownOptionsEvent:2824, ARIA combobox:3094.
E18 Should a failed model request be retried, and how many times? RULING · code
- Answered how
The Browser Use client makes up to five attempts on server errors, rate limits and network failures, with growing pauses, all inside the agent's 75-second limit for each model call.
- Held by
default path:
browser_use/llm/browser_use/chat.py:176-225: up tomax_retries=5attempts (:51) on 429/500/502/503/504 (:28) and on httpx timeouts/connect errors, exponential backoff from 1 s capped at 60 s with 10% jitter (:186-193). Other providers hand the retry to the vendor SDK (max_retriespassed to the client, e.g.browser_use/llm/openai/chat.py:59,:94;browser_use/llm/anthropic/chat.py:60,:78).
E19 After a step raises an error, does the run go on, wait for the browser, or stop? RULING · code
- Answered how
The error becomes the next step's input for the model and counts as a failure; the run continues. A closed browser ends the run, and a connection being rebuilt is waited for first.
- Held by
browser_use/agent/service.py:1259-1315(_handle_step_error): an interruption is not a failure (:1263-1267); a connection-like error (string match,:1317-1331) while a reconnect is in progress waits up toRECONNECT_WAIT_TIMEOUT, and if the connection came back records "Connection lost and recovered" as the result without counting a failure and the run moves on (:1270-1286); a closed browser stops the run (:1289-1293,:1333-1355); anything else, including a connection-like error that did not recover and is not a closed browser, becomes the next step's error message and counts (:1296-1314).
E20 When a step runs out of time part-way, what does the model learn about what already happened? RULING · code
- Answered how
If a step runs past 180 seconds, it is cut off and the model is told only that the step timed out, not which of its actions had already run.
- Held by
browser_use/agent/service.py:2481-2497(_execute_step): on the 180 s step timeout,last_resultis replaced with one error "Step N timed out after 180 seconds". The actions that already ran are kept only inmulti_act's localresults(:2764), assigned tostate.last_resultonly after it returns (:1217-1218);step()clearedlast_resultbefore the model call (:1072) and_finalizewrites no history item whenlast_resultis empty (:1360-1361).
F. Limits and memory
F1 When has the run used up its step budget? RULE · code
- Answered how
Code stops a run after 500 steps by default (
max_stepsofrun()), records "Failed to complete task in maximum steps" and returns with no answer; a follow-up task on the same Agent keeps counting from the first run's steps.- Held by
browser_use/agent/service.py:2620(while self.state.n_steps <= max_steps), defaultmax_steps=500atbrowser_use/agent/service.py:2523(andrun_sync:4088); the loop'selsebranch atbrowser_use/agent/service.py:2654-2672appends a history item witherror='Failed to complete task in maximum steps'.
F2 When should the agent be warned to wrap up? RULING · code
- Answered how
From 75% of the step budget (step 375 of the default 500) until the last step, code adds a "BUDGET WARNING" to each prompt telling the model to consolidate its results and call
done.- Held by
browser_use/agent/service.py:1543-1567(_inject_budget_warning, fires atsteps_used / max_steps >= 0.75and not on the last step), called from_prepare_contextat:1154.
F3 On the last allowed step, what may the agent do? RULE · code
- Answered how
On the last step (step 500 by default) code offers the model only the
doneaction and tells it to setsuccessto false if the task is not fully finished.- Held by
browser_use/agent/service.py:1569-1578(_force_done_after_last_step: adds a message and swapsself.AgentOutputtoself.DoneAgentOutput, built with only thedoneaction at:794-800and:4062-4068).is_last_stepisstep_number >= max_steps - 1(browser_use/agent/views.py:283-285).
F4 Does this step count as a failure? RULING · code
- Answered how
Code counts a step as a failure when its only result is an error (one action, or several where the first errored), the model call fails, or the step times out. A step whose later action errors resets the count to zero, by design.
- Held by
browser_use/agent/service.py:1234-1243(_post_process: incrementsconsecutive_failuresonly when the step produced exactly ONE result and it carrieserror; otherwise RESETS the counter to 0); also:1298-1300(any exception in a step),:2492(step timeout),:2613(initial actions timeout).
F5 When does the agent give up after repeated failures? RULING · code
- Answered how
By default, after 5 failed steps in a row code gives the model one forced-
donestep (F6); if that fails too, the run ends with "Stopped due to 5 consecutive failures" and returns the history.- Held by
browser_use/agent/service.py:2629-2635(stop whenconsecutive_failures >= max_failures + int(final_response_after_failure), i.e. 5 + 1 = 6 by default); defaultsmax_failures=5(:173),final_response_after_failure=True(:203).
F6 After repeated failures, who writes the run's final answer? RULING · llm
- Answered how
After 5 failures in a row (the default), the main model gets one step with only
doneand is told to report what it found and setsuccessfalse unless finished; nothing checks that it does.- Held by
browser_use/agent/service.py:1580-1591(_force_done_after_failure: atconsecutive_failures >= max_failureswithfinal_response_after_failureTrue, adds the message and swaps toDoneAgentOutput), answered by the mainllmon that step.
F7 How long may one model call take? RULING · code
- Answered how
With the default model (
bu-2-0) code gives each model call 75 seconds (90 for Claude, o3, DeepSeek and Gemini 3 Pro names, 30 for Groq); a call that runs over counts as a failed step.- Held by
browser_use/agent/service.py:262-278(_get_model_timeout: 90 s for gemini 3-pro, o3, claude, sonnet, deepseek; 75 s other gemini; 30 s groq; 75 s otherwise), enforced at:1185-1199(asyncio.wait_for(..., timeout=self.settings.llm_timeout)).
F8 How long may a whole step take? RULING · code
- Answered how
Code gives a whole step (browser state, model call and actions) 180 seconds by default; a step that runs over is cancelled, recorded as timed out and counted as a failure.
- Held by
browser_use/agent/service.py:2481-2497(asyncio.wait_for(self.step(...), timeout=self.settings.step_timeout), default 180 s at:199); initial actions get the same bound at:2599-2613.
F9 Is the agent stuck in a loop, and what is it told? RULING · code
- Answered how
On by default: code counts repeated similar actions (nudges at 5, 8 and 12 repeats in the last 20;
wait,doneandgo_backare not counted) and unchanged pages, and adds a "you might be looping" note to the next prompt; it never blocks or stops the agent.- Held by
browser_use/agent/views.py:157-248(ActionLoopDetector: rolling window of 20 action hashes, nudges at 5/8/12 repeats, page-stagnation nudge once the page fingerprint is unchanged for 5 consecutive steps); wired atbrowser_use/agent/service.py:1497-1541and:1157-1158,:1232.
F10 Should the agent be told to replan? RULING · code
- Answered how
Off at the default model: ChatBrowserUse forces flash mode, which turns planning off. With planning on and a plan written, code adds "REPLAN SUGGESTED" after 3 counted failures in a row (F4's counter).
- Held by
browser_use/agent/service.py:1465-1479(when a plan exists andconsecutive_failures >= planning_replan_on_stall, default 3 at:205).
F11 Should the agent be told to make a plan or finish? RULING · code
- Answered how
Off at the default model (flash mode turns planning off). With planning on, from step 5 code tells an agent with no plan, on every step, to write one or call
done.- Held by
browser_use/agent/service.py:1481-1495(no plan andn_steps >= planning_exploration_limit, default 5 at:206).
F12 Which older history is summarised away, and what does the summary keep? RULING · llm
- Answered how
On by default: once 25 steps have passed and the history text exceeds 40,000 characters, the main model summarises it, and code keeps that summary plus the first and last six steps; a failed summary is retried every step.
- Held by
browser_use/agent/service.py:1169(settings.compaction_llm or self.settings.page_extraction_llm or self.llm, i.e. the mainllmby default); call atbrowser_use/agent/message_manager/service.py:216-302. Gates: every 25 steps (compact_every_n_steps,browser_use/agent/views.py:39) AND history text >= 40,000 chars (:55,browser_use/agent/message_manager/service.py:241-243). After a summary it keeps the first history item plus the last 6 (keep_last_items,browser_use/agent/views.py:43;browser_use/agent/message_manager/service.py:292-298).
F13 What is the agent's plan, and which item is it on? RULING · llm
- Answered how
Off at the default model (flash mode removes the plan fields). With planning on, the model may write a todo list and say which item it is on; code stores it and shows it back each step.
- Held by
browser_use/agent/views.py:395-396(the mainllm'splan_update/current_plan_itemfields; dropped from the flash-mode schema atbrowser_use/agent/views.py:469-470), applied bybrowser_use/agent/service.py:1418-1451(index clamped to range atbrowser_use/agent/service.py:1439).
F14 What should the agent remember from this step? RULING · llm
- Answered how
Each step the model may write a short
memorynote (the default prompt asks for up to five sentences that also judge the last step and plan the next); code carries the notes it writes forward as the run's history text.- Held by
browser_use/agent/views.py:393(the mainllm'smemoryfield), stored per step atbrowser_use/agent/message_manager/service.py:382-389and rendered back byHistoryItem.to_string(browser_use/agent/message_manager/views.py:33-55).
F16 When a history cap is set, which past steps does the model stop seeing? RULING · code
- Answered how
Off by default (
max_history_items=None): every step stays in view until compaction (F12). When set (it must be above 5), code shows the first step, a "steps omitted" marker and the most recent steps up to the cap.- Held by
browser_use/agent/message_manager/service.py:165-189(keeps the first item and the lastmax_history_items - 1, inserts "[... N previous steps omitted...]");max_history_items=Noneby default (browser_use/agent/service.py:183), must be > 5 (browser_use/agent/message_manager/service.py:141).
G. Judging the result
G1 Is the task finished? RULING · llm
- Answered how
The model decides the task is finished by calling
done; code ends the run on that call without checking whether the answer is right (the judge, G3, only grades it afterwards).- Held by
browser_use/tools/service.py:2049-2090(thedoneaction the mainllmcalls; structured variantbrowser_use/tools/service.py:2012-2045); the loop reads it throughAgentHistoryList.is_done(browser_use/agent/views.py:722-727, last result of the last step) atbrowser_use/agent/service.py:2502.multi_actrefusesdoneanywhere but first in a step (browser_use/agent/service.py:2786-2790) and stops after it (:2834).
G2 Did the task succeed (the agent's own report)? RULING · llm
- Answered how
The run's success flag is whatever the model puts in
done; if the model leaves it out code records success, and with an output schema the field is hidden from the model, so a structured run reads as successful unless the model sets it anyway.- Held by
browser_use/tools/views.py:100(DoneAction.success, filled by the model'sdonecall;StructuredOutputAction.successatbrowser_use/tools/views.py:117); read back byAgentHistoryList.is_successful(browser_use/agent/views.py:729-735). This is the value integrators read and the value telemetry sends (browser_use/agent/service.py:2261); the judge does NOT override it (:1632-1634).
G3 Does an independent judge think the task succeeded? RULING · llm
- Answered how
On by default: after a
done, a second call through the agent's own model client grades the run against the task and the last 10 screenshots; code attaches and logs the verdict but keeps the agent's own success flag. Nodone, no judging.- Held by
browser_use/agent/service.py:1594-1627(_judge_trace, callingjudge_llm, which defaults to the mainllmatbrowser_use/agent/service.py:256-257;use_judge=Trueby default at:186), with messages fromconstruct_judge_messages(browser_use/agent/judge.py:44-225); runs after adone, before the done callback (browser_use/agent/service.py:2502-2507,:2291-2296).
G4 Did the last action achieve what it was meant to? RULING · llm
- Answered how
Absent at the default model: flash mode removes the field (its prompt asks for the same judgement inside
memory, F14). With a model not in flash mode, the model writes a one-line verdict each step; code shows it back and acts on nothing in it.- Held by
browser_use/agent/views.py:392(the mainllm'sevaluation_previous_goalfield, required in the schema atbrowser_use/agent/views.py:405, removed from the flash-mode schema atbrowser_use/agent/views.py:467), stored atbrowser_use/agent/message_manager/service.py:384and shown back as history text (browser_use/agent/message_manager/views.py:45-47).
G5 Does the final output match the schema the integrator asked for? RULE · code
- Answered how
Absent by default. When the integrator passes
output_model_schema, pydantic checks the finaldoneagainst it; a misfit is a failed step the model sees, and a run can still end at its step or failure limit with no fitting answer.- Held by
browser_use/tools/service.py:2012-2016(pydantic validation of thedoneparameters againstStructuredOutputAction[output_model]at action dispatch), thenAgentHistoryList.structured_outputre-parses the final JSON (browser_use/agent/views.py:914-926). Present only withoutput_model_schemaor a Tools output model (browser_use/agent/service.py:351-365).
G6 Did a replayed run succeed? RULING · llm
- Answered how
Only when an integrator calls
rerun_historyorload_and_rerun: a model (by default the agent's own) judges a final screenshot and step counts; if that call fails, code calls the replay successful when no step recorded an error.- Held by
browser_use/agent/service.py:2965-2967(summary_llm, defaulting to the mainllm) in_generate_rerun_summary(browser_use/agent/service.py:2932-3021), called at the end ofrerun_history(browser_use/agent/service.py:3299-3302). A separate entry point (I-stage), not reached byAgent.run.
H. Delegation
H1 When an integrator adds MCP tools, what does an outside tool do and return? RULING · external
- Answered how
Absent by default. When integrator code registers an MCP server's tools, each one (or each in
tool_filter) becomes an action the model can call, and the outside server decides what it does and returns.- Held by
browser_use/mcp/client.py:309-342(mcp_action_wrapperhands the call to the MCP server viaself.session.call_tool; no-parameter twinbrowser_use/mcp/client.py:360-390); registered only when integrator code callsMCPClient.register_to_tools(browser_use/mcp/client.py:212-246; Grep forregister_to_tools|MCPClient\(overbrowser_use/finds only the module's own docstring and definition).
I. Learning and feedback
I1 What browser state (cookies, logins) carries into the next run? RULING · code
- Answered how
By default no saved cookies or logins are loaded: with no
storage_statenamed, code loads and saves none. The default browser profile folder is a temporary one made once when the library loads, so later runs in the same Python process can find what earlier ones left there. With astorage_statenamed, code loads it at start and merges changed cookies back about once a minute.- Held by
browser_use/browser/watchdogs/storage_state_watchdog.py:49-57(StorageStateWatchdogloadsstorage_stateon connect,browser_use/browser/watchdogs/storage_state_watchdog.py:224-322), saves on cookie change every 30 s (:41,:119-133) and on demand, MERGING with the existing file (new cookie wins per name/domain/path,:185-191,:324-345), atomic write with.bak(:194-204); an in-memory dict is loaded but never saved (:168-172). With a non-temp Chromeuser_data_dir, the profile is COPIED to a temp dir first (browser_use/browser/profile.py:849-904), so the real profile is read, not written.
I2 Which values typed in a recorded run are reusable variables? RULING · code
- Answered how
Only when an integrator calls
detect_variablesorload_and_rerun(variables=...): code guesses which typed values are variables to swap on replay, from field type and id/name/label keywords, else from email, phone, date, name or number patterns.- Held by
browser_use/agent/variable_detector.py:9-46(detect_variables_in_history): element attributes first, then value patterns for email, phone, YYYY-MM-DD date, capitalised name and short number (browser_use/agent/variable_detector.py:98-120,:213-256); reached throughAgent.detect_variables(browser_use/agent/service.py:4097-4101) andload_and_rerun(variables=...)→_substitute_variables_in_history(:3931-3932,:4103-4163). Only text intextandqueryfields (browser_use/agent/variable_detector.py:63).
I3 On replay, which element on today's page is the one the recording clicked? RULING · code
- Answered how
Only when an integrator replays a run: code matches each recorded element to today's page by a fixed cascade (exact hash, stable hash, XPath, accessible name, attribute) and acts on the first element matched at the first level that finds one.
- Held by
browser_use/agent/service.py:3554-3712(_update_action_indices): five-level cascade EXACT hash → STABLE hash → XPATH → accessible name → attribute (name, id, aria-label), first match wins at each level, same-frame elements first (browser_use/agent/service.py:3576-3583).
I4 On replay, is this step a needless repeat that should be skipped? RULING · code
- Answered how
Only when an integrator replays a run: code skips a step when the previous step worked and both first actions are the same action type on the same element, whatever their parameters, and records the skip as no error.
- Held by
browser_use/agent/service.py:3739-3808(_is_redundant_retry_step), applied atbrowser_use/agent/service.py:3226-3235: skip when the previous step succeeded and both steps' FIRST action has the same action type on the same element (by hash, stable hash or xpath).
How this map was made
Four readers each took a part of the agent and wrote seat cards from the source, and four more rewrote each answer in a short form that describes the default. The map's author then re-read every seat against the cited lines and corrected what the source did not support. Reviews by a model from another family (read-only, at the same commit) checked the answers against the code, and each of their findings was checked against the code before anything changed. A checker confirms that each seat's recorded holder line exists at the pinned commit and carries its anchor text; the few holder lines edited for this page were checked by the cross-family page review instead. Nothing on this page was produced by running their code.