async functions both work.
Return values
The model sees what the function returns: astr, 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, passparam_model:
Rules
- Use
@tools.action('description')with parentheses. - Names must match
[a-zA-Z0-9_-]{1,64}.python,finishandfinish_from_replare 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=[...]andimages=[...]raise: the model ends the run withfinish, and saves files in the workspace. A function that returns one raises aTypeErrorwhen@tools.actionregisters it, before any browser starts.include_in_memoryandinclude_extracted_content_only_oncelog 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=andterminates_sequence=raise. Limit navigation withBrowser(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 withtype_secret(name). Controlleris an alias ofTools.
No built-in actions
0.x had built-in actions such asclick, 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.