parent
cd5c74b6c7
commit
790378cc53
@ -0,0 +1,204 @@
|
|||||||
|
# ToolStorage
|
||||||
|
|
||||||
|
|
||||||
|
The `ToolStorage` module provides a structured and efficient way to manage and utilize various tool functions. It is designed to store tool functions, manage settings, and ensure smooth registration and retrieval of tools. This module is particularly useful in applications that require dynamic management of a collection of functions, such as plugin systems, modular software, or any application where functions need to be registered and called dynamically.
|
||||||
|
|
||||||
|
## Class: ToolStorage
|
||||||
|
|
||||||
|
The `ToolStorage` class is the core component of the module. It provides functionalities to add, retrieve, and list tool functions as well as manage settings.
|
||||||
|
|
||||||
|
### Attributes
|
||||||
|
|
||||||
|
| Attribute | Type | Description |
|
||||||
|
|------------|--------------------|-----------------------------------------------------------------------|
|
||||||
|
| `verbose` | `bool` | A flag to enable verbose logging. |
|
||||||
|
| `tools` | `List[Callable]` | A list of tool functions. |
|
||||||
|
| `_tools` | `Dict[str, Callable]` | A dictionary that stores the tools, where the key is the tool name and the value is the tool function. |
|
||||||
|
| `_settings`| `Dict[str, Any]` | A dictionary that stores the settings, where the key is the setting name and the value is the setting value. |
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
#### `__init__`
|
||||||
|
|
||||||
|
Initializes the `ToolStorage` instance.
|
||||||
|
|
||||||
|
|
||||||
|
| Parameter | Type | Default | Description |
|
||||||
|
|------------|-------------------|---------|------------------------------------------------------------|
|
||||||
|
| `verbose` | `bool` | `None` | A flag to enable verbose logging. |
|
||||||
|
| `tools` | `List[Callable]` | `None` | A list of tool functions to initialize the storage with. |
|
||||||
|
| `*args` | `tuple` | `None` | Additional positional arguments. |
|
||||||
|
| `**kwargs` | `dict` | `None` | Additional keyword arguments. |
|
||||||
|
|
||||||
|
#### `add_tool`
|
||||||
|
|
||||||
|
Adds a tool to the storage.
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
|-----------|----------|------------------------------|
|
||||||
|
| `func` | `Callable` | The tool function to be added. |
|
||||||
|
|
||||||
|
**Raises:**
|
||||||
|
- `ValueError`: If a tool with the same name already exists.
|
||||||
|
|
||||||
|
#### `get_tool`
|
||||||
|
|
||||||
|
Retrieves a tool by its name.
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
|-----------|--------|-------------------------------|
|
||||||
|
| `name` | `str` | The name of the tool to retrieve. |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- `Callable`: The tool function.
|
||||||
|
|
||||||
|
**Raises:**
|
||||||
|
- `ValueError`: If no tool with the given name is found.
|
||||||
|
|
||||||
|
#### `set_setting`
|
||||||
|
|
||||||
|
Sets a setting in the storage.
|
||||||
|
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
|-----------|--------|--------------------------|
|
||||||
|
| `key` | `str` | The key for the setting. |
|
||||||
|
| `value` | `Any` | The value for the setting. |
|
||||||
|
|
||||||
|
#### `get_setting`
|
||||||
|
|
||||||
|
Gets a setting from the storage.
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
|-----------|--------|--------------------------|
|
||||||
|
| `key` | `str` | The key for the setting. |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- `Any`: The value of the setting.
|
||||||
|
|
||||||
|
**Raises:**
|
||||||
|
- `KeyError`: If the setting is not found.
|
||||||
|
|
||||||
|
#### `list_tools`
|
||||||
|
|
||||||
|
Lists all registered tools.
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- `List[str]`: A list of tool names.
|
||||||
|
|
||||||
|
## Decorator: tool_registry
|
||||||
|
|
||||||
|
The `tool_registry` decorator registers a function as a tool in the storage.
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
|-----------|----------------|----------------------------------|
|
||||||
|
| `storage` | `ToolStorage` | The storage instance to register the tool in. |
|
||||||
|
|
||||||
|
**Returns:**
|
||||||
|
- `Callable`: The decorator function.
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
|
||||||
|
### Full Example
|
||||||
|
```python
|
||||||
|
from swarms import ToolStorage, tool_registry
|
||||||
|
|
||||||
|
storage = ToolStorage()
|
||||||
|
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
@tool_registry(storage)
|
||||||
|
def example_tool(x: int, y: int) -> int:
|
||||||
|
"""
|
||||||
|
Example tool function that adds two numbers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
x (int): The first number.
|
||||||
|
y (int): The second number.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: The sum of the two numbers.
|
||||||
|
"""
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
|
||||||
|
# Query all the tools and get the example tool
|
||||||
|
print(storage.list_tools()) # Should print ['example_tool']
|
||||||
|
# print(storage.get_tool('example_tool')) # Should print <function example_tool at 0x...>
|
||||||
|
|
||||||
|
# Find the tool by names and call it
|
||||||
|
print(storage.get_tool("example_tool")) # Should print 5
|
||||||
|
|
||||||
|
|
||||||
|
# Test the storage and querying
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(storage.list_tools()) # Should print ['example_tool']
|
||||||
|
print(storage.get_tool("example_tool")) # Should print 5
|
||||||
|
storage.set_setting("example_setting", 42)
|
||||||
|
print(storage.get_setting("example_setting")) # Should print 42
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
#### Example 1: Initializing ToolStorage and Adding a Tool
|
||||||
|
|
||||||
|
```python
|
||||||
|
from swarms.tools.tool_registry import ToolStorage, tool_registry
|
||||||
|
|
||||||
|
# Initialize ToolStorage
|
||||||
|
storage = ToolStorage()
|
||||||
|
|
||||||
|
# Define a tool function
|
||||||
|
@tool_registry(storage)
|
||||||
|
def add_numbers(x: int, y: int) -> int:
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
# List tools
|
||||||
|
print(storage.list_tools()) # Output: ['add_numbers']
|
||||||
|
|
||||||
|
# Retrieve and use the tool
|
||||||
|
add_tool = storage.get_tool('add_numbers')
|
||||||
|
print(add_tool(5, 3)) # Output: 8
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Usage
|
||||||
|
|
||||||
|
#### Example 2: Managing Settings
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Set a setting
|
||||||
|
storage.set_setting('max_retries', 5)
|
||||||
|
|
||||||
|
# Get a setting
|
||||||
|
max_retries = storage.get_setting('max_retries')
|
||||||
|
print(max_retries) # Output: 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
#### Example 3: Handling Errors in Tool Retrieval
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
non_existent_tool = storage.get_tool('non_existent')
|
||||||
|
except ValueError as e:
|
||||||
|
print(e) # Output: No tool found with name: non_existent
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example 4: Handling Duplicate Tool Addition
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
@tool_registry(storage)
|
||||||
|
def add_numbers(x: int, y: int) -> int:
|
||||||
|
return x + y
|
||||||
|
except ValueError as e:
|
||||||
|
print(e) # Output: Tool with name add_numbers already exists.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The `ToolStorage` module provides a robust solution for managing tool functions and settings. Its design allows for easy registration, retrieval, and management of tools, making it a valuable asset in various applications requiring dynamic function handling. The inclusion of detailed logging ensures that the operations are transparent and any issues can be quickly identified and resolved.
|
@ -0,0 +1,35 @@
|
|||||||
|
from swarms.tools.tool_registry import ToolStorage, tool_registry
|
||||||
|
|
||||||
|
storage = ToolStorage()
|
||||||
|
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
@tool_registry(storage)
|
||||||
|
def example_tool(x: int, y: int) -> int:
|
||||||
|
"""
|
||||||
|
Example tool function that adds two numbers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
x (int): The first number.
|
||||||
|
y (int): The second number.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: The sum of the two numbers.
|
||||||
|
"""
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
|
||||||
|
# Query all the tools and get the example tool
|
||||||
|
print(storage.list_tools()) # Should print ['example_tool']
|
||||||
|
# print(storage.get_tool('example_tool')) # Should print <function example_tool at 0x...>
|
||||||
|
|
||||||
|
# Find the tool by names and call it
|
||||||
|
print(storage.get_tool("example_tool")) # Should print 5
|
||||||
|
|
||||||
|
|
||||||
|
# Test the storage and querying
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(storage.list_tools()) # Should print ['example_tool']
|
||||||
|
print(storage.get_tool("example_tool")) # Should print 5
|
||||||
|
storage.set_setting("example_setting", 42)
|
||||||
|
print(storage.get_setting("example_setting")) # Should print 42
|
@ -1,11 +0,0 @@
|
|||||||
"""
|
|
||||||
A loop is a sequence of instructions that is continually repeated until a certain condition is met. In the context of agent-based systems, a loop can be used to control the behavior of an agent, such as how many times it interacts with other agents or how long it runs for.
|
|
||||||
|
|
||||||
- Code Example:
|
|
||||||
|
|
||||||
loop = Loop(
|
|
||||||
PlanGeneratorAgent(),
|
|
||||||
ExecutionAgent(),
|
|
||||||
max_loops=10,
|
|
||||||
)
|
|
||||||
"""
|
|
@ -0,0 +1,69 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
from swarms.artifacts.main_artifact import Artifact, FileVersion
|
||||||
|
|
||||||
|
|
||||||
|
def artifact_save(
|
||||||
|
file_path: str,
|
||||||
|
file_type: str,
|
||||||
|
contents: str = "",
|
||||||
|
versions: List[FileVersion] = [],
|
||||||
|
edit_count: int = 0,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Saves an artifact with the given file path, file type, contents, versions, and edit count.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path (str): The path of the file.
|
||||||
|
file_type (str): The type of the file.
|
||||||
|
contents (str, optional): The contents of the file. Defaults to an empty string.
|
||||||
|
versions (List[FileVersion], optional): The list of file versions. Defaults to an empty list.
|
||||||
|
edit_count (int, optional): The number of times the file has been edited. Defaults to 0.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Artifact: The saved artifact.
|
||||||
|
"""
|
||||||
|
out = Artifact(
|
||||||
|
file_path=file_path,
|
||||||
|
file_type=file_type,
|
||||||
|
contents=contents,
|
||||||
|
versions=versions,
|
||||||
|
edit_count=edit_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
out.save()
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def edit_artifact(
|
||||||
|
file_path: str,
|
||||||
|
file_type: str,
|
||||||
|
contents: str = "",
|
||||||
|
versions: List[FileVersion] = [],
|
||||||
|
edit_count: int = 0,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Edits an artifact with the given file path, file type, contents, versions, and edit count.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path (str): The path of the file.
|
||||||
|
file_type (str): The type of the file.
|
||||||
|
contents (str, optional): The contents of the file. Defaults to an empty string.
|
||||||
|
versions (List[FileVersion], optional): The list of file versions. Defaults to an empty list.
|
||||||
|
edit_count (int, optional): The number of times the file has been edited. Defaults to 0.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Artifact: The edited artifact.
|
||||||
|
"""
|
||||||
|
out = Artifact(
|
||||||
|
file_path=file_path,
|
||||||
|
file_type=file_type,
|
||||||
|
contents=contents,
|
||||||
|
versions=versions,
|
||||||
|
edit_count=edit_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
out.edit(contents)
|
||||||
|
|
||||||
|
return out
|
@ -0,0 +1,132 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from loguru import logger
|
||||||
|
import black
|
||||||
|
from swarms.models.tiktoken_wrapper import TikTokenizer
|
||||||
|
|
||||||
|
|
||||||
|
class CodeExecutor:
|
||||||
|
"""
|
||||||
|
A class to execute Python code and return the output as a string.
|
||||||
|
|
||||||
|
The class also logs the input and output using loguru and stores the outputs
|
||||||
|
in a folder called 'artifacts'.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
execute(code: str) -> str:
|
||||||
|
Executes the given Python code and returns the output.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
max_output_length: int = 1000,
|
||||||
|
artifacts_directory: str = "artifacts",
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Initializes the CodeExecutor class and sets up the logging.
|
||||||
|
"""
|
||||||
|
self.max_output_length = max_output_length
|
||||||
|
self.artifacts_dir = artifacts_directory
|
||||||
|
os.makedirs(self.artifacts_dir, exist_ok=True)
|
||||||
|
self.setup_logging()
|
||||||
|
self.tokenizer = TikTokenizer()
|
||||||
|
|
||||||
|
def setup_logging(self) -> None:
|
||||||
|
"""
|
||||||
|
Sets up the loguru logger with colorful output.
|
||||||
|
"""
|
||||||
|
logger.add(
|
||||||
|
os.path.join(self.artifacts_dir, "code_execution.log"),
|
||||||
|
format="{time} {level} {message}",
|
||||||
|
level="DEBUG",
|
||||||
|
)
|
||||||
|
logger.info("Logger initialized and artifacts directory set up.")
|
||||||
|
|
||||||
|
def format_code(self, code: str) -> str:
|
||||||
|
"""
|
||||||
|
Formats the given Python code using black.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code (str): The Python code to format.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The formatted Python code.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the code cannot be formatted.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
formatted_code = black.format_str(code, mode=black.FileMode())
|
||||||
|
return formatted_code
|
||||||
|
except black.InvalidInput as e:
|
||||||
|
logger.error(f"Error formatting code: {e}")
|
||||||
|
raise ValueError(f"Error formatting code: {e}") from e
|
||||||
|
|
||||||
|
def execute(self, code: str) -> str:
|
||||||
|
"""
|
||||||
|
Executes the given Python code and returns the output.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code (str): The Python code to execute.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The output of the executed code.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
RuntimeError: If there is an error during the execution of the code.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
formatted_code = self.format_code(code)
|
||||||
|
logger.info(f"Executing code:\n{formatted_code}")
|
||||||
|
completed_process = subprocess.run(
|
||||||
|
["python", "-c", formatted_code],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
output = completed_process.stdout
|
||||||
|
logger.info(f"Code output:\n{output}")
|
||||||
|
token_count = self.tokenizer.count_tokens(output)
|
||||||
|
print(token_count)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.max_output_length
|
||||||
|
and token_count > self.max_output_length
|
||||||
|
):
|
||||||
|
logger.warning(
|
||||||
|
f"Output length exceeds {self.max_output_length} characters. Truncating output."
|
||||||
|
)
|
||||||
|
output = output[: self.max_output_length] + "..."
|
||||||
|
|
||||||
|
return output
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
logger.error(f"Error executing code: {e.stderr}")
|
||||||
|
raise RuntimeError(f"Error executing code: {e.stderr}") from e
|
||||||
|
|
||||||
|
|
||||||
|
# # Example usage:
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# executor = CodeExecutor(max_output_length=300)
|
||||||
|
# code = """
|
||||||
|
# import requests
|
||||||
|
# from typing import Any
|
||||||
|
|
||||||
|
# def fetch_financial_news(api_key: str, query: str, num_articles: int) -> Any:
|
||||||
|
# try:
|
||||||
|
# url = f"https://newsapi.org/v2/everything?q={query}&apiKey={api_key}"
|
||||||
|
# response = requests.get(url)
|
||||||
|
# response.raise_for_status()
|
||||||
|
# return response.json()
|
||||||
|
# except requests.RequestException as e:
|
||||||
|
# print(f"Request Error: {e}")
|
||||||
|
# raise
|
||||||
|
# except ValueError as e:
|
||||||
|
# print(f"Value Error: {e}")
|
||||||
|
# raise
|
||||||
|
|
||||||
|
# api_key = ""
|
||||||
|
# result = fetch_financial_news(api_key, query="Nvidia news", num_articles=5)
|
||||||
|
# print(result)
|
||||||
|
# """
|
||||||
|
# result = executor.execute(code)
|
||||||
|
# print(result)
|
@ -0,0 +1,148 @@
|
|||||||
|
from typing import Callable, List, Dict, Any
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
class ToolStorage:
|
||||||
|
"""
|
||||||
|
A class that represents a storage for tools.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
verbose (bool): A flag to enable verbose logging.
|
||||||
|
tools (List[Callable]): A list of tool functions.
|
||||||
|
_tools (Dict[str, Callable]): A dictionary that stores the tools, where the key is the tool name and the value is the tool function.
|
||||||
|
_settings (Dict[str, Any]): A dictionary that stores the settings, where the key is the setting name and the value is the setting value.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
verbose: bool = None,
|
||||||
|
tools: List[Callable] = None,
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
) -> None:
|
||||||
|
self.verbose = verbose
|
||||||
|
self.tools = tools
|
||||||
|
self._tools: Dict[str, Callable] = {}
|
||||||
|
self._settings: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
def add_tool(self, func: Callable) -> None:
|
||||||
|
"""
|
||||||
|
Adds a tool to the storage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
func (Callable): The tool function to be added.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If a tool with the same name already exists.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logger.info(f"Adding tool: {func.__name__}")
|
||||||
|
if func.__name__ in self._tools:
|
||||||
|
raise ValueError(
|
||||||
|
f"Tool with name {func.__name__} already exists."
|
||||||
|
)
|
||||||
|
self._tools[func.__name__] = func
|
||||||
|
logger.info(f"Added tool: {func.__name__}")
|
||||||
|
except ValueError as e:
|
||||||
|
logger.error(e)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def get_tool(self, name: str) -> Callable:
|
||||||
|
"""
|
||||||
|
Retrieves a tool by its name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): The name of the tool to retrieve.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Callable: The tool function.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If no tool with the given name is found.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logger.info(f"Getting tool: {name}")
|
||||||
|
if name not in self._tools:
|
||||||
|
raise ValueError(f"No tool found with name: {name}")
|
||||||
|
return self._tools[name]
|
||||||
|
except ValueError as e:
|
||||||
|
logger.error(e)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def set_setting(self, key: str, value: Any) -> None:
|
||||||
|
"""
|
||||||
|
Sets a setting in the storage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key for the setting.
|
||||||
|
value (Any): The value for the setting.
|
||||||
|
"""
|
||||||
|
self._settings[key] = value
|
||||||
|
logger.info(f"Setting {key} set to {value}")
|
||||||
|
|
||||||
|
def get_setting(self, key: str) -> Any:
|
||||||
|
"""
|
||||||
|
Gets a setting from the storage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The key for the setting.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any: The value of the setting.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
KeyError: If the setting is not found.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self._settings[key]
|
||||||
|
except KeyError as e:
|
||||||
|
logger.error(f"Setting {key} not found error: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def list_tools(self) -> List[str]:
|
||||||
|
"""
|
||||||
|
Lists all registered tools.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: A list of tool names.
|
||||||
|
"""
|
||||||
|
return list(self._tools.keys())
|
||||||
|
|
||||||
|
|
||||||
|
# Decorator
|
||||||
|
def tool_registry(storage: ToolStorage) -> Callable:
|
||||||
|
"""
|
||||||
|
A decorator that registers a function as a tool in the storage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
storage (ToolStorage): The storage instance to register the tool in.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Callable: The decorator function.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
logger.info(f"Registering tool: {func.__name__}")
|
||||||
|
storage.add_tool(func)
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
logger.info(f"Tool {func.__name__} executed successfully")
|
||||||
|
return result
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error executing tool {func.__name__}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
logger.info(f"Registered tool: {func.__name__}")
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# # Test the storage and querying
|
||||||
|
# if __name__ == "__main__":
|
||||||
|
# print(storage.list_tools()) # Should print ['example_tool']
|
||||||
|
# # print(use_example_tool(2, 3)) # Should print 5
|
||||||
|
# storage.set_setting("example_setting", 42)
|
||||||
|
# print(storage.get_setting("example_setting")) # Should print 42
|
Loading…
Reference in new issue