Skip to main content
A decorated function becomes a tool the model can call next to its Python REPL. Its parameters, with type hints, become the tool’s arguments. The description tells the model when to use it. Sync and async functions both work. python(code) runs a cell in the REPL worker process, which drives the browser. A @tools.action function such as get_price(sku) runs in your process with only the arguments the model passes; its return value or error goes back to the model. finish(result) delivers the result and ends the run. python(code) runs a cell in the REPL worker process, which drives the browser. A @tools.action function such as get_price(sku) runs in your process with only the arguments the model passes; its return value or error goes back to the model. finish(result) delivers the result and ends the run.

Return values

The model sees what the function returns: a str, a Pydantic model or other JSON-able value, or an ActionResult(extracted_content=..., error=...). A value that can’t be serialized (an SDK client, a response object) reaches the model as its str().

Errors

  • A tool that raises does not end the run. The model gets the error and can recover.
  • Raise pydantic_ai.ModelRetry('...') to ask the model to call the tool again with better arguments.

param_model

To keep a 0.x action that takes one model argument, pass param_model:

Rules

  • Use @tools.action('description') with parentheses.
  • Names must match [a-zA-Z0-9_-]{1,64}. python, finish and finish_from_repl are taken.
  • A tool gets only the arguments the model passes. The 0.x injected parameters (browser_session, page_extraction_llm, file_system, …) raise.
  • ActionResult(is_done=True, ...), success=, attachments=[...] and images=[...] raise: the model ends the run with finish, and saves files in the workspace. A function that returns one raises a TypeError when @tools.action registers it, before any browser starts. include_in_memory and include_extracted_content_only_once log a warning and are ignored: every result stays in the conversation.
  • Registering a name again replaces the earlier tool, as in 0.x.
  • domains=, allowed_domains=, page_filter=, requires_browser= and terminates_sequence= raise. Limit navigation with Browser(allowed_domains=...).
  • A <secret>name</secret> placeholder in a tool’s arguments is not replaced: the tool does not run and the model gets an error. Secrets are typed in the browser with type_secret(name).
  • Controller is an alias of Tools.

No built-in actions

0.x had built-in actions such as click, extract and scroll. 1.0 has none: the agent writes Python with browser helpers instead, so Tools(exclude_actions=...) raises. The helpers it uses include new_tab, goto_url, js, cdp, click_at_xy, type_text, press_key, scroll, screenshot, upload_file, http_get, checkpoint and show_image. Write a tool when the agent needs something the browser can’t give it: your database, an internal API, a 2FA code from your vault, a human approval.