Files
browser-use/browser_use/tools/registry/views.py
Magnus Müller de0488031d Squashed commit of the following:
commit 92d1732a40
Merge: fa4ff47a efcd2b33
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 08:18:35 2025 -0700

    Merge main

commit fa4ff47ae4
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 08:03:04 2025 -0700

    Laminar info mode

commit 8625aa9ba9
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 08:02:54 2025 -0700

    Default to flash for browser use llm

commit 69a517ad7c
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 08:02:44 2025 -0700

    Update example

commit c91467c51d
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 08:02:15 2025 -0700

    Update example

commit 4e2b3f1306
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 07:54:05 2025 -0700

    Linter

commit e8d6936a47
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 07:53:43 2025 -0700

    Example

commit 961d6fc451
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 07:52:23 2025 -0700

    Update default links

commit 0b2853859b
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Wed Oct 8 07:44:59 2025 -0700

    Default fast fasle

commit 9d67594b63
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 22:01:24 2025 -0700

    Simplify

commit f5712bdec0
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 21:45:00 2025 -0700

    Parsing json

commit 503af624dd
Merge: ef7fa1e4 0d2522b1
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 21:04:31 2025 -0700

    Merge branch 'flat-output' of https://github.com/browser-use/browser-use into flat-output

commit ef7fa1e401
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 21:04:28 2025 -0700

    Add prompt description handling for browser-use cloud service

    - Enhanced the Agent class to generate and pass prompt descriptions to the LLM when using the browser-use provider.
    - Updated the ChatBrowserUse class to accept an optional prompt_description parameter in the ainvoke method.
    - Modified the tracked_ainvoke function in TokenCost to forward additional keyword arguments.
    - Adjusted example model to initialize Laminar for tracing.

commit 0d2522b1f9
Author: Gregor Žunič <36313686+gregpr07@users.noreply.github.com>
Date:   Tue Oct 7 20:23:39 2025 -0700

    updated default base url

commit 0a2e6d6520
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 18:50:56 2025 -0700

    Hide api key

commit 96bba9692b
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 18:49:05 2025 -0700

    Add env var loading and validation to ChatBrowserUse, update example

commit c2e57a3bab
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 18:36:31 2025 -0700

    Linter

commit 3d4cc1dbec
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 16:28:10 2025 -0700

    Rename

commit 14ab0b75fe
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 16:21:52 2025 -0700

    Rename super_fast to fast parameter in ChatBrowserUse

commit 7fab3c47d3
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 16:08:10 2025 -0700

    Update system prompt

commit 2066e77b98
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 16:07:51 2025 -0700

    Del claude file

commit 297b767e91
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 16:01:50 2025 -0700

    Revert flash system prompt to JSON format

    - Reverted system_prompt_flash.md to main (JSON format)
    - Added examples/models/browser_use_cloud.py for llm-use cloud service
    - llm-use service will inject unstructured format on the server side

commit 99af55f8e9
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 15:58:40 2025 -0700

    Example

commit 657ff0d352
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 15:54:23 2025 -0700

    Remove unused

commit a42123d8e5
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 15:49:54 2025 -0700

    ignore

commit de4fe19020
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 15:48:01 2025 -0700

    Example

commit 27e5ab9947
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 14:29:01 2025 -0700

    Add llm-use cloud client example

    - ChatLLMUseCloud: Browser-use compatible client for llm-use service
    - Implements BaseChatModel protocol with proper typing
    - Includes credit checking before/after tasks
    - Error handling for 401/402/500 responses
    - Converts messages between browser-use and HTTP API formats
    - Returns ChatInvokeCompletion with usage stats

    Usage:
      export LLM_USE_URL='https://your-app.railway.app'
      export LLM_USE_API_KEY='your-key'
      python examples/llm_use_cloud_client.py

commit a47a448005
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Tue Oct 7 13:03:59 2025 -0700

    Enhance response parsing in ChatBrowserUse to handle structured data from the API, including debug logging for received data keys.

commit e79c7dc633
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Mon Oct 6 19:39:29 2025 -0700

    Include browser-use llm

commit 584d977154
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Mon Oct 6 17:55:31 2025 -0700

    Linter

commit b0ac87076a
Merge: 1183b8fe 0076775f
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Mon Oct 6 15:01:37 2025 -0700

    merge main

commit 1183b8fe6b
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 16:26:34 2025 -0700

    Fix done output action model

commit 852449b1bc
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 16:23:31 2025 -0700

    More debug info

commit a57ba25d36
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 16:07:15 2025 -0700

    Multiline parser

commit 2153dbe6aa
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 15:50:14 2025 -0700

    Fix custom output

commit ec5c08ba0f
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 15:36:54 2025 -0700

    Fix files in output

commit 7444048e8f
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 15:28:09 2025 -0700

    Update codebase with unstructured output

commit a8f05b4611
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 14:55:20 2025 -0700

    Save systemprompt

