Tool¶
Represents an individual tool with metadata and execution logic within the ToolRegistry ecosystem.
Overview¶
The Tool class serves as a fundamental abstraction for all tools in the ToolRegistry system. It encapsulates both the executable logic and the metadata necessary for proper tool discovery, parameter validation, and execution within LLM applications.
Key Features¶
- Metadata Management: Comprehensive tool description, parameters, and execution metadata
- Parameter Validation: Built-in parameter schema validation and type checking
- Execution Abstraction: Unified interface for both synchronous and asynchronous execution
- Namespace Support: Integration with namespace organization for tool grouping
- Callable Integration: Direct execution through callable interface
Architecture¶
The Tool class follows a data-transfer-object pattern with the following key components:
Core Attributes¶
- name: Unique identifier for the tool
- description: Human-readable description of tool functionality
- parameters: JSON schema defining expected parameters
- callable: The actual executable function or wrapper
- is_async: Flag indicating asynchronous execution capability
- namespace: Optional namespace for organization (stores the original namespace string after normalization)
- method_name: Optional original method/function name before namespace prefixing (preserved for unambiguous base name recovery)
Computed Properties¶
- qualified_name: Returns the fully-qualified tool name. If both
namespaceandmethod_nameare set, returns{namespace}-{method_name}; otherwise falls back to thenamefield.
Design Philosophy¶
- Immutability: Tool instances are designed to be immutable after creation
- Schema-Driven: Parameter validation based on JSON Schema standards
- Execution Flexibility: Support for both sync and async execution patterns
- Metadata Preservation: Complete preservation of tool metadata for LLM consumption
API Reference¶
toolregistry.Tool ¶
Bases: BaseModel
Base class representing an executable tool/function.
Provides core functionality for
- Function wrapping and metadata management
- Parameter validation using Pydantic
- Synchronous/asynchronous execution
- JSON schema generation
callable
class-attribute
instance-attribute
¶
The tool's callable, always a :class:BaseToolWrapper at runtime.
Typed as Callable for Pydantic compatibility (Pydantic cannot
generate a schema for BaseToolWrapper). Use call_sync() /
call_async() for sync/async transparent execution.
Excluded from serialization to prevent accidental exposure of implementation details.
description
class-attribute
instance-attribute
¶
Detailed description of the tool's functionality.
Should clearly explain what the tool does, its purpose, and any important usage considerations.
fn
property
¶
Return the underlying unwrapped function.
For native tools (registered via from_function), returns the
original Python function. For integration tools (MCP, OpenAPI,
LangChain), returns the wrapper itself.
is_async
property
¶
Whether the tool requires async execution.
Backward-compatible proxy to metadata.is_async.
metadata
class-attribute
instance-attribute
¶
Behavioral and classification metadata for this tool.
Contains execution hints (is_async, is_concurrency_safe,
timeout) and classification tags (tags, custom_tags).
method_name
class-attribute
instance-attribute
¶
The original method/function name before namespace prefixing.
Preserved so that the base name can be recovered without
ambiguity even when the name field contains a namespace
prefix joined by - (which normalize_tool_name would
otherwise convert to _).
name
class-attribute
instance-attribute
¶
The name of the tool.
Used as the primary identifier when calling the tool. Must be unique within a tool registry.
namespace
class-attribute
instance-attribute
¶
The namespace this tool belongs to.
Used to group tools logically and avoid name collisions.
When set, the tool's name is typically prefixed as
{namespace}-{method_name}. This field stores the
original namespace string (after normalization) so that
downstream code can reliably determine group membership
without parsing the name field.
parameters
class-attribute
instance-attribute
¶
Parameter schema defining the tool's expected inputs.
Follows JSON Schema format. Automatically generated from the wrapped function's type hints when using from_function().
parameters_model
class-attribute
instance-attribute
¶
parameters_model: Any | None = Field(default=None, description='Pydantic Model for tool parameters')
Pydantic model used for parameter validation.
Automatically generated from the wrapped function's type hints when using from_function(). Can be None for tools without parameter validation.
qualified_name
property
¶
Return the fully-qualified tool name.
If a namespace is set, returns {namespace}-{method_name}.
Otherwise falls back to the name field.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The qualified name of the tool. |
arun
async
¶
Execute tool asynchronously.
Delegates to callable.call_async() which handles sync/async
callable transparency. Exceptions propagate directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
dict[str, Any]
|
Input parameters for the tool. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The tool execution result. |
Raises:
| Type | Description |
|---|---|
Exception
|
Any exception raised during validation or execution. |
Note
Result size truncation (via max_result_size) is only applied
when tools are executed through
ToolRegistry.execute_tool_calls(). Direct calls return raw
results without truncation.
arun_raw
async
¶
Deprecated alias for arun().
.. deprecated:: 0.12.0
Use arun() instead. arun_raw will be removed in a
future version.
describe ¶
Deprecated: use :meth:get_schema instead.
from_function
classmethod
¶
from_function(func: Callable[..., Any], name: str | None = None, description: str | None = None, namespace: str | None = None, method_name: str | None = None, metadata: ToolMetadata | None = None) -> Tool
Factory method to create Tool from callable.
Automatically
- Extracts function metadata
- Generates parameter schema
- Handles async/sync detection
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Function to convert to tool. |
required |
name
|
str | None
|
Override tool name (defaults to function name). |
None
|
description
|
str | None
|
Override description (defaults to docstring). |
None
|
namespace
|
str | None
|
Namespace the tool belongs to. |
None
|
method_name
|
str | None
|
Original method name of the tool. |
None
|
metadata
|
ToolMetadata | None
|
Optional ToolMetadata; |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Tool |
Tool
|
Configured Tool instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For unnamed lambda functions. |
get_json_schema ¶
Deprecated: use :meth:get_schema instead.
get_schema ¶
get_schema(api_format: API_FORMATS = 'openai-chat', *, _think_augment: bool | None = None) -> dict[str, Any]
Generate schema representation of tool for a target API format.
All formats are produced via llm-rosetta converters, which also
apply schema sanitization (stripping unsupported JSON Schema
keywords like $ref, $schema, anyOf, etc.).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_format
|
API_FORMATS
|
Target API format. One of |
'openai-chat'
|
_think_augment
|
bool | None
|
Internal override for toolcall_reason injection.
When |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Provider-specific tool definition dict. |
model_post_init ¶
Inject toolcall_reason property into the tool's parameter schema.
Runs after every Tool (and subclass) construction, regardless
of whether the instance was created via from_function(), or
directly (MCP, OpenAPI, LangChain integrations).
The toolcall_reason field is only added when parameters
already contains a properties mapping.
run ¶
Execute tool synchronously.
Delegates to callable.call_sync() which handles sync/async
callable transparency. Exceptions propagate directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parameters
|
dict[str, Any]
|
Input parameters for the tool. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The tool execution result. |
Raises:
| Type | Description |
|---|---|
Exception
|
Any exception raised during validation or execution. |
Note
Result size truncation (via max_result_size) is only applied
when tools are executed through
ToolRegistry.execute_tool_calls(). Direct calls return raw
results without truncation.
run_raw ¶
Deprecated alias for run().
.. deprecated:: 0.12.0
Use run() instead. run_raw will be removed in a
future version.
update_namespace ¶
Updates the namespace of a tool.
This method checks if the tool's name already contains a namespace (indicated by the presence of a separator character).
OpenAI requires that function names match the pattern ^[a-zA-Z0-9_-]+$. Some other providers allow dot (.) as separator.
If it does and force is True, the existing namespace is replaced with the provided namespace.
If force is False and an existing namespace is present, no changes are made.
If the tool's name does not contain a namespace, the namespace is prepended as a prefix to the tool's name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
namespace
|
str
|
The new namespace to apply to the tool's name. |
required |
force
|
bool
|
If |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
None |
None
|
This method modifies the |
Example
tool = Tool(name="example_tool")
tool.update_namespace("new_namespace")
tool.name # 'new_namespace-example_tool'
tool = Tool(name="old_namespace.example_tool")
tool.update_namespace("new_namespace", force=False)
tool.name # 'old_namespace-example_tool'
tool = Tool(name="old_namespace.example_tool")
tool.update_namespace("new_namespace", force=True, sep=".")
tool.name # 'new_namespace.example_tool'
Usage Examples¶
Basic Tool Creation¶
from toolregistry import Tool
def calculate_area(length: float, width: float) -> float:
"""Calculate the area of a rectangle."""
return length * width
# Create a Tool instance
area_tool = Tool(
name="calculate_area",
description="Calculate the area of a rectangle",
parameters={
"type": "object",
"properties": {
"length": {"type": "number", "description": "Length of rectangle"},
"width": {"type": "number", "description": "Width of rectangle"}
},
"required": ["length", "width"]
},
callable=calculate_area,
is_async=False
)
Tool with Namespace¶
from toolregistry import Tool
# Create a tool with namespace and method_name fields
math_tool = Tool(
name="math_ops-multiply",
description="Multiply two numbers",
parameters={
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
},
callable=lambda a, b: a * b,
is_async=False,
namespace="math_ops",
method_name="multiply",
)
# Access the qualified name
print(math_tool.qualified_name) # Output: "math_ops-multiply"
print(math_tool.namespace) # Output: "math_ops"
print(math_tool.method_name) # Output: "multiply"
Tool from Function with Namespace¶
from toolregistry import Tool
def multiply(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
# Create a tool with namespace using from_function()
tool = Tool.from_function(multiply, namespace="math_ops")
print(tool.name) # Output: "math_ops-multiply"
print(tool.namespace) # Output: "math_ops"
print(tool.method_name) # Output: "multiply"
print(tool.qualified_name) # Output: "math_ops-multiply"
# You can also provide a custom method_name
tool2 = Tool.from_function(multiply, namespace="math_ops", method_name="mul")
print(tool2.name) # Output: "math_ops-mul"
print(tool2.method_name) # Output: "mul"
Updating Namespace¶
from toolregistry import Tool
# Create a tool without namespace
math_tool = Tool.from_function(lambda a, b: a * b, name="multiply")
# Update with namespace
math_tool.update_namespace("math_operations")
print(math_tool.name) # Output: "math_operations-multiply"
print(math_tool.namespace) # Output: "math_operations"
print(math_tool.method_name) # Output: "multiply"
print(math_tool.qualified_name) # Output: "math_operations-multiply"
Async Tool¶
import asyncio
from toolregistry import Tool
async def fetch_data(url: str) -> dict:
"""Fetch data from a URL asynchronously."""
# Async implementation
return {"url": url, "data": "sample"}
# Create async tool
async_tool = Tool(
name="fetch_data",
description="Fetch data from URL",
parameters={
"type": "object",
"properties": {
"url": {"type": "string", "description": "URL to fetch from"}
},
"required": ["url"]
},
callable=fetch_data,
is_async=True
)
Executing Tools¶
The Tool class provides sync and async execution:
run(parameters)— Execute synchronously. Raises exceptions on failure.arun(parameters)— Execute asynchronously. Raises exceptions on failure.
Both methods handle sync/async callable transparency automatically. A sync tool can be called via arun() (dispatched via asyncio.to_thread()), and an async tool can be called via run() (dispatched via asyncio.run()).
from toolregistry import Tool
def divide(a: float, b: float) -> float:
"""Divide a by b."""
return a / b
tool = Tool.from_function(divide)
# Sync execution
try:
result = tool.run({"a": 10, "b": 0})
except ZeroDivisionError:
print("Cannot divide by zero!")
# Async execution
result = await tool.arun({"a": 10, "b": 2}) # returns 5.0
run_raw() / arun_raw() are deprecated
These methods are now aliases for run() / arun() and emit
DeprecationWarning. Use run() / arun() directly.
Accessing the Underlying Function¶
Use the tool.fn property to get the original unwrapped function:
tool = Tool.from_function(my_func)
tool.fn # → my_func (the original function)
tool.callable # → _FunctionToolWrapper (the wrapper, for internal use)
Parameter Schema Format¶
The Tool class uses JSON Schema format for parameter validation:
{
"type": "object",
"properties": {
"param_name": {
"type": "string|number|boolean|array|object",
"description": "Parameter description",
"default": "default_value"
}
},
"required": ["param1", "param2"]
}
Integration with ToolRegistry¶
Tools are primarily used through the ToolRegistry:
from toolregistry import ToolRegistry, Tool
registry = ToolRegistry()
# Register tool with registry
registry.register(tool_instance)
# Execute tool through registry
result = registry.execute_tool("tool_name", param1="value1", param2="value2")
The Tool class provides the foundation for all tool operations within the ToolRegistry ecosystem, ensuring consistent behavior across different tool sources and execution environments.