π οΈ Tool Development Guide
Master the art of creating powerful DSPy tools for SuperOptiX agents
π― What Are SuperOptiX Tools?
SuperOptiX tools are DSPy tools that integrate seamlessly with the ReAct (Reasoning + Acting) module in agentic pipelines. Unlike traditional OpenAI function calling, DSPy tools are designed to work within the ReAct reasoning framework, enabling agents to:
-
Think step-by-step about complex problems
-
Choose appropriate tools based on reasoning
-
Execute tools with proper parameters
-
Integrate results back into the reasoning process
π ReAct vs Function Calling
Aspect | DSPy ReAct Tools | OpenAI Function Calling |
---|---|---|
Reasoning | Built-in step-by-step reasoning | External reasoning required |
Tool Selection | Agent decides when to use tools | Pre-defined function calls |
Integration | Seamless with DSPy pipelines | Requires custom integration |
Learning | Can be optimized with DSPy | Static function definitions |
πͺ Browse Available Tools
SuperOptiX comes with a rich marketplace of pre-built tools across multiple categories:
# Browse all available tools
super market browse tools
# Filter by category
super market browse tools --category Core
super market browse tools --category Development
super market browse tools --category Data
# Get detailed information about a specific tool
super market show calculator
# See usage examples
super market examples web_search
π Available Tool Categories
π§ Core Tools (6 tools)
Essential tools for basic agent functionality:
-
web_search - Search the web for information
-
calculator - Perform safe mathematical calculations
-
file_reader - Read and process text files safely
-
datetime - Get current time and format dates
-
text_analyzer - Analyze text for statistics and readability
-
json_processor - Parse JSON and extract specific fields
π» Development Tools (9 tools)
Tools for software development and DevOps:
-
code_formatter - Format code with syntax highlighting
-
git_analyzer - Analyze Git commit messages
-
api_tester - Validate and analyze API responses
-
database_query - Validate SQL queries for security
-
version_checker - Compare semantic versions
-
dependency_analyzer - Analyze package dependencies
-
code_reviewer - Perform automated code review
-
test_coverage - Analyze test coverage reports
-
docker_helper - Validate Dockerfiles
π Data Tools (1 tool)
Data processing and analysis:
- data_processor - Process and analyze CSV data
π¨ Create Custom DSPy Tools
1. Basic Tool Structure
All SuperOptiX tools follow a consistent pattern:
"""
SuperOptiX Custom Tool
=====================
Description of what this tool does.
"""
class MyCustomTool:
"""Brief description of the tool's purpose."""
def __init__(self, config_param: str = "default"):
"""Initialize tool with configuration."""
self.config_param = config_param
def execute_function(self, input_param: str) -> str:
"""Main tool execution method.
Args:
input_param: Description of the input parameter
Returns:
Formatted string result with emojis and clear structure
"""
try:
# Tool logic here
result = f"β
Tool executed successfully: {input_param}"
# Return formatted result
return f"""π οΈ Custom Tool Result:
{'='*50}
{result}
Configuration: {self.config_param}
"""
except Exception as e:
return f"β Tool execution error: {str(e)}"
2. Tool Categories and Organization
In your SuperOptiX project, custom tools are organized in the tools/
directory. This follows the standard SuperOptiX project structure:
your-superoptix-project/
βββ agents/ # Agent playbooks and pipelines
βββ guardrails/ # Safety and validation rules
βββ memory/ # Memory modules for agents
βββ protocols/ # Communication protocols
βββ teams/ # Multi-agent team configurations
βββ evals/ # Evaluation scenarios and test cases
βββ knowledge/ # Knowledge bases and data sources
βββ optimizers/ # Optimization strategies
βββ servers/ # Server and API integration code
βββ tools/ # π§ Custom tools and utilities for your agents
βββ ...
π Tools Directory Structure
Organize your custom tools by domain or functionality:
tools/
βββ __init__.py # Tool registry and imports
βββ core/ # Essential project tools
β βββ __init__.py
β βββ data_processor.py
β βββ api_client.py
β βββ file_handler.py
βββ finance/ # Financial domain tools
β βββ __init__.py
β βββ investment_analyzer.py
β βββ budget_planner.py
β βββ tax_calculator.py
βββ healthcare/ # Healthcare domain tools
β βββ __init__.py
β βββ patient_analyzer.py
β βββ medication_checker.py
β βββ health_metrics.py
βββ development/ # Software development tools
β βββ __init__.py
β βββ code_reviewer.py
β βββ dependency_checker.py
β βββ deployment_helper.py
βββ domain_specific/ # Your specific domain tools
βββ __init__.py
βββ industry_analyzer.py
βββ custom_calculator.py
3. Creating a New Tool Category
To create a new tool category in your SuperOptiX project:
- Create the category directory and files:
# Create the category directory
mkdir -p tools/finance
# Create the main tool file
touch tools/finance/__init__.py
touch tools/finance/investment_analyzer.py
- Implement your tools:
# tools/finance/investment_analyzer.py
"""
Investment Analysis Tools
=========================
Tools for analyzing investment opportunities and financial metrics.
"""
class InvestmentAnalyzer:
"""Analyze investment opportunities and calculate financial metrics."""
def __init__(self):
"""Initialize the investment analyzer."""
pass
def calculate_roi(self, initial_investment: float, final_value: float, years: int) -> str:
"""Calculate Return on Investment."""
try:
roi = ((final_value - initial_investment) / initial_investment) * 100
annual_roi = roi / years
return f"""π ROI Analysis:
{'='*50}
Initial Investment: ${initial_investment:,.2f}
Final Value: ${final_value:,.2f}
Time Period: {years} years
Total ROI: {roi:.2f}%
Annual ROI: {annual_roi:.2f}%
"""
except Exception as e:
return f"β ROI calculation error: {str(e)}"
- Register tools in the category's
__init__.py
:
# tools/finance/__init__.py
"""
Finance Tools Module
===================
Financial analysis and calculation tools for SuperOptiX agents.
"""
from .investment_analyzer import InvestmentAnalyzer
# Export tools for easy importing
__all__ = ['InvestmentAnalyzer']
# Tool registry for this category
FINANCE_TOOLS = {
"investment_analyzer": {
"class": InvestmentAnalyzer,
"description": "Analyze investment opportunities and calculate ROI",
"tags": ["finance", "investment", "roi", "analysis"]
}
}
- Register in the main tools registry:
# tools/__init__.py
"""
Project Tools Registry
=====================
Central registry for all custom tools in your SuperOptiX project.
"""
from .finance import FINANCE_TOOLS, InvestmentAnalyzer
# Combine all tool registries
PROJECT_TOOLS = {
**FINANCE_TOOLS,
# Add other categories here
# **HEALTHCARE_TOOLS,
# **DEVELOPMENT_TOOLS,
}
# Export all tools
__all__ = [
'InvestmentAnalyzer',
'PROJECT_TOOLS',
]
4. Tool Integration with DSPy
Tools are integrated into DSPy pipelines through the ToolsMixin
. In your SuperOptiX project:
# agents/financial_advisor/pipelines/financial_advisor_pipeline.py
from superoptix.core.pipeline_utils import ToolsMixin
class FinancialAdvisorPipeline(ToolsMixin):
def setup_tools(self, spec_data=None):
"""Setup tools including custom project tools."""
super().setup_tools(spec_data)
# Import custom tools from your project
from tools.finance import InvestmentAnalyzer
# Create tool instances
investment_tool = InvestmentAnalyzer()
# Convert to DSPy Tool and add to pipeline
from dspy.adapters import Tool
self.tools.append(Tool(investment_tool.calculate_roi, name="calculate_roi"))
print(f"β
Added {len(self.tools)} tools to FinancialAdvisorPipeline")
Alternative: Using Tool Registry
You can also use the project's tool registry for automatic tool discovery:
# agents/financial_advisor/pipelines/financial_advisor_pipeline.py
from superoptix.core.pipeline_utils import ToolsMixin
from tools import PROJECT_TOOLS
class FinancialAdvisorPipeline(ToolsMixin):
def setup_tools(self, spec_data=None):
"""Setup tools using project registry."""
super().setup_tools(spec_data)
# Automatically add tools from registry
for tool_name, tool_config in PROJECT_TOOLS.items():
tool_class = tool_config['class']
tool_instance = tool_class()
# Add all methods from the tool class
for method_name in dir(tool_instance):
method = getattr(tool_instance, method_name)
if callable(method) and not method_name.startswith('_'):
from dspy.adapters import Tool
self.tools.append(Tool(method, name=f"{tool_name}_{method_name}"))
print(f"β
Added {len(self.tools)} tools from project registry")
5. Tool Configuration in SuperSpec DSL
Define tools in your agent playbook. You can reference both builtin tools and your custom project tools:
# agents/financial_advisor/financial_advisor_playbook.yaml
spec:
tools:
enabled: true
builtin_tools:
- calculator
- web_search
- file_reader
custom_tools:
- name: "calculate_roi"
description: "Calculate Return on Investment for financial analysis"
function_name: "calculate_roi"
parameters:
- name: "initial_investment"
type: "float"
required: true
description: "Initial investment amount"
- name: "final_value"
type: "float"
required: true
description: "Final investment value"
- name: "years"
type: "int"
required: true
description: "Investment time period in years"
implementation: |
def calculate_roi(initial_investment: float, final_value: float, years: int) -> str:
try:
roi = ((final_value - initial_investment) / initial_investment) * 100
annual_roi = roi / years
return f"π ROI: {roi:.2f}% (Annual: {annual_roi:.2f}%)"
except Exception as e:
return f"β ROI calculation error: {str(e)}"
Project Tool References
You can also reference tools from your project's tools/
directory:
# agents/health_advisor/health_advisor_playbook.yaml
spec:
tools:
enabled: true
builtin_tools:
- calculator
- text_analyzer
project_tools:
- category: "healthcare"
tools:
- "patient_analyzer"
- "medication_checker"
- "health_metrics"
custom_tools:
- name: "bmi_calculator"
description: "Calculate Body Mass Index"
function_name: "calculate_bmi"
parameters:
- name: "weight_kg"
type: "float"
required: true
description: "Weight in kilograms"
- name: "height_m"
type: "float"
required: true
description: "Height in meters"
implementation: |
def calculate_bmi(weight_kg: float, height_m: float) -> str:
try:
bmi = weight_kg / (height_m ** 2)
category = "Underweight" if bmi < 18.5 else "Normal" if bmi < 25 else "Overweight" if bmi < 30 else "Obese"
return f"π₯ BMI: {bmi:.1f} ({category})"
except Exception as e:
return f"β BMI calculation error: {str(e)}"
π§ Tool Development Best Practices
1. Error Handling and Safety
def safe_tool_execution(self, input_data: str) -> str:
"""Execute tool with comprehensive error handling."""
try:
# Validate input
if not input_data or not input_data.strip():
return "β Error: Input data is required"
# Perform operation
result = self._process_data(input_data)
# Validate output
if not result:
return "β Error: No result generated"
return f"β
Success: {result}"
except ValueError as e:
return f"β Validation error: {str(e)}"
except Exception as e:
return f"β Unexpected error: {str(e)}"
2. Input Validation
def validate_input(self, **kwargs) -> bool:
"""Validate tool input parameters."""
required_params = ['data', 'format']
for param in required_params:
if param not in kwargs or kwargs[param] is None:
raise ValueError(f"Required parameter '{param}' is missing")
# Type validation
if not isinstance(kwargs['data'], str):
raise ValueError("Data must be a string")
return True
3. Output Formatting
def format_output(self, result: str, metadata: dict = None) -> str:
"""Format tool output consistently."""
output = f"""π οΈ Tool Result:
{'='*50}
{result}
"""
if metadata:
output += f"\nMetadata:\n"
for key, value in metadata.items():
output += f"- {key}: {value}\n"
return output
4. Performance Considerations
def optimized_tool(self, large_data: str) -> str:
"""Tool with performance optimizations."""
# Process in chunks for large data
chunk_size = 1000
chunks = [large_data[i:i+chunk_size] for i in range(0, len(large_data), chunk_size)]
results = []
for chunk in chunks:
result = self._process_chunk(chunk)
results.append(result)
return "\n".join(results)
π§ͺ Testing Your Tools
1. Unit Testing
# tests/tools/test_finance_tools.py
import pytest
from tools.finance import InvestmentAnalyzer
def test_investment_analyzer():
tool = InvestmentAnalyzer()
# Test normal operation
result = tool.calculate_roi(1000, 1500, 2)
assert "ROI: 50.00%" in result
assert "Annual: 25.00%" in result
assert "π" in result
# Test error handling
result = tool.calculate_roi(0, 1500, 2)
assert "β" in result
assert "error" in result.lower()
def test_invalid_inputs():
tool = InvestmentAnalyzer()
# Test with negative values
result = tool.calculate_roi(-1000, 1500, 2)
assert "β" in result
# Test with zero years
result = tool.calculate_roi(1000, 1500, 0)
assert "β" in result
2. Integration Testing
# tests/integration/test_tool_integration.py
def test_tool_in_pipeline():
"""Test that custom tools integrate properly with DSPy pipelines."""
from superoptix.core.pipeline_utils import ToolsMixin
from tools.finance import InvestmentAnalyzer
class TestPipeline(ToolsMixin):
def __init__(self):
super().__init__()
self.setup_tools()
# Add custom tool
investment_tool = InvestmentAnalyzer()
from dspy.adapters import Tool
self.tools.append(Tool(investment_tool.calculate_roi, name="calculate_roi"))
pipeline = TestPipeline()
# Verify tools are loaded
assert len(pipeline.tools) > 0
# Verify custom tool is available
tool_names = [tool.name for tool in pipeline.tools]
assert "calculate_roi" in tool_names
def test_tool_execution():
"""Test tool execution within a pipeline context."""
from superoptix.core.pipeline_utils import ToolsMixin
from tools.finance import InvestmentAnalyzer
import dspy
class TestPipeline(ToolsMixin):
def __init__(self):
super().__init__()
self.setup_tools()
# Add custom tool
investment_tool = InvestmentAnalyzer()
from dspy.adapters import Tool
self.tools.append(Tool(investment_tool.calculate_roi, name="calculate_roi"))
pipeline = TestPipeline()
# Test tool execution
for tool in pipeline.tools:
if tool.name == "calculate_roi":
result = tool(1000, 1500, 2)
assert "ROI" in result
assert "50.00%" in result
break
π Advanced Tool Features
1. Async Tools
import asyncio
class AsyncTool:
"""Async tool for I/O operations."""
async def fetch_data(self, url: str) -> str:
"""Fetch data asynchronously."""
try:
import aiohttp
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.text()
return f"β
Fetched {len(data)} characters from {url}"
except Exception as e:
return f"β Fetch error: {str(e)}"
2. Tool with Memory
class MemoryAwareTool:
"""Tool that remembers previous operations."""
def __init__(self):
self.history = []
def process_with_memory(self, data: str) -> str:
"""Process data with memory of previous operations."""
self.history.append(data)
# Use history for context
context = f"Previous operations: {len(self.history)}"
result = f"Processed: {data} (with context: {context})"
return f"""π§ Memory-Aware Tool:
{'='*50}
{result}
History: {len(self.history)} operations
"""
3. Tool with Configuration
class ConfigurableTool:
"""Tool with runtime configuration."""
def __init__(self, config: dict = None):
self.config = config or {}
self.max_retries = self.config.get('max_retries', 3)
self.timeout = self.config.get('timeout', 30)
def execute_with_config(self, data: str) -> str:
"""Execute with configuration parameters."""
result = f"Processed with {self.max_retries} retries, {self.timeout}s timeout"
return f"""βοΈ Configurable Tool:
{'='*50}
{result}
Config: {self.config}
"""
π Tool Examples by Domain
Finance Tools
class InvestmentAnalyzer:
"""Analyze investment opportunities."""
def analyze_roi(self, initial_investment: float, final_value: float, years: int) -> str:
"""Calculate Return on Investment."""
try:
roi = ((final_value - initial_investment) / initial_investment) * 100
annual_roi = roi / years
return f"""π ROI Analysis:
{'='*50}
Initial Investment: ${initial_investment:,.2f}
Final Value: ${final_value:,.2f}
Time Period: {years} years
Total ROI: {roi:.2f}%
Annual ROI: {annual_roi:.2f}%
"""
except Exception as e:
return f"β ROI calculation error: {str(e)}"
Healthcare Tools
class HealthAnalyzer:
"""Analyze health metrics."""
def calculate_bmi(self, weight_kg: float, height_m: float) -> str:
"""Calculate Body Mass Index."""
try:
bmi = weight_kg / (height_m ** 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 25:
category = "Normal weight"
elif bmi < 30:
category = "Overweight"
else:
category = "Obese"
return f"""π₯ BMI Analysis:
{'='*50}
Weight: {weight_kg} kg
Height: {height_m} m
BMI: {bmi:.1f}
Category: {category}
"""
except Exception as e:
return f"β BMI calculation error: {str(e)}"
π― Next Steps
- Browse existing tools:
super market browse tools
- Study tool patterns: Examine tools in
superoptix/tools/categories/
- Create your first tool: Follow the basic structure above
- Test thoroughly: Use unit tests and integration tests
- Share your tools: Contribute tools to the SuperOptiX ecosystem
π Related Documentation
- Agent Development Guide - Learn how tools fit into the agent development process
- SuperSpec DSL Guide - Configure tools in agent playbooks
- CLI Reference - Command-line tool management
- API Reference - Programmatic tool access
Ready to build powerful tools that enhance your SuperOptiX agents? Start with the marketplace, then create your own custom tools! π