# Tool Development Guide Tools are functions that agents can call to interact with external systems, perform calculations, or access data. The `@tool` decorator registers a Python function as an agent tool with proper schema and tracing. --- ## Basic Tool Structure ```python from laddr import tool from typing import Dict @tool( name="weather_lookup", description="Fetches current weather for a given city", parameters={ "type": "object", "properties": { "city": {"type": "string", "description": "City name"}, "units": {"type": "string", "description": "Units (metric/imperial)", "default": "metric"} }, "required": ["city"] } ) def weather_lookup(city: str, units: str = "metric") -> Dict: """Tool docstring: fetch current weather.""" try: result = get_weather(city, units) return {"status": "success", "data": result} except Exception as e: return {"status": "error", "error": str(e)} ``` --- ## The `@tool` Decorator **Syntax:** ```python @tool( name: str, description: str, parameters: dict, trace: bool = True, trace_mask: list = [] ) ``` --- ## Key Features | Parameter | Type | Required | Description | |------------|------|-----------|-------------| | name | str | ✅ | Unique identifier used by agents | | description | str | ✅ | Summary of the tool’s purpose | | parameters | dict | ✅ | JSON Schema for tool inputs | | trace | bool | ❌ | Enables or disables logging | | trace_mask | list | ❌ | Redacts sensitive trace fields | --- ### Parameter Descriptions #### `name` **Rules:** - Must be unique and descriptive - Use lowercase `snake_case` - Avoid generic names **Examples:** ```python name="web_search" name="calculate_area" name="query_database" ``` --- #### `description` **Best Practices:** - Begin with an action verb - Limit to 100 characters - Avoid redundant phrasing like “use this tool to…” **Examples:** ```python description="Scrape text content from a webpage" description="Translate text from English to French" ``` --- #### `parameters` Each tool defines a **JSON Schema** describing its accepted parameters. **Example:** ```python parameters={ "type": "object", "properties": { "url": {"type": "string", "description": "Page URL"}, "timeout": {"type": "integer", "description": "Timeout seconds", "default": 10} }, "required": ["url"] } ``` **Supported JSON Schema Types:** | Type | Description | Example | |------|--------------|---------| | string | Text input | `"hello"` | | integer | Whole numbers | `42` | | number | Decimals | `3.14` | | boolean | True/False | `true` | | array | Lists | `["a", "b"]` | | object | Nested dict | `{"key": "value"}` | --- #### `trace` Enables or disables trace logging. **Example:** ```python trace=True # Default ``` Set to `False` when: - Handling sensitive user data - Reducing log volume for high-frequency tools --- #### `trace_mask` Redacts specified fields in traces. **Example:** ```python trace_mask=["api_key", "token", "password"] ``` Fields matching these keys will appear as: ``` ***REDACTED*** ``` in logs. --- ## Example Tool Patterns ### Pattern 1: API Wrapper ```python @tool(name="api_call", description="Perform a GET request to external API") def api_call(endpoint: str) -> Dict: api_key = os.getenv("API_KEY") response = requests.get( f"https://api.example.com/{endpoint}", headers={"Authorization": f"Bearer {api_key}"}, timeout=10 ) return {"status": "success", "data": response.json()} ``` --- ### Pattern 2: Data Transformer ```python @tool(name="convert_format", description="Convert data between formats") def convert_format(data: str, to_format: str = "json") -> Dict: if to_format == "json": return {"result": json.loads(data)} elif to_format == "csv": return {"result": parse_csv(data)} else: return {"error": f"Unsupported format {to_format}"} ``` --- ### Pattern 3: File Operations ```python @tool(name="list_files", description="List files by pattern") def list_files(directory: str, pattern: str = "*") -> Dict: import glob files = glob.glob(f"{directory}/{pattern}") return {"files": files, "count": len(files)} ``` --- ## Registering Tools with Agents Tools must be passed to an agent during instantiation: ```python from laddr import Agent from tools.web_tools import web_search from tools.math_tools import calculate agent = Agent( name="researcher", tools=[web_search, calculate] ) ``` Agents automatically load the tool schemas and metadata for decision-making. --- ## Testing Tools ### Manual Testing (Python) ```python from tools.web_tools import web_search result = web_search(query="AI trends", max_results=3) print(result) ``` ### Manual Testing (API) ```bash curl -X POST http://localhost:8000/api/agents/researcher/chat \ -H "Content-Type: application/json" \ -d '{"message": "search for AI trends"}' ```