| | from dataclasses import dataclass |
| | from typing import Optional, Type |
| | from abc import ABC |
| | from importlib import import_module |
| |
|
| | from ..exceptions.exceptions import InvalidConfigException |
| | from ..utils import Config |
| |
|
| |
|
| | @dataclass |
| | class BaseToolRequest(ABC): |
| | input_text: Optional[str] |
| |
|
| |
|
| | @dataclass |
| | class BaseToolResponse(ABC): |
| | output_text: Optional[str] |
| |
|
| |
|
| | |
| | class BaseTool(ABC): |
| | _name = None |
| | _description = None |
| |
|
| | def __init__(self, name, description, **kwargs): |
| | self._name = name |
| | self._description = description |
| | self.setup() |
| |
|
| | @property |
| | def name(self): |
| | """Getter for name.""" |
| | return self._name |
| |
|
| | @property |
| | def description(self): |
| | """Getter for description.""" |
| | return self._description |
| |
|
| | @classmethod |
| | def from_config(cls, config_input, **kwargs): |
| | """Create a BaseTool instance from a config file path or a config data dictionary. |
| | |
| | :param config_input: Either a file path to a config file or a config data dictionary. |
| | :type config_input: str or dict |
| | :param kwargs: Additional keyword arguments to pass to the class constructor. |
| | :return: A BaseTool instance. |
| | :rtype: BaseTool |
| | """ |
| | if isinstance(config_input, str): |
| | |
| | config_data = Config.load(config_input) |
| | elif isinstance(config_input, dict): |
| | |
| | config_data = config_input |
| | else: |
| | raise InvalidConfigException( |
| | f"Invalid config_input type: {type(config_input)}. " |
| | "Expected str (file path) or dict (config data)." |
| | ) |
| |
|
| | module_name = config_data['module_name'] |
| | class_name = config_data['class_name'] |
| | module = import_module(module_name) |
| | clazz = getattr(module, class_name) |
| | return clazz(**config_data, **kwargs) |
| |
|
| | @classmethod |
| | async def async_from_config(cls, config_input, **params): |
| | """Asynchronously create a BaseTool instance from a config file path or a config data dictionary. |
| | |
| | :param config_input: Either a file path to a config file or a config data dictionary. |
| | :type config_input: str or dict |
| | :param params: Additional parameters to pass to the create method. |
| | :return: A BaseTool instance. |
| | :rtype: BaseTool |
| | """ |
| | |
| |
|
| | if isinstance(config_input, str): |
| | |
| | config_data = Config.load(config_input) |
| | elif isinstance(config_input, dict): |
| | |
| | config_data = config_input |
| | else: |
| | raise InvalidConfigException( |
| | f"Invalid config_input type: {type(config_input)}. " |
| | "Expected str (file path) or dict (config data)." |
| | ) |
| |
|
| | |
| | module_name = config_data['module_name'] |
| | class_name = config_data['class_name'] |
| | module = import_module(module_name) |
| | clazz = getattr(module, class_name) |
| | |
| | return await clazz.create(config_data, **params) |
| |
|
| | @classmethod |
| | async def async_from_config_path(cls, config_path, **params): |
| | return await cls.async_from_config_data(config_data=Config.load(config_path), **params) |
| |
|
| | @classmethod |
| | async def async_from_config_data(cls, config_data, **params): |
| | module_name = config_data['module_name'] |
| | class_name = config_data['class_name'] |
| |
|
| | module = import_module(module_name) |
| | clazz = getattr(module, class_name) |
| |
|
| | return await clazz.create(config_data, **params) |
| |
|
| | @classmethod |
| | async def create(cls, config_data, **params): |
| | """ |
| | Async create tool instance. init cannot be async, so wrap async init logic here. |
| | """ |
| | pass |
| |
|
| | def setup(self): |
| | pass |
| |
|
| | def run(self, req: BaseToolRequest): |
| | pass |
| |
|
| | async def async_run(self, req: BaseToolRequest): |
| | """ |
| | Async run tool. |
| | """ |
| | return self.run(req) |
| |
|