-
Notifications
You must be signed in to change notification settings - Fork 12
Creating a Custom Tool Repository for AgentLabUI
This guide explains how to create your own Git repository containing custom tools based on the Gofannon framework, which can then be loaded and used within AgentLabUI.
AgentLabUI allows you to extend its functionality by loading custom tools from external Git repositories. These tools must be built using the Gofannon BaseTool structure. By providing a tool_manifest.json file in your repository, AgentLabUI can discover, display, and integrate your custom tools into the agent creation process.
Before you start, ensure you have:
- A Python environment (Python 3.8+ recommended).
- Git installed on your system.
- Basic understanding of Python classes and modules.
- Familiarity with the Gofannon
BaseToolconcept is helpful. A Gofannon tool typically has adefinitionproperty (describing the tool for LLMs) and anfnmethod (the actual Python code to execute). - A Git hosting account (e.g., GitHub, GitLab) where you can host your public tool repository.
- Create a new directory for your tool repository:
mkdir my-gofannon-tools cd my-gofannon-tools - Initialize it as a Git repository:
git init
- (Optional) Create a
.gitignorefile to exclude common Python artifacts:__pycache__/ *.pyc .env venv/
You can organize your tools in a single Python file or a package structure.
-
Single File Example: Create
my_tools.pyin the root of your repository. -
Package Example:
my-gofannon-tools/ ├── my_tool_package/ │ ├── __init__.py │ └── specific_tool.py └── tool_manifest.json
Each custom tool should be a Python class inheriting from gofannon.base.BaseTool.
-
Import
BaseTool:
If you have Gofannon installed locally for development, you can import it. If not, you'll need to ensure your tool class structure is compatible. For AgentLabUI's ADK deployment, the key is that your tool class can be instantiated and has anexport_to_adk()method (whichBaseToolfrom Gofannon provides) or is directly an ADK-compatible tool.If Gofannon is not directly in your Python path for local development, you can define a compatible base structure. However, to leverage Gofannon's mixins (like
AdkMixin), your tool should ideally inherit fromgofannon.base.BaseTool. When AgentLabUI deploys an agent using your tool, it installs thegofannonpackage alongside your custom tool repo. -
Create your tool class:
# In your my_tools.py or my_tool_package/specific_tool.py from gofannon.base import BaseTool # You do NOT need @FunctionRegistry.register for tools in external repos # consumed by AgentLabUI, as the manifest.json is the discovery mechanism. class MyCustomWebServiceTool(BaseTool): def __init__(self, name="my_custom_web_service", api_key=None): # 'name' from manifest, api_key from setup_parameters super().__init__() self.name = name # Name from manifest or default self.api_key = api_key # Received from ToolSelector dialog if configured in manifest if not self.api_key: self.logger.warning(f"{self.name}: API key not provided during instantiation.") # You might raise an error or handle gracefully depending on the tool's needs @property def definition(self): """ This definition is used by Gofannon's AdkMixin to export the tool to a format ADK can understand. It should describe the tool for an LLM. """ return { "type": "function", "function": { "name": self.name, # Should match the ID in tool_manifest.json "description": "Fetches data from my custom web service.", "parameters": { "type": "object", "properties": { "endpoint": { "type": "string", "description": "The specific API endpoint to call (e.g., '/users')." }, "query_params": { "type": "object", "description": "A dictionary of query parameters for the API call." } }, "required": ["endpoint"] } } } def fn(self, endpoint: str, query_params: dict = None): """ The actual logic of your tool. """ if not self.api_key: return {"error": "API key is missing. Cannot execute tool."} # Example: Make an API call # import requests # headers = {"Authorization": f"Bearer {self.api_key}"} # response = requests.get(f"https://api.example.com{endpoint}", params=query_params, headers=headers) # response.raise_for_status() # return response.json() self.logger.info(f"Executing {self.name} for endpoint: {endpoint} with API key {'*' * len(self.api_key) if self.api_key else 'N/A'}") return {"message": f"Data fetched from {endpoint}", "params": query_params, "api_key_used_length": len(self.api_key) if self.api_key else 0}
Key points for your tool class:
- It must inherit (directly or indirectly) from
gofannon.base.BaseTool. - The
__init__method can accept arguments. If your tool requires configuration like API keys, define them assetup_parametersin yourtool_manifest.json(see Step 4). These will be passed as keyword arguments to__init__when AgentLabUI instantiates the tool. - The
definitionproperty must return a dictionary in the OpenAI function calling format. This describes your tool to the Language Model. Thenameinfunction.nameshould ideally match theidyou assign intool_manifest.json. - The
fnmethod contains the Python code that executes your tool's logic. Its parameters should match those defined in thepropertiesof yourdefinition.
- It must inherit (directly or indirectly) from
This is the most crucial file for AgentLabUI to discover your tools. Create a file named tool_manifest.json at the root of your repository.
The file structure should be:
{
"tools": [
{
"id": "my_custom_web_service_v1",
"name": "Custom Web Service Caller",
"description": "Connects to our internal web service to fetch data.",
"module_path": "my_tools",
"class_name": "MyCustomWebServiceTool",
"setup_parameters": [
{
"name": "api_key",
"label": "API Key",
"type": "secret",
"description": "The API key for accessing the custom web service.",
"required": true,
"default_value": ""
}
]
}
// Add more tool definitions here
]
} Manifest Fields:
-
tools: An array of tool objects. - Each tool object has:
-
id(string, required): A unique identifier for your tool. Used internally. -
name(string, required): A human-readable name displayed in AgentLabUI. -
description(string, required): A short description of what the tool does. -
module_path(string, required): The Python import path to the module containing your tool class.- If your tool is in
my_tools.pyat the root, this is"my_tools". - If in
my_tool_package/specific_tool.py, this would be"my_tool_package.specific_tool".
- If your tool is in
-
class_name(string, required): The name of your Python class for the tool. -
setup_parameters(array, optional): Defines configuration parameters your tool's__init__method needs. AgentLabUI will prompt the user for these. Each object in the array needs:-
name(string): The keyword argument name in your tool's__init__. -
label(string): Human-readable label for the UI. -
type(string): Data type, e.g.,"string","secret"(for password fields),"number","boolean". -
description(string): Description shown in the UI. -
required(boolean): If the parameter is mandatory. -
default_value(any, optional): A default value for the parameter.
-
-
If your tools require external Python libraries (e.g., requests, beautifulsoup4), create a requirements.txt file at the root of your repository.
# requirements.txt
requests==2.28.1
# other_dependency==1.2.3
When an agent using tools from this repository is deployed via AgentLabUI, the ADK deployment process will attempt to install these dependencies.
- Add your files to Git:
git add . - Commit your changes:
git commit -m "Add custom web service tool and manifest" - Create a repository on a public Git hosting service (like GitHub).
- Add the remote and push:
git remote add origin <your_repository_url.git> git push -u origin main # Or your default branch name
Make sure your repository is publicly accessible if you intend for AgentLabUI (and the underlying ADK deployment service) to clone it without authentication.
In AgentLabUI:
- When creating or editing an agent, go to the "Tools" section.
- Find the "Gofannon & Custom Tools" accordion and expand "Load Tools from Custom Git Repo".
- Enter the HTTPS URL of your Git repository (e.g.,
https://github.com/your-username/my-gofannon-tools.git). - Click "Load Tools".
- AgentLabUI will attempt to fetch
tool_manifest.jsonfrom the root of the repository at the default branch. - If successful, your custom tools will appear in the selection list, grouped by their repository URL.
- If your tool has
setup_parameters, AgentLabUI will prompt for these when you select the tool.
When you deploy an agent that uses a tool from your custom repository, the ADK deployment process will include your repository URL in the requirements. The build service will then clone your repository and install any dependencies from requirements.txt into the agent's runtime environment.
1. Repository Structure:
my-adder-tool-repo/
├── simple_calculator.py
└── tool_manifest.json
2. simple_calculator.py:
from gofannon.base import BaseTool
class SimpleAdderTool(BaseTool):
def __init__(self, name="simple_adder"):
super().__init__()
# The 'name' parameter here will be overridden by the 'id' from the manifest
# when instantiated by AgentLabUI, or you can use the manifest 'name'
# for display. The ADK tool name will be derived from the definition.
self.name = name
@property
def definition(self):
return {
"type": "function",
"function": {
"name": "simple_adder_tool", # Should match id in manifest for clarity
"description": "Adds two numbers and returns the sum.",
"parameters": {
"type": "object",
"properties": {
"number1": {"type": "number", "description": "The first number."},
"number2": {"type": "number", "description": "The second number."}
},
"required": ["number1", "number2"]
}
}
}
def fn(self, number1: float, number2: float) -> float:
"""Adds two numbers."""
self.logger.info(f"Adding {number1} and {number2}")
return number1 + number2 3. tool_manifest.json:
{
"tools": [
{
"id": "simple_adder_tool",
"name": "Simple Adder",
"description": "A tool that adds two numbers.",
"module_path": "simple_calculator",
"class_name": "SimpleAdderTool"
}
]
} -
Clear Naming: Use clear and descriptive
id,name, anddescriptionfields in your manifest. - Modularity: Keep tools focused on a single task.
-
Error Handling: Implement robust error handling within your tool's
fnmethod. -
Logging: Use
self.logger(available fromBaseTool) for logging within your tools. -
Dependencies: Clearly list all dependencies in
requirements.txt. Keep them minimal if possible. -
Security: Be mindful of security implications, especially if your tools interact with external services or handle sensitive data. Use
setup_parameterswithtype: "secret"for API keys. - Testing: Test your tools thoroughly locally before relying on them in AgentLabUI.
- Versioning: Use Git tags to version releases of your tool repository.
By following these steps, you can effectively create and share your custom Gofannon tools for use within AgentLabUI, significantly enhancing its capabilities for your specific needs.