> ## Documentation Index
> Fetch the complete documentation index at: https://slide.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding tools to agents

> Learn how to give your agents new capabilities with tools

Tools are what make agents powerful. They allow your agent to interact with the world - searching the web, processing files, analyzing images, and much more. In this guide, you'll learn how to add tools to your agents.

**💻 Code Examples**

<CardGroup cols={2}>
  <Card title="Basic Tools" icon="wrench" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/100_tools_basic.py">
    Get started with agent tools
  </Card>

  <Card title="Selective Tools" icon="filter" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/102_selective_tools.py">
    Pick specific tools from groups
  </Card>

  <Card title="Tool Groups" icon="layer-group" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/107_tools_group_import.py">
    Import and combine tool groups
  </Card>

  <Card title="Image Tools" icon="image" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/104_tools_image.py">
    Analyze images with agents
  </Card>
</CardGroup>

## Understanding Tools in Slide

Tools in Slide follow the OpenAI function calling format. Each tool has:

* A **definition** that describes what it does
* An **implementation** that executes the action

## Using Lye's built-in tools

The easiest way to add tools is using Lye's pre-built tool groups:

```python theme={null}
from tyler import Agent
from lye import WEB_TOOLS, IMAGE_TOOLS, FILES_TOOLS, AUDIO_TOOLS, BROWSER_TOOLS

# Agent with all capabilities
agent = Agent(
    name="powerful-assistant",
    model_name="gpt-4",
    purpose="To help with any task",
    tools=[
        *WEB_TOOLS,      # search, fetch
        *IMAGE_TOOLS,    # analyze_image, extract_text_from_image
        *FILES_TOOLS,    # read_file, write_file, list_files
        *AUDIO_TOOLS,    # transcribe, text_to_speech
        *BROWSER_TOOLS   # screenshot, extract_text_from_webpage
    ]
)
```

## Tool Groups Explained

### Web Tools

Perfect for research and information gathering:

```python theme={null}
from lye import WEB_TOOLS

# Includes:
# - search: Search the web for information
# - fetch: Get content from a specific URL
```

### Image Tools

For visual analysis and OCR:

```python theme={null}
from lye import IMAGE_TOOLS

# Includes:
# - analyze_image: Describe images and answer questions
# - extract_text_from_image: OCR text extraction
```

### File Tools

For reading and writing files:

```python theme={null}
from lye import FILES_TOOLS

# Includes:
# - read_file: Read file contents
# - write_file: Create or update files
# - list_files: List directory contents
```

### Audio Tools

For speech processing:

```python theme={null}
from lye import AUDIO_TOOLS

# Includes:
# - transcribe: Convert speech to text
# - text_to_speech: Generate speech from text
```

### Browser Tools

For web automation:

```python theme={null}
from lye import BROWSER_TOOLS

# Includes:
# - screenshot: Capture webpage screenshots
# - extract_text_from_webpage: Get clean text from pages
```

## Selective Tool Usage

Sometimes you only need specific tools:

```python theme={null}
from lye.web import search
from lye.files import write_file
from lye.image import analyze_image

agent = Agent(
    name="research-writer",
    model_name="gpt-4",
    purpose="To research topics and write reports",
    tools=[search, write_file, analyze_image]  # Only what's needed
)
```

## Creating custom tools

You can create your own tools by following the OpenAI function format:

```python theme={null}
def get_weather(location: str, unit: str = "celsius") -> str:
    """Get the current weather for a location."""
    # Your implementation here
    return f"The weather in {location} is sunny and 22°{unit[0].upper()}"

# Tool definition
weather_tool = {
    "definition": {
        "name": "get_weather",
        "description": "Get the current weather for a location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and country, e.g. San Francisco, USA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "Temperature unit"
                }
            },
            "required": ["location"]
        }
    },
    "implementation": get_weather
}

# Use your custom tool
agent = Agent(
    name="weather-assistant",
    model_name="gpt-4",
    purpose="To provide weather information",
    tools=[weather_tool]
)
```

## Advanced Custom Tools

Here's a more complex example with async support and error handling:

```python theme={null}
import aiohttp
import json

async def call_api(endpoint: str, method: str = "GET", data: dict = None) -> str:
    """Make an API call to an external service."""
    async with aiohttp.ClientSession() as session:
        try:
            if method == "GET":
                async with session.get(endpoint) as response:
                    result = await response.json()
            else:
                async with session.post(endpoint, json=data) as response:
                    result = await response.json()
            
            return json.dumps(result, indent=2)
        except Exception as e:
            return f"Error calling API: {str(e)}"

api_tool = {
    "definition": {
        "name": "call_api",
        "description": "Make HTTP API calls to external services",
        "parameters": {
            "type": "object",
            "properties": {
                "endpoint": {
                    "type": "string",
                    "description": "The API endpoint URL"
                },
                "method": {
                    "type": "string",
                    "enum": ["GET", "POST"],
                    "description": "HTTP method"
                },
                "data": {
                    "type": "object",
                    "description": "Data to send with POST request"
                }
            },
            "required": ["endpoint"]
        }
    },
    "implementation": call_api
}
```

