CodeVetter · Repo Unpack · Extension points
browser-use/browser-use
New behavior is meant to be added as registered actions, not by editing the step loop. Tools.action and Registry.action are the plugin table; special parameter names are the injection API. Browser behavior is extended by watchdogs that subscribe to bubus events. LLM providers plug in through BaseChatModel and get_llm_by_name. Cloud skills, Gmail, and MCP are additional registries on top of the same action or tool list. System prompts are selected markdown files, overridable with override_system_message or extend_system_message.
- Registry.action(description, param_model, domains/allowed_domains, terminates_sequence) is the registration decorator. It normalizes the function to keyword-only, builds a Pydantic param model from the signature when param_model is omitted, and rejects **kwargs. Tools.action is a pass-through to that decorator.
- Injected parameter names recognized by Registry._get_special_param_types are context, browser_session, page_url, cdp_client, page_extraction_llm, available_file_paths, has_sensitive_data, file_system, and extraction_schema. sensitive_data is added to the context only when the action name is input. The docs warn that the name must be browser_session, not browser.
- Registry.exclude_action and Tools.exclude_action remove a name from the action map and block re-registration. Tools.__getattr__ also exposes registered actions as direct methods for tests.
- Per-action domain limits are the domains (alias allowed_domains) argument on Registry.action, separate from BrowserProfile.allowed_domains enforced by SecurityWatchdog. Both can be set.
- New browser services are watchdogs: a BaseWatchdog subclass with LISTENS_TO and EMITS class vars, constructed and attach_to_session() inside BrowserSession.attach_all_watchdogs. SecurityWatchdog is the template (LISTENS_TO NavigateToUrlEvent, NavigationCompleteEvent, TabCreatedEvent; EMITS BrowserErrorEvent).
- LLM extensions implement BaseChatModel and are either imported lazily from browser_use/__init__.py _LAZY_IMPORTS or constructed by get_llm_by_name. Adding a provider requires both a chat module and a branch in that factory if string names should work.
- System prompt extension points are override_system_message (replaces the template) and extend_system_message (appended). Otherwise SystemPrompt._load_prompt_template picks a file under browser_use/agent/system_prompts based on is_browser_use_model, flash_mode, is_anthropic, and Anthropic 4.5 caching.
- Cloud skills plug in through Agent(skill_ids=...) and SkillService, which turns each API skill into a registry action in _register_skills_as_actions. Gmail plugs in through register_gmail_actions(tools). MCP tools are a separate list built in the MCP server, not the Registry.
- Coordinate clicking is a mode switch: Tools.set_coordinate_clicking re-registers the click action. File types are a dict on FileSystem._file_types (md, txt, json, jsonl, csv, pdf, docx, html, xml, png, gif, jpg, jpeg, webp); a new extension means a new BaseFile subclass in that map.
- Run hooks are on_step_start and on_step_end passed to Agent.run, plus register_new_step_callback, register_done_callback, register_should_stop_callback, and register_external_agent_status_raise_error_callback on the constructor. output_model_schema swaps the done schema via Tools.use_structured_output_action.
- CLI skill targets are the TARGET_DIR_BUILDERS dict. Adding an assistant is a new entry there, not a new command parser. Legacy CLI verbs are the _LEGACY_HINTS dict; new verbs must not collide with those keys or they will be treated as removed 2.x commands.