ConnectOnionConnectOnion

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!