Tools Documentation
Build powerful, reusable function tools and stateful class tools. Typed signatures become schemas automatically; docstrings become human-friendly descriptions.
Pro Tip: For class-based tools, pass the instance directly! ConnectOnion automatically discovers all public methods with type hints.
Quick Start
main.py
1from connectonion import Agent
2
3def search(query: str) -> str:
4 return f"Found results for {query}"
5
6agent = Agent("helper", tools=[search], max_iterations=5)
7
8print(agent.input("Find Python tutorials"))
Python REPL
Interactive
>>> agent = Agent("helper", tools=[search], max_iterations=5)
>>> print(agent.input("Find Python tutorials"))
I'll search for Python tutorials.
Found results for Python tutorials
Based on my search, here are some excellent Python tutorials for you:
1. Official Python Tutorial - Great for beginners
2. Real Python - Comprehensive guides and examples
3. Python.org Beginner's Guide - Step-by-step introduction
4. W3Schools Python Tutorial - Interactive examples
5. Codecademy Python Course - Hands-on learning
Function Tools
Use Python type hints as your interface. Keep signatures explicit and return structures when needed.
main.py
1from typing import List
2from connectonion import Agent
3
4def top_k(query: str, k: int = 5) -> List[str]:
5 """Return the top-k result titles for a query."""
6 return [f"{i+1}. {query} result" for i in range(k)]
7
8agent = Agent("helper", tools=[top_k], max_iterations=8)
9
10print(agent.input("top_k('vector db', k=3)"))
Python REPL
Interactive
>>> agent = Agent("helper", tools=[top_k], max_iterations=8)
>>> print(agent.input("top_k('vector db', k=3)"))
I'll search for the top 3 results about vector databases.
['1. vector db result', '2. vector db result', '3. vector db result']
main.py
1from typing import TypedDict, List
2
3class SearchHit(TypedDict):
4 title: str
5 url: str
6 score: float
7
8def search_hits(query: str, k: int = 3) -> List[SearchHit]:
9 """Structured results for chaining and UI."""
10 return [
11 {"title": f"{query} {i}", "url": f"https://example.com/{i}", "score": 0.9 - i*0.1}
12 for i in range(k)
13 ]
Python REPL
Interactive
>>> search_hits("machine learning", k=2)
[{'title': 'machine learning 0', 'url': 'https://example.com/0', 'score': 0.9},
{'title': 'machine learning 1', 'url': 'https://example.com/1', 'score': 0.8}]
Stateful Tools: Playwright
main.py
1from typing import List, Optional
2from connectonion import Agent
3
4try:
5 from playwright.sync_api import sync_playwright, Page
6except ImportError:
7 raise SystemExit("Install Playwright: pip install playwright && playwright install")
8
9class Browser:
10 """Persistent browser session with navigation, screenshots, and tab control."""
11 def __init__(self):
12 self._p = None
13 self._browser = None
14 self._pages: dict[str, Page] = {}
15 self._active_tab: Optional[str] = None
16
17 def start(self, headless: bool = True) -> str:
18 self._p = sync_playwright().start()
19 self._browser = self._p.chromium.launch(headless=headless)
20 self._pages["main"] = self._browser.new_page()
21 self._active_tab = "main"
22 return "Browser started"
23
24 def new_tab(self, name: str) -> str:
25 if not self._browser:
26 return "Error: Browser not started"
27 if name in self._pages:
28 return f"Tab '{name}' already exists"
29 self._pages[name] = self._browser.new_page()
30 self._active_tab = name
31 return f"Opened tab '{name}'"
32
33 def list_tabs(self) -> List[str]:
34 return list(self._pages.keys())
35
36 def switch_tab(self, name: str) -> str:
37 if name not in self._pages:
38 return f"Error: No tab named '{name}'"
39 self._active_tab = name
40 return f"Switched to tab '{name}'"
41
42 def goto(self, url: str, tab: Optional[str] = None) -> str:
43 if not self._pages:
44 return "Error: Browser not started"
45 target = tab or self._active_tab
46 page = self._pages[target]
47 page.goto(url)
48 return page.title()
49
50 def screenshot(self, path: Optional[str] = None, tab: Optional[str] = None) -> str:
51 if not self._pages:
52 return "Error: Browser not started"
53 target = tab or self._active_tab
54 page = self._pages[target]
55 filename = path or f"{target}_screenshot.png"
56 page.screenshot(path=filename)
57 return filename
58
59 def close(self) -> None:
60 for page in list(self._pages.values()):
61 page.close()
62 self._pages.clear()
63 if self._browser:
64 self._browser.close()
65 if self._p:
66 self._p.stop()
67
68browser = Browser()
69agent = Agent("helper", tools=[browser], max_iterations=15) # Pass instance directly!
70
71# Try tools directly
72print(browser.start())
73print(browser.goto("https://example.com"))
74print(browser.screenshot("example.png"))
75print(browser.new_tab("docs"))
76print(browser.goto("https://playwright.dev", tab="docs"))
77print(browser.screenshot("docs.png", tab="docs"))
78print(browser.list_tabs())
79browser.close()
Python REPL
Interactive
>>> browser = Browser()
>>> browser.start()
'Browser started'
>>> browser.goto("https://example.com")
'Example Domain'
>>> browser.new_tab("docs")
'Opened tab \'docs\''
>>> browser.switch_tab("docs")
'Switched to tab \'docs\''
>>> browser.goto("https://playwright.dev")
'Fast and reliable end-to-end testing for modern web apps | Playwright'
>>> browser.list_tabs()
['main', 'docs']
Class Instance vs Individual Methods
Recommended: Class Instance
main.py
1browser = BrowserAutomation()
2
3# Clean & automatic - ConnectOnion discovers all methods!
4agent = Agent("browser_agent", tools=[browser])
Python REPL
Interactive
Auto-discovers all public methods:
- start_browser()
- navigate()
- take_screenshot()
- scrape_content()
- extract_links()
- close_browser()
Verbose: Individual Methods
main.py
1browser = BrowserAutomation()
2
3# Verbose - must list every method manually
4agent = Agent("browser_agent", tools=[
5 browser.start_browser,
6 browser.navigate,
7 browser.take_screenshot,
8 browser.scrape_content,
9 browser.extract_links,
10 browser.close_browser
11 # Easy to forget methods!
12])
Python REPL
Interactive
Problems:
- Verbose and error-prone
- Easy to forget methods
- Hard to maintain
- Must update when adding methods
ConnectOnion's Smart Discovery: When you pass a class instance, ConnectOnion automatically finds all public methods with proper type hints and makes them available as tools. Much cleaner code!