Skip to content

AlacerMortis/Tool-Registration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tool Registration

A modular tool registration system that separates core tool metadata handling from specific tool format implementations. This system provides decorator-based tool registration with automatic metadata extraction, tool discovery, and export capabilities for integration with external systems like Ollama.

Features

  • Tool Registration: Decorate functions with @tool to register them with metadata
  • Export Control: Use @expose to mark tools for external consumption
  • Metadata Management: Automatic parameter analysis and optional parameter detection
  • Tool Invocation: Execute registered tools by name with parameter validation
  • Ollama Integration: Export tools in Ollama-compatible format
  • HTTP Server: RESTful API for tool discovery and execution
  • Module Scanning: Automatic discovery of tools within modules using frame inspection
  • Caching: Built-in caching for tool metadata and Ollama tool exports

Installation

From Source

# Clone the repository
git clone https://github.com/yourusername/tool-registration.git
cd tool-registration

# Install in development mode
pip install -e .

# Or install normally
pip install .

As a Dependency

Add to your requirements.txt:

tool-registration>=0.1.0

Or install directly:

pip install tool-registration

Quick Start

Basic Tool Definition

from tool_registration import tool, expose

@expose
@tool(
    name="hello_world",
    description="A simple greeting tool",
    parameters={
        "name": {
            "type": "string",
            "description": "Name to greet",
            "default": "World"
        }
    },
    version="1.0.0"
)
def hello_world(name: str = "World") -> str:
    """Return a greeting message."""
    return f"Hello, {name}!"

Using the Tool Registry

from tool_registration import get_registered_tool_names, invoke_tool

# Get all registered tools
tool_names = get_registered_tool_names()
print(f"Available tools: {tool_names}")

# Invoke a tool
result = invoke_tool("hello_world", name="Alice")
print(result)  # Output: Hello, Alice!

Ollama Integration

from tool_registration import get_tools_for_ollama, get_tool_for_ollama

# Get all tools in Ollama format
ollama_tools = get_tools_for_ollama()
print(ollama_tools)

# Get a specific tool in Ollama format
specific_tool = get_tool_for_ollama("hello_world")
print(specific_tool)

HTTP Server

from tool_registration import create_server

# Create and start the HTTP server
server = create_server(host="localhost", port=5002)
server.run(debug=True)

# Available endpoints:
# GET /tools - List all exportable tools
# GET /ollama/tools - List tools in Ollama format
# GET /health - Health check
# POST /tool/<tool_name> - Execute a tool
# POST /ollama/tool/<tool_name> - Execute a tool via Ollama registry

Project Structure

tool-registration/
├── src/                         # Source code
│   └── tool_registration/       # Main package
│       ├── __init__.py          # Package initialization and exports
│       ├── ToolRegistry.py      # Core tool registration system
│       ├── ToolExportServer.py  # HTTP server for tool export
│       ├── OllamaTools.py       # Ollama integration
│       └── utils/               # Utility modules
│           ├── __init__.py
│           └── LoggerUtils.py   # Logging configuration
├── examples/                    # Example implementations
│   ├── ExampleTools.py          # Sample tool definitions
│   ├── ExampleTools2.py         # Additional examples
│   └── ExampleUsage.py          # Usage demonstration
├── tests/                       # Test suite
├── pyproject.toml               # Build configuration
├── setup.py                     # Alternative setup script
└── README.md                    # This file

API Reference

Core Functions

Tool Registration

  • @tool(name, description, parameters, version): Decorator to register a tool
  • @expose: Decorator to mark a tool as exportable
  • register_tools_from_module(module_name): Register tools from a specific module
  • scan_and_register_tools(): Scan and register tools from current context

Tool Discovery and Metadata

  • get_registered_tool_names(): Get list of all registered tool names
  • get_tool_count(): Get total number of registered tools
  • get_tool_metadata(tool_name): Get metadata for a specific tool
  • get_all_tool_metadata(): Get metadata for all registered tools
  • get_exportable_tool_names(): Get list of exportable tool names
  • get_exportable_tool_count(): Get total number of exportable tools
  • get_exportable_tool_metadata(tool_name): Get metadata for a specific exportable tool
  • get_all_exportable_tool_metadata(): Get metadata for all exportable tools

Tool Execution

  • invoke_tool(tool_name, **kwargs): Execute a tool by name
  • invoke_tool_from_registry(tool_name, **kwargs): Execute a tool via Ollama registry

Ollama Integration

  • get_tools_for_ollama(exportable_only=False): Get tools in Ollama format
  • get_tool_for_ollama(tool_name): Get a specific tool in Ollama format
  • get_ollama_tool_count(): Get count of registered Ollama tools
  • get_registered_ollama_tool_names(): Get list of registered Ollama tool names
  • clear_ollama_tools(): Clear the Ollama tools registry

HTTP Server

  • ToolExportServer(host, port): Create an HTTP server instance
  • create_server(host, port): Factory function to create a server
  • API_VERSION: Current API version
  • DEFAULT_HOST: Default server host
  • DEFAULT_PORT: Default server port

Registry Management

  • clear_tool_registry(): Clear the entire tool registry
  • get_registry_timestamp(): Get timestamp of last registry scan

Tool Parameters

The parameters argument in the @tool decorator should be a dictionary with the following structure:

parameters={
    "param_name": {
        "type": "string|number|boolean|array|object",
        "description": "Parameter description",
        "default": "default_value",  # Optional
        "enum": ["value1", "value2"],  # Optional, for enum types
        "optional": True  # Auto-detected from function signature
    }
}

