There are many cases where it is helpful to define custom tools for the RAG Agent. R2R allows for users to define custom tools, passing these definitions into the Agent at server start.

### Defining New Tools
There is a directory in the R2R repository, `/docker/user_tools`, which is mounted to the R2R docker container. It is here that we will place our custom tool files.

There, we will find a README.md file, which includes a template for our new tool:


```python
from core.base.agent.tools.base import Tool


class ToolNameTool(Tool):
    """
    A user defined tool.
    """

    def __init__(self):
        super().__init__(
            name="tool_name",
            description="A natural language tool description that is shown to the agent.",
            parameters={
                "type": "object",
                "properties": {
                    "input_parameter": {
                        "type": "string",
                        "description": "Define any input parameters by their name and type",
                    },
                },
                "required": ["input_parameter"],
            },
            results_function=self.execute,
            llm_format_function=None,
        )

    async def execute(self, input_parameter: str, *args, **kwargs):
        """
        Implementation of the tool.
        """

        # Any custom tool logic can go here

        output_response = some_method(input_parameter)

        result = AggregateSearchResult(
            generic_tool_result=[web_response],
        )

        # Add to results collector if context is provided
        if context and hasattr(context, "search_results_collector"):
            context.search_results_collector.add_aggregate_result(result)

        return result
```

This template has two basic methods:

1. `__init__` is where we define the tool. The description that we make here is shown to the agent.
2. `execute` is where we define any custom tool logic and interact with the inputs.

### Writing our new tool

Below, we have an example of a toy tool, which takes an integer and string input, returning a silly message to the agent. Should your tool require additional dependencies, be sure to include them in the `user_requirements.txt` file located in the `/docker` directory.

```python
from r2r import Tool, AggregateSearchResult


class SecretMethodTool(Tool):
    """
    A user defined tool.
    """

    def __init__(self):
        super().__init__(
            name="secret_method",
            description="Performs a secret method.",
            parameters={
                "type": "object",
                "properties": {
                    "number": {
                        "type": "string",
                        "description": "An integer input for the secret method.",
                    },
                    "string": {
                        "type": "string",
                        "description": "A string input for the secret method.",
                    },
                },
                "required": ["number", "string"],
            },
            results_function=self.execute,
            llm_format_function=None,
        )

    async def execute(self, number: int, string: str, *args, **kwargs):
        """
        Implementation of the tool.
        """

        output_response = f"Your order for {number} dancing flamingos has been received. They will arrive by unicycle courier within 3-5 business dreams. Please prepare {string} for them."

        result = AggregateSearchResult(
            generic_tool_result=output_response,
        )

        context = self.context
        # Add to results collector if context is provided
        if context and hasattr(context, "search_results_collector"):
            context.search_results_collector.add_aggregate_result(result)

        return result
```

Finally, we can modify our configuration file's `agent` section to include our new tool:

```toml
[agent]
rag_tools = ["secret_method"]
```


Finally, we can run the following and see that our agent called our new method, passed the required parameters, and understood its output:

```python
client.retrieval.agent(
    message={"role": "user", "content": "Can you run the secret method tool? Feel free to use any parameters you want. I just want to see the output."},
)
```

```zsh
results=AgentResponse(messages=[Message(role='assistant', content='The secret method tool produced the following output:\n\n"Your order for 42 dancing flamingos has been received. They will arrive by unicycle courier within 3-5 business dreams. Please prepare Hello, World! for them."\n\nThis whimsical response seems to be a playful and humorous output generated by the tool.', name=None, function_call=None, tool_calls=None, tool_call_id=None, metadata={'citations': [], 'tool_calls': [{'name': 'secret_method', 'args': '{"number":"42","string":"Hello, World!"}'}], 'aggregated_search_result': '[]'}, structured_content=None, image_url=None, image_data=None)], conversation_id='12ad2d6b-1429-48ea-9077-711726d8cfde')
```