commit d7d112c569
Author: Magnus Müller <67061560+MagMueller@users.noreply.github.com>
Date:   Sun Oct 5 14:51:24 2025 -0700

    new parser
2025-10-08 08:39:24 -07:00

175 lines
5.6 KiB
Python

from collections.abc import Callable
from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, ConfigDict
from browser_use.browser import BrowserSession
from browser_use.filesystem.file_system import FileSystem
from browser_use.llm.base import BaseChatModel
if TYPE_CHECKING:
pass
class RegisteredAction(BaseModel):
"""Model for a registered action"""
name: str
description: str
function: Callable
param_model: type[BaseModel]
# filters: provide specific domains to determine whether the action should be available on the given URL or not
domains: list[str] | None = None # e.g. ['*.google.com', 'www.bing.com', 'yahoo.*]
model_config = ConfigDict(arbitrary_types_allowed=True)
def prompt_description(self) -> str:
"""Get a description of the action for the prompt in unstructured format"""
schema = self.param_model.model_json_schema()
params = []
if 'properties' in schema:
for param_name, param_info in schema['properties'].items():
# Build parameter description
param_desc = param_name
# Add type information if available
if 'type' in param_info:
param_type = param_info['type']
param_desc += f'={param_type}'
# Add description as comment if available
if 'description' in param_info:
param_desc += f' ({param_info["description"]})'
params.append(param_desc)
# Format: action_name: Description. (param1=type, param2=type, ...)
if params:
return f'{self.name}: {self.description}. ({", ".join(params)})'
else:
return f'{self.name}: {self.description}'
class ActionModel(BaseModel):
"""Base model for dynamically created action models"""
# this will have all the registered actions, e.g.
# click_element = param_model = ClickElementParams
# done = param_model = None
#
model_config = ConfigDict(arbitrary_types_allowed=True, extra='forbid')
def get_index(self) -> int | None:
"""Get the index of the action"""
# {'clicked_element': {'index':5}}
params = self.model_dump(exclude_unset=True).values()
if not params:
return None
for param in params:
if param is not None and 'index' in param:
return param['index']
return None
def set_index(self, index: int):
"""Overwrite the index of the action"""
# Get the action name and params
action_data = self.model_dump(exclude_unset=True)
action_name = next(iter(action_data.keys()))
action_params = getattr(self, action_name)
# Update the index directly on the model
if hasattr(action_params, 'index'):
action_params.index = index
class ActionRegistry(BaseModel):
"""Model representing the action registry"""
actions: dict[str, RegisteredAction] = {}
@staticmethod
def _match_domains(domains: list[str] | None, url: str) -> bool:
"""
Match a list of domain glob patterns against a URL.
Args:
domains: A list of domain patterns that can include glob patterns (* wildcard)
url: The URL to match against
Returns:
True if the URL's domain matches the pattern, False otherwise
"""
if domains is None or not url:
return True
# Use the centralized URL matching logic from utils
from browser_use.utils import match_url_with_domain_pattern
for domain_pattern in domains:
if match_url_with_domain_pattern(url, domain_pattern):
return True
return False
def get_prompt_description(self, page_url: str | None = None) -> str:
"""Get a description of all actions for the prompt
Args:
page_url: If provided, filter actions by URL using domain filters.
Returns:
A string description of available actions.
- If page is None: return only actions with no page_filter and no domains (for system prompt)
- If page is provided: return only filtered actions that match the current page (excluding unfiltered actions)
"""
if page_url is None:
# For system prompt (no URL provided), include only actions with no filters
return '\n'.join(action.prompt_description() for action in self.actions.values() if action.domains is None)
# only include filtered actions for the current page URL
filtered_actions = []
for action in self.actions.values():
if not action.domains:
# skip actions with no filters, they are already included in the system prompt
continue
# Check domain filter
if self._match_domains(action.domains, page_url):
filtered_actions.append(action)
return '\n'.join(action.prompt_description() for action in filtered_actions)
class SpecialActionParameters(BaseModel):
"""Model defining all special parameters that can be injected into actions"""
model_config = ConfigDict(arbitrary_types_allowed=True)
# optional user-provided context object passed down from Agent(context=...)
# e.g. can contain anything, external db connections, file handles, queues, runtime config objects, etc.
# that you might want to be able to access quickly from within many of your actions
# browser-use code doesn't use this at all, we just pass it down to your actions for convenience
context: Any | None = None
# browser-use session object, can be used to create new tabs, navigate, access CDP
browser_session: BrowserSession | None = None
# Current page URL for filtering and context
page_url: str | None = None
# CDP client for direct Chrome DevTools Protocol access
cdp_client: Any | None = None # CDPClient type from cdp_use
# extra injected config if the action asks for these arg names
page_extraction_llm: BaseChatModel | None = None
file_system: FileSystem | None = None
available_file_paths: list[str] | None = None
has_sensitive_data: bool = False
@classmethod
def get_browser_requiring_params(cls) -> set[str]:
"""Get parameter names that require browser_session"""
return {'browser_session', 'cdp_client', 'page_url'}