## Tool Combinations for Common Tasks

### Research assistant

```python theme={null}
from lye import WEB_TOOLS, FILES_TOOLS

research_agent = Agent(
    name="researcher",
    model_name="gpt-4",
    purpose="To conduct thorough research and create reports",
    tools=[*WEB_TOOLS, *FILES_TOOLS]
)
```

### Content Analyzer

```python theme={null}
from lye import IMAGE_TOOLS, AUDIO_TOOLS, FILES_TOOLS

analyzer_agent = Agent(
    name="content-analyzer",
    model_name="gpt-4",
    purpose="To analyze multimedia content",
    tools=[*IMAGE_TOOLS, *AUDIO_TOOLS, *FILES_TOOLS]
)
```

### Web Scraper

```python theme={null}
from lye import WEB_TOOLS, BROWSER_TOOLS, FILES_TOOLS

scraper_agent = Agent(
    name="web-scraper",
    model_name="gpt-4",
    purpose="To extract and save information from websites",
    tools=[*WEB_TOOLS, *BROWSER_TOOLS, *FILES_TOOLS]
)
```

## Tool Timeouts

For tools that might take a long time (API calls, database queries), you can set a timeout using the low-level tool runner:

```python theme={null}
from tyler.utils.tool_runner import tool_runner

async def slow_api_call(query: str) -> str:
    """Call an external API that might be slow."""
    # ... implementation
    pass

# Register with a 30-second timeout
tool_runner.register_tool(
    name="slow_api_call",
    implementation=slow_api_call,
    definition={
        "name": "slow_api_call",
        "description": "Call external API",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string"}
            },
            "required": ["query"]
        }
    },
    timeout=30.0  # Timeout in seconds
)
```

### Timeout Behavior

When a tool exceeds its timeout:

1. A `TimeoutError` is raised with the message: `Tool 'tool_name' timed out after X seconds`
2. The error is returned to the LLM as the tool result
3. The LLM can then decide how to proceed (retry, try a different approach, or inform the user)

<Note>
  Timeouts work for both async and synchronous tools. For sync tools, the operation runs in a thread pool with the timeout applied to the entire operation.
</Note>

<Warning>
  For synchronous tools, the underlying thread cannot be forcibly stopped after a timeout—it will continue running in the background. For truly cancellable long-running operations, implement your tools as async functions.
</Warning>

You can also specify timeouts in the lye tool format:

```python theme={null}
my_tool = {
    "definition": {
        "type": "function",
        "function": {
            "name": "my_slow_tool",
            "description": "A tool that might take a while",
            "parameters": {...}
        }
    },
    "implementation": my_slow_function,
    "timeout": 60.0  # 60 second timeout
}
```

## Best practices

### 1. Tool Selection

Only give your agent the tools it needs:

```python theme={null}
# ❌ Too many tools
tools=[*WEB_TOOLS, *IMAGE_TOOLS, *AUDIO_TOOLS, *FILES_TOOLS, *BROWSER_TOOLS]

# ✅ Just what's needed
tools=[*WEB_TOOLS, *FILES_TOOLS]
```

### 2. Clear Tool Descriptions

When creating custom tools, write clear descriptions:

```python theme={null}
# ❌ Vague
"description": "Does something with data"

# ✅ Clear
"description": "Fetches user data from the API and returns formatted profile information"
```

### 3. Error Handling

Always handle errors in custom tools:

```python theme={null}
async def safe_api_call(url: str) -> str:
    try:
        # API call logic
        return result
    except Exception as e:
        return f"Error: {str(e)}"
```

### 4. Tool Composition

Combine tools for complex workflows:

```python theme={null}
# Agent that can research, analyze, and report
agent = Agent(
    name="analyst",
    model_name="gpt-4",
    purpose="To analyze data from multiple sources",
    tools=[
        *WEB_TOOLS,      # Gather data
        *IMAGE_TOOLS,    # Analyze visuals
        *FILES_TOOLS     # Save results
    ]
)
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Can't process scanned PDFs">
    For OCR support with image-based PDFs, install poppler:

    * macOS: `brew install poppler`
    * Ubuntu: `sudo apt-get install poppler-utils`
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Tool Patterns" icon="diagram-project" href="/guides/patterns">
    Advanced patterns for tool usage
  </Card>

  <Card title="Testing with Tools" icon="vial" href="/guides/testing-agents">
    Test agents with mock tools
  </Card>

  <Card title="MCP Integration" icon="plug" href="/guides/mcp-integration">
    Use MCP tools with your agents
  </Card>

  <Card title="Using Lye" icon="toolbox" href="/guides/using-lye">
    Explore all built-in tools
  </Card>
</CardGroup>