Examples

The examples/ directory contains complete working examples demonstrating how to use the tool registration system:

  • ExampleTools.py - Sample tools with various parameter types and decorators
  • ExampleTools2.py - Additional tools showing different use cases
  • ExampleUsage.py - Complete demonstration script showing external project integration

Running the Examples

# Run the complete demonstration
python examples/ExampleUsage.py

# Or import and use individual example modules
python -c "from examples import ExampleTools; print('Tools loaded successfully')"

Here are complete working examples of how to use the tool registration system:

Basic Tool Definition

from tool_registration import tool, expose

# Define a simple tool
@expose
@tool(
    name="hello_world",
    description="A simple greeting tool",
    parameters={
        "name": {
            "type": "string",
            "description": "Name to greet",
            "default": "World"
        }
    },
    version="1.0.0"
)
def hello_world(name: str = "World") -> str:
    """Return a greeting message."""
    return f"Hello, {name}!"

# Define a tool with multiple parameters
@expose
@tool(
    name="calculate",
    description="Perform basic arithmetic operations",
    parameters={
        "operation": {
            "type": "string",
            "description": "Arithmetic operation (add, subtract, multiply, divide)",
            "enum": ["add", "subtract", "multiply", "divide"]
        },
        "a": {
            "type": "number",
            "description": "First number"
        },
        "b": {
            "type": "number",
            "description": "Second number"
        }
    },
    version="1.0.0"
)
def calculate(operation: str, a: float, b: float) -> float:
    """Perform arithmetic operation on two numbers."""
    if operation == "add":
        return a + b
    elif operation == "subtract":
        return a - b
    elif operation == "multiply":
        return a * b
    elif operation == "divide":
        if b == 0:
            raise ValueError("Cannot divide by zero")
        return a / b
    else:
        raise ValueError(f"Unknown operation: {operation}")

Using the Tool Registry

from tool_registration import get_registered_tool_names, invoke_tool, register_tools_from_module

# Register tools from a module (assuming the tools are defined in a module called 'my_tools')
register_tools_from_module('my_tools')

# Get all registered tools
tool_names = get_registered_tool_names()
print(f"Available tools: {tool_names}")

# Invoke a tool
result = invoke_tool("hello_world", name="Alice")
print(result)  # Output: Hello, Alice!

# Invoke with default parameter
result = invoke_tool("hello_world")
print(result)  # Output: Hello, World!

# Invoke the calculate tool
result = invoke_tool("calculate", operation="add", a=10, b=5)
print(result)  # Output: 15.0

Working with Tool Metadata

from tool_registration import (
    get_tool_metadata, 
    get_all_tool_metadata,
    get_exportable_tool_names,
    get_exportable_tool_count
)

# Get metadata for a specific tool
metadata = get_tool_metadata("hello_world")
print(f"Tool metadata: {metadata}")

# Get all tool metadata
all_metadata = get_all_tool_metadata()
print(f"Total tools: {len(all_metadata)}")

# Get exportable tools (those decorated with @expose)
exportable_tools = get_exportable_tool_names()
print(f"Exportable tools: {exportable_tools}")

# Get count of exportable tools
exportable_count = get_exportable_tool_count()
print(f"Exportable tool count: {exportable_count}")

Limitations and Known Issues

Tool Discovery Limitations

  • Frame Inspection: The automatic tool discovery relies on Python frame inspection, which can be unreliable in certain environments (e.g., some IDEs, debuggers, or complex import scenarios)
  • Module Scanning: Tools must be defined in modules that can be imported and scanned. Dynamic or runtime-generated tools may not be discovered automatically
  • Tool Name Constraints: Tool names must exactly match the function name they decorate - no aliasing is supported
  • Cache Expiration: Tool registry cache expires after 24 hours, which may cause performance issues in long-running applications

Security and Authentication

  • No Input Sanitization: Limited input validation beyond basic type checking
  • No Rate Limiting: The HTTP server doesn't implement rate limiting or request throttling

Technical Limitations

  • Global State: The system uses global variables for tool storage, which can cause issues in multi-threaded environments
  • No Persistence: Tool metadata is not persisted between application restarts
  • Limited Error Handling: Some error conditions may not be handled gracefully
  • No Tool Versioning: While tools can specify a version, there's no version management or compatibility checking

Ollama Integration Limitations

  • Format Constraints: Ollama tool export is limited to the specific format expected by Ollama
  • Parameter Type Mapping: Some complex parameter types may not map perfectly to Ollama's expected format
  • No Dynamic Updates: Ollama tools cache may not reflect real-time changes to the tool registry

Development and Maintenance

  • TODO Items: Several features are marked as TODO and not yet implemented (authentication, configuration)
  • Hacky Implementation: Some module scanning logic is marked as "too hacky" and needs refactoring
  • Limited Documentation: Some internal APIs lack comprehensive documentation

Development

Running Tests

# Install test dependencies
pip install -e ".[test]"

# Run tests
pytest

# Run with coverage
pytest --cov=src

Building the Package

# Build source distribution
python setup.py sdist

# Build wheel
python setup.py bdist_wheel

# Or use modern tools
pip install build
python -m build

Contributing

When contributing to this project, please be aware of the current limitations and consider:

  • Implementing proper authentication for the HTTP server
  • Adding comprehensive error handling
  • Improving the module scanning mechanism
  • Adding persistence for tool metadata
  • Implementing proper configuration management

About

A commons library for tool registration and exposure

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages