How to Add Tools

🛠️ How to Add New Tools to LumoKit (v1.0.0)
LumoKit's power lies in its extensible tools system, allowing you to integrate new on-chain actions and research capabilities. Adding a new tool involves implementing its logic in the backend, registering it within the core system and chat controller, and then making it available and configurable in the frontend. This guide will walk you through the comprehensive process.
🌟 Overview of the Process
Adding a new tool to LumoKit generally follows these steps:
Plan Your Tool: Define its purpose, functionality, required inputs, and a unique identifier.
Backend Implementation & Registration: Create the core logic for your tool and integrate it into the LumoKit backend's tool system and chat controller.
Frontend Configuration: Define the tool's metadata and add its icon to the LumoKit frontend.
Thorough Testing: Ensure the tool works as expected end-to-end.
Let's break down each step:
Step 1: Backend Implementation & Registration (LumoKit
Backend)
LumoKit
Backend)The backend is where your tool's core functionality resides and where it's made available to the AI agent.
A. Create Your Tool Class
File Location:
Create a new Python file in the
src/tools/
directory (e.g.,src/tools/my_new_tool.py
).Alternatively, you can add your tool to an existing relevant file within
src/tools/
.
Define Input Schema (Pydantic):
If your tool requires specific input parameters, define a Pydantic
BaseModel
for its arguments. This ensures data validation.
# Example: src/tools/my_new_tool.py from pydantic import BaseModel, Field class MyNewToolInput(BaseModel): """Input schema for My New Tool.""" target_address: str = Field(..., description="The Solana address to query.") some_parameter: int = Field(default=10, description="An optional parameter with a default value.")
Implement the Tool Class:
Your tool class must inherit from
langchain.tools.BaseTool
.Define class variables:
name
: A unique string identifier for the tool (e.g.,"my_new_tool_identifier"
). This is crucial and will be used by the AI agent and for linking with the frontend.description
: A clear explanation of what the tool does, its inputs, and expected outputs. This description is vital for the LLM to understand when and how to use your tool.args_schema
: Link to your Pydantic input schema class.
Implement the
_arun
asynchronous method for the tool's main logic.Implement a
_run
synchronous method (often, this can just state that only async is supported if that's the case).
# Example: src/tools/my_new_tool.py (continued) from typing import ClassVar, Type from langchain.tools import BaseTool class MyNewTool(BaseTool): """ My New Tool processes data for a given Solana address and an optional parameter. It returns a summary string based on the inputs. """ name: ClassVar[str] = "my_new_tool_identifier" # Crucial identifier for the AI and frontend description: ClassVar[str] = ( "Use this tool to get a processed summary for a specific Solana address. " "Input should be the target_address (string) and optionally some_parameter (integer)." ) args_schema: ClassVar[Type[BaseModel]] = MyNewToolInput async def _arun(self, target_address: str, some_parameter: int = 10) -> str: """Execute the tool asynchronously.""" # Your tool's core logic here return f"Successfully processed {target_address} with parameter {some_parameter}." def _run(self, target_address: str, some_parameter: int = 10) -> str: """Synchronous version.""" return "This tool primarily supports asynchronous execution."
B. Register Your Tool in the Backend System
This involves making your tool recognizable by the LumoKit system.
Export from
src/tools/__init__.py
:Open
src/tools/__init__.py
.Import your new tool class.
Add your tool class name to the
__all__
list. This makes it easier to import tools from thetools
module.
# Example: src/tools/__init__.py # ... other imports from .my_new_tool import MyNewTool # Assuming your file is my_new_tool.py # Add to __all__ __all__ = [ # ... other tools "MyNewTool", # ... other common exports like get_tools_system_message ]
LLM Tool Descriptions: The backend README previously mentioned adding tool descriptions to
TOOL_DESCRIPTIONS
ininit.py
(or a similar central mapping). This dictionary helps the LLM understand available tools. Ensure your tool'sname
and its AI-facingdescription
are correctly registered here if this pattern is used in your project version. This is often vital for the AI agent's tool selection process.
Integrate into Chat Controller (
src/api/chat/controllers.py
): This is a critical step to make your tool available to the chat interface and the AI agent processing chat requests.Import your tool: Add an import statement for your new tool class at the top of
src/api/chat/controllers.py
alongside other tool imports.# Example: At the top of src/api/chat/controllers.py from tools import ( # ... other existing tool imports MyNewTool # Your new tool )
Instantiate your tool: Within the relevant function or method where other tools are initialized (often in the main chat request handler), create an instance of your tool.
# Example: Inside a function/method in src/api/chat/controllers.py # ... my_new_tool_instance = MyNewTool() # ... other tool instantiations
Add to
available_tools
dictionary: Add your instantiated tool to theavailable_tools
dictionary. The key for the dictionary entry must be the string identifier of your tool (i.e.,MyNewTool.name
, which is"my_new_tool_identifier"
in our example). This dictionary is used to dynamically provide tools to the AI agent based on user selections or requests.Python
# Example: Continuing inside the function/method in src/api/chat/controllers.py # Instantiate other tools as per existing code rugcheck_token_information_tool = RugcheckTokenInformationTool() fluxbeam_token_price_tool = FluxBeamTokenPriceTool() # ... and so on for all tools # Your new tool instance my_new_tool_instance = MyNewTool() # Ensure this is done if not above # Process requested additional tools (or however tools are gathered) available_tools = { "rugcheck_token_information_tool": rugcheck_token_information_tool, "fluxbeam_token_price_tool": fluxbeam_token_price_tool, # ... other existing tools mapped by their string identifiers "my_new_tool_identifier": my_new_tool_instance # Add your new tool here } # The rest of the logic that uses available_tools... # active_tools = [available_tools[tool_name] for tool_name in requested_tools if tool_name in available_tools]
Step 2: Frontend Configuration (lumokit-frontend
)
lumokit-frontend
)Once the backend logic is in place and registered, you need to make the tool accessible and configurable from the LumoKit frontend.
A. Define the Tool in data/tools.json
Locate the File:
Open the
data/tools.json
file in the root of yourlumokit-frontend
project.
Add a New Tool Entry:
Add a new JSON object to the array in
data/tools.json
for your tool.
// Example entry in data/tools.json { "icon_url": "/icons/my_new_tool_icon.svg", "default_status": false, "tool_identifier": "my_new_tool_identifier", // MUST MATCH backend tool 'name' and controller key "name": "My New Awesome Tool", "category": "Data Analysis", "description": "Fetches and processes data from a Solana address.", "read_more": "https://your-docs-link.com/my-new-tool" }
Key Fields Explained:
icon_url
: Path to the tool's icon (relative to/public
).default_status
: Boolean (true
if enabled by default,false
otherwise).tool_identifier
: String. Critical field. Must exactly match thename
class variable in your backend tool class (e.g.,"my_new_tool_identifier"
) AND the key used in theavailable_tools
dictionary insrc/api/chat/controllers.py
.name
: String. User-friendly display name in the UI.category
: String. Groups tools in "Tools & Settings".description
: String. Short (10-15 words) user-facing explanation.read_more
: String. Optional URL to detailed documentation.
B. Add the Tool's Icon
Create/Obtain Icon: SVG or PNG recommended.
Place Icon: In
/public/
or a subdirectory (e.g.,/public/icons/
) inlumokit-frontend
.Ensure
icon_url
indata/tools.json
points to it correctly.
Step 3: Testing Your New Tool
Thorough testing is essential.
Backend Tests: Write unit/integration tests for your tool's logic.
Restart Services: Rebuild and restart both the LumoKit backend and frontend development server to load all changes.
End-to-End Frontend UI Testing:
Open LumoKit in your browser.
Navigate to "Tools & Settings" and verify your tool appears correctly.
Enable your tool.
Use the chat interface with prompts designed to trigger your new tool. Check:
Correct tool selection by the AI.
Proper argument passing.
Successful execution in the backend (check logs).
Correct results/display in the frontend.
Iterate: Debug and refine as necessary. Pay close attention to logs and console outputs.
✨ Best Practices & Important Considerations
Consistent Naming: Use lowercase with underscores for the shared
tool_identifier
/name
.Clear Descriptions:
Backend
description
(in tool class): Explicit for the LLM (capabilities, inputs, use cases).Frontend
description
(intools.json
): Concise and user-friendly.
Robust Error Handling: Implement in your backend tool's
_arun
method.Performance: Be mindful of tool execution time. Limit default tools.
Security: Adhere to security best practices if handling sensitive data or actions.
Documentation: Use
read_more
for complex tools.
By following these updated and detailed steps, you can effectively extend LumoKit's capabilities by adding new, powerful tools tailored to your needs within the Solana ecosystem!
Last updated