skills/open-source/references/tools.md
from browser_use import Tools, ActionResult, BrowserSession
tools = Tools()
@tools.action('Ask human for help with a question')
async def ask_human(question: str, browser_session: BrowserSession) -> ActionResult:
answer = input(f'{question} > ')
return ActionResult(extracted_content=f'The human responded with: {answer}')
agent = Agent(task='Ask human for help', llm=llm, tools=tools)
Warning: Parameter MUST be named
browser_session: BrowserSession, notbrowser: Browser. Agent injects by name matching — wrong name fails silently.
@tools.action(description='Fill out banking forms', allowed_domains=['https://mybank.com'])
async def fill_bank_form(account_number: str) -> ActionResult:
return ActionResult(extracted_content=f'Filled form for account {account_number}')
Decorator parameters:
description (required): What the tool does — LLM uses this to decide when to callallowed_domains: Domains where tool can run (default: all)from pydantic import BaseModel, Field
class Car(BaseModel):
name: str = Field(description='Car name, e.g. "Toyota Camry"')
price: int = Field(description='Price in USD')
@tools.action(description='Save cars to file')
def save_cars(cars: list[Car]) -> str:
with open('cars.json', 'w') as f:
json.dump([c.model_dump() for c in cars], f)
return f'Saved {len(cars)} cars'
@tools.action(description='Click submit button via CSS selector')
async def click_submit(browser_session: BrowserSession):
page = await browser_session.must_get_current_page()
elements = await page.get_elements_by_css_selector('button[type="submit"]')
if not elements:
return ActionResult(extracted_content='No submit button found')
await elements[0].click()
return ActionResult(extracted_content='Clicked!')
The agent fills function parameters by name. These special names are auto-injected:
| Parameter Name | Type | Description |
|---|---|---|
browser_session | BrowserSession | Current browser session (CDP access) |
cdp_client | Direct Chrome DevTools Protocol client | |
page_extraction_llm | BaseChatModel | The LLM passed to agent |
file_system | FileSystem | File system access |
available_file_paths | list[str] | Files available for upload/processing |
has_sensitive_data | bool | Whether action contains sensitive data |
page = await browser_session.must_get_current_page()
# CSS selector
elements = await page.get_elements_by_css_selector('button.submit')
# LLM-powered (natural language)
element = await page.get_element_by_prompt("login button", llm=page_extraction_llm)
element = await page.must_get_element_by_prompt("login button", llm=page_extraction_llm) # raises if not found
Source: tools/service.py
search — Search queries (DuckDuckGo, Google, Bing)navigate — Navigate to URLsgo_back — Go back in historywait — Wait for specified secondsclick — Click elements by indexinput — Input text into form fieldsupload_file — Upload filesscroll — Scroll page up/downfind_text — Scroll to specific textsend_keys — Send keys (Enter, Escape, Tab, etc.)evaluate — Execute custom JS (shadow DOM, selectors, extraction)switch — Switch between tabsclose — Close tabsextract — Extract data using LLMscreenshot — Request screenshot in next browser statedropdown_options — Get dropdown valuesselect_dropdown — Select dropdown optionwrite_file — Write to filesread_file — Read filesreplace_file — Replace text in filesdone — Complete the task (always available)tools = Tools(exclude_actions=['search', 'wait'])
agent = Agent(task='...', llm=llm, tools=tools)
@tools.action('My tool')
def my_tool() -> str:
return "Task completed successfully"
@tools.action('Advanced tool')
def advanced_tool() -> ActionResult:
return ActionResult(
extracted_content="Main result",
long_term_memory="Remember this for all future steps",
error="Something went wrong",
is_done=True,
success=True,
attachments=["file.pdf"],
)
| Field | Default | Description |
|---|---|---|
extracted_content | None | Main result passed to LLM |
include_extracted_content_only_once | False | Show large content only once, then drop |
long_term_memory | None | Always included in LLM input for all future steps |
error | None | Error message (auto-caught exceptions set this) |
is_done | False | Tool completes entire task |
success | None | Task success (only with is_done=True) |
attachments | None | Files to show user |
metadata | None | Debug/observability data |
extracted_content + include_extracted_content_only_once=True + long_term_memorylong_term_memory alone