Tools
With run_agent, the agent can only call tools you pass explicitly through the tools parameter.
from abstra.ai import run_agent, TablesTools, FilesTools, ConnectorsTools, BrowserTools
You can pass custom Python functions, built-in toolkits, or both:
from abstra.ai import run_agent, TablesTools
def enrich_customer(email: str) -> dict:
"""Looks up customer data from the CRM by email."""
return {"name": "John", "plan": "pro"}
run_agent(
prompt="Find customer john@example.com in the CRM, then update their plan in the database.",
tools=[
enrich_customer,
TablesTools(method=["select", "update"], table="customers"),
],
)
Custom Python functions
Any Python function can be a tool. The agent uses the function name, docstring, and type hints to decide when and how to call it.
from abstra.ai import run_agent
def get_order_status(order_id: str) -> str:
"""Returns the current status for an order id."""
return "shipped"
run_agent(
prompt="Find the order status for order_id=123 and explain it to the customer.",
tools=[get_order_status],
)
Tips for custom tools:
- Always add a docstring — it becomes the tool description the agent sees.
- Use type hints on all parameters — they define the JSON schema for arguments.
- Keep function names descriptive — the agent reads them to decide which tool to use.
TablesTools
Give the agent access to your Abstra Tables. See TablesTools reference for the full constructor signature.
from abstra.ai import run_agent, TablesTools
run_agent(
prompt="List all open tickets and summarize them.",
tools=[TablesTools(method=["select"], table="tickets")],
)
run_agent(
prompt="Process the pending orders for tenant abc.",
tools=[
TablesTools(
method="all",
table=["orders", "order_items"],
where={"tenant_id": "abc"},
)
],
)
run_agent(
prompt="Find the top 10 customers by revenue.",
tools=[TablesTools(allow_sql=True)],
)
Tools exposed
| Tool | Signature | Notes |
|---|---|---|
select | select(table: str, where: dict = {}) -> list[dict] | Read rows. Returns iterable of dicts. |
insert | insert(table: str, data: dict) | Insert a single row. Returns the inserted row. |
update | update(table: str, set: dict, where: dict = {}) | Update matching rows. |
delete | delete(table: str, where: dict = {}) | Delete matching rows. |
run_sql | run_sql(query: str) | Only when allow_sql=True. Executes raw SQL. |
The constructor's where is merged into every call as defaults — useful for tenant scoping.
FilesTools
Give the agent access to the project filesystem. See FilesTools reference for the full constructor signature.
from abstra.ai import run_agent, FilesTools
run_agent(
prompt="Read all files in data/ and summarize their contents.",
tools=[FilesTools(actions=["read_text", "list"], globs=["data/*"])],
)
run_agent(
prompt="Parse input.csv, clean the data, and write the result to output.csv.",
tools=[FilesTools(actions=["read_text", "write_text"], globs=["*.csv"])],
)
Tools exposed
| Tool | Signature | Enabled by |
|---|---|---|
read_text | read_text(path, encoding="utf-8") -> str | read or read_text |
read_bytes | read_bytes(path) -> bytes | read or read_bytes |
write_text | write_text(path, data: str, encoding="utf-8") | write or write_text |
write_bytes | write_bytes(path, data: bytes) | write or write_bytes |
delete | delete(path) | delete |
move | move(src, dst) | move |
list | list(path) -> list[str] | list |
append | append(path, data: str, encoding="utf-8") | append |
Every call validates the path against the configured globs. Calls outside the allowed paths raise ValueError.
ConnectorsTools
Give the agent access to your configured connectors (Slack, Stripe, APIs, etc.). See ConnectorsTools reference for the full constructor signature.
from abstra.ai import run_agent, ConnectorsTools
run_agent(
prompt="Notify the #orders channel about the new order.",
tools=[ConnectorsTools(connection="slack", action="send_message")],
)
run_agent(
prompt="Charge the customer and send a receipt by email.",
tools=[
ConnectorsTools(
connection=["stripe", "email"],
action=["create_charge", "send_email"],
params={"currency": "brl"},
)
],
)
Tools exposed
| Tool | Signature | Notes |
|---|---|---|
call | call(connection: str, action: str, params: dict = {}) | The single tool. Constructor's connection/action filters limit which combinations are accepted. Constructor's params are merged into every call as defaults. |
BrowserTools
Give the agent a headless Chromium browser to navigate and interact with web pages. See BrowserTools reference for the full constructor signature.
from abstra.ai import run_agent, BrowserTools
run_agent(
prompt="Go to https://news.ycombinator.com and get the top 5 stories with titles and URLs.",
tools=[BrowserTools(url="https://news.ycombinator.com")],
max_steps=10,
)
run_agent(
prompt="""Go to https://app.example.com/login, fill in user@test.com and password123,
click Login, then take a screenshot of the dashboard.""",
tools=[BrowserTools(url="https://app.example.com")],
)
run_agent(
prompt="Navigate to the page and check for any failed API calls or console errors.",
tools=[BrowserTools(
url="https://app.example.com",
listen_network=True,
listen_console=True,
)],
)
Tools exposed
Always available:
| Tool | Signature | Notes |
|---|---|---|
navigate_to_url | navigate_to_url(url, page_id=None) -> dict | Open a new page or navigate an existing one. Returns {page_id, ...}. |
list_pages | list_pages() -> list[dict] | List currently open pages with their page_id, URL, and title. |
get_page_summary | get_page_summary(page_id, max_elements=50) | Most important read tool. Returns up to N interactive elements with index, selector, text, tag, category, parent_context. Indices are stable until the DOM changes — call again after any action that mutates the page. |
get_element_by_summary_index | get_element_by_summary_index(page_id, index) | Detailed info (bbox, attributes) for one element from the last summary. |
click_element | click_element(page_id, index) | Preferred way to click. Pass an index from get_page_summary instead of a CSS selector. |
click | click(page_id, selector) | Fallback when you need a raw CSS selector. |
fill_element | fill_element(page_id, index, value) | Preferred way to fill form fields. |
fill | fill(page_id, selector, value) | Raw selector fallback. |
get_text | get_text(page_id, selector) -> str | Inner text of an element. |
get_attribute | get_attribute(page_id, selector, attribute) -> str | One HTML attribute. |
get_attributes | get_attributes(page_id, selector) -> dict | All HTML attributes. |
get_html | get_html(page_id) -> str | Full page HTML. Prefer get_page_summary unless you really need raw HTML. |
get_all_links | get_all_links(page_id) -> list[dict] | All <a> links as {text, href}. |
download_file | download_file(page_id, selector=None, index=None, output_path=None, overwrite=False, timeout_ms=30000) -> dict | Save a file produced by clicking a link or button. Prefer index from get_page_summary; returns the saved path, suggested filename, source URL, and byte size. |
download_url | download_url(page_id, url, output_path=None, overwrite=False, timeout_ms=30000) -> dict | Save a direct URL using the browser context's cookies/session. Relative URLs resolve against the current page. |
execute_javascript | execute_javascript(page_id, script) | Run JS on the page. Invalidates the page summary cache — call get_page_summary again before using any prior indices. |
wait | wait(page_id, milliseconds=1000) | Sleep without invalidating the cache. Use after clicks, submits, or transitions before taking a screenshot. |
screenshot | screenshot(page_id, ...) | Returns a base64 PNG. Supports show_markers=True to overlay numbered labels on interactive elements, and highlight_element=<selector> to draw a red border around a specific element. |
close_page | close_page(page_id) | Disabled when allow_close_page=False. |
Conditionally enabled:
| Tool | Enabled by | Returns |
|---|---|---|
get_network_requests | listen_network=True | All HTTP requests captured during the page's lifetime. |
get_console_logs | listen_console=True | All console.log/warn/error/info messages from the page. |
get_websocket_frames | listen_websocket=True | All WebSocket frames sent and received. Each frame is a dict with url, direction, binary, and either payload (str, text frames) or payload_b64 (base64, binary frames with binary=True). |
Combining toolkits
You can pass multiple toolkits and custom functions together. The agent decides which tools to use based on the prompt.
from abstra.ai import run_agent, TablesTools, FilesTools, ConnectorsTools
run_agent(
prompt="""Read the CSV file with customer complaints, categorize each one,
insert the results into the complaints table, and send a Slack summary.""",
tools=[
FilesTools(actions=["read_text"], globs=["complaints.csv"]),
TablesTools(method=["insert"], table="complaints"),
ConnectorsTools(connection="slack", action="send_message"),
],
)
For longer pipelines and multi-tool examples, see Examples.
Recommendations
- Start with small, explicit toolsets instead of exposing broad access.
- Use strong type hints and clear docstrings on custom tools.
- Keep
max_stepsconservative to avoid long, expensive loops. - Prefer specific table/file/connection names over unrestricted access.
- For browser sessions, prefer
*_elementvariants over CSS selectors. They're paired to the latestget_page_summaryand are robust to selector changes.