From 659ca04752992bc1a56ba2d6570f1296c1fbba90 Mon Sep 17 00:00:00 2001 From: Robert Jambrecic Date: Thu, 19 Dec 2024 12:19:48 +0100 Subject: [PATCH] Add docstrings --- autogen/interop/crewai/crewai.py | 25 ++++++++++ autogen/interop/interoperability.py | 55 ++++++++++++++++++++++ autogen/interop/interoperable.py | 22 ++++++++- autogen/interop/langchain/langchain.py | 27 +++++++++++ autogen/interop/pydantic_ai/pydantic_ai.py | 47 ++++++++++++++++++ autogen/tools/pydantic_ai_tool.py | 33 +++++++++++++ autogen/tools/tool.py | 30 ++++++++++++ 7 files changed, 238 insertions(+), 1 deletion(-) diff --git a/autogen/interop/crewai/crewai.py b/autogen/interop/crewai/crewai.py index 240ec47960..97abda9e77 100644 --- a/autogen/interop/crewai/crewai.py +++ b/autogen/interop/crewai/crewai.py @@ -18,7 +18,32 @@ def _sanitize_name(s: str) -> str: class CrewAIInteroperability(Interoperable): + """ + A class implementing the `Interoperable` protocol for converting CrewAI tools + to a general `Tool` format. + + This class takes a `CrewAITool` and converts it into a standard `Tool` object. + """ + def convert_tool(self, tool: Any, **kwargs: Any) -> Tool: + """ + Converts a given CrewAI tool into a general `Tool` format. + + This method ensures that the provided tool is a valid `CrewAITool`, sanitizes + the tool's name, processes its description, and prepares a function to interact + with the tool's arguments. It then returns a standardized `Tool` object. + + Args: + tool (Any): The tool to convert, expected to be an instance of `CrewAITool`. + **kwargs (Any): Additional arguments, which are not supported by this method. + + Returns: + Tool: A standardized `Tool` object converted from the CrewAI tool. + + Raises: + ValueError: If the provided tool is not an instance of `CrewAITool`, or if + any additional arguments are passed. + """ if not isinstance(tool, CrewAITool): raise ValueError(f"Expected an instance of `crewai.tools.BaseTool`, got {type(tool)}") if kwargs: diff --git a/autogen/interop/interoperability.py b/autogen/interop/interoperability.py index 68190fbf04..27df3cd9c7 100644 --- a/autogen/interop/interoperability.py +++ b/autogen/interop/interoperability.py @@ -11,28 +11,83 @@ class Interoperability: + """ + A class to handle interoperability between different tool types. + + This class allows the conversion of tools to various interoperability classes and provides functionality + for retrieving and registering interoperability classes. + """ + _interoperability_classes: Dict[str, Type[Interoperable]] = get_all_interoperability_classes() def __init__(self) -> None: + """ + Initializes an instance of the Interoperability class. + + This constructor does not perform any specific actions as the class is primarily used for its class + methods to manage interoperability classes. + """ pass def convert_tool(self, *, tool: Any, type: str, **kwargs: Any) -> Tool: + """ + Converts a given tool to an instance of a specified interoperability type. + + Args: + tool (Any): The tool object to be converted. + type (str): The type of interoperability to convert the tool to. + **kwargs (Any): Additional arguments to be passed during conversion. + + Returns: + Tool: The converted tool. + + Raises: + ValueError: If the interoperability class for the provided type is not found. + """ interop_cls = self.get_interoperability_class(type) interop = interop_cls() return interop.convert_tool(tool, **kwargs) @classmethod def get_interoperability_class(cls, type: str) -> Type[Interoperable]: + """ + Retrieves the interoperability class corresponding to the specified type. + + Args: + type (str): The type of the interoperability class to retrieve. + + Returns: + Type[Interoperable]: The interoperability class type. + + Raises: + ValueError: If no interoperability class is found for the provided type. + """ if type not in cls._interoperability_classes: raise ValueError(f"Interoperability class {type} not found") return cls._interoperability_classes[type] @classmethod def supported_types(cls) -> List[str]: + """ + Returns a sorted list of all supported interoperability types. + + Returns: + List[str]: A sorted list of strings representing the supported interoperability types. + """ return sorted(cls._interoperability_classes.keys()) @classmethod def register_interoperability_class(cls, name: str, interoperability_class: Type[Interoperable]) -> None: + """ + Registers a new interoperability class with the given name. + + Args: + name (str): The name to associate with the interoperability class. + interoperability_class (Type[Interoperable]): The class implementing the Interoperable protocol. + + Raises: + ValueError: If the provided class does not implement the Interoperable protocol. + """ if not issubclass(interoperability_class, Interoperable): raise ValueError( f"Expected a class implementing `Interoperable` protocol, got {type(interoperability_class)}" diff --git a/autogen/interop/interoperable.py b/autogen/interop/interoperable.py index 1b9bed1405..75aefaaf25 100644 --- a/autogen/interop/interoperable.py +++ b/autogen/interop/interoperable.py @@ -11,4 +11,24 @@ @runtime_checkable class Interoperable(Protocol): - def convert_tool(self, tool: Any, **kwargs: Any) -> Tool: ... + """ + A Protocol defining the interoperability interface for tool conversion. + + This protocol ensures that any class implementing it provides the method + `convert_tool` to convert a given tool into a desired format or type. + """ + + def convert_tool(self, tool: Any, **kwargs: Any) -> Tool: + """ + Converts a given tool to a desired format or type. + + This method should be implemented by any class adhering to the `Interoperable` protocol. + + Args: + tool (Any): The tool object to be converted. + **kwargs (Any): Additional parameters to pass during the conversion process. + + Returns: + Tool: The converted tool in the desired format or type. + """ + ... diff --git a/autogen/interop/langchain/langchain.py b/autogen/interop/langchain/langchain.py index 1507796c5d..925e00431a 100644 --- a/autogen/interop/langchain/langchain.py +++ b/autogen/interop/langchain/langchain.py @@ -13,7 +13,34 @@ class LangchainInteroperability(Interoperable): + """ + A class implementing the `Interoperable` protocol for converting Langchain tools + into a general `Tool` format. + + This class takes a `LangchainTool` and converts it into a standard `Tool` object, + ensuring compatibility between Langchain tools and other systems that expect + the `Tool` format. + """ + def convert_tool(self, tool: Any, **kwargs: Any) -> Tool: + """ + Converts a given Langchain tool into a general `Tool` format. + + This method verifies that the provided tool is a valid `LangchainTool`, + processes the tool's input and description, and returns a standardized + `Tool` object. + + Args: + tool (Any): The tool to convert, expected to be an instance of `LangchainTool`. + **kwargs (Any): Additional arguments, which are not supported by this method. + + Returns: + Tool: A standardized `Tool` object converted from the Langchain tool. + + Raises: + ValueError: If the provided tool is not an instance of `LangchainTool`, or if + any additional arguments are passed. + """ if not isinstance(tool, LangchainTool): raise ValueError(f"Expected an instance of `langchain_core.tools.BaseTool`, got {type(tool)}") if kwargs: diff --git a/autogen/interop/pydantic_ai/pydantic_ai.py b/autogen/interop/pydantic_ai/pydantic_ai.py index fe778ea904..b170ccf501 100644 --- a/autogen/interop/pydantic_ai/pydantic_ai.py +++ b/autogen/interop/pydantic_ai/pydantic_ai.py @@ -18,11 +18,38 @@ class PydanticAIInteroperability(Interoperable): + """ + A class implementing the `Interoperable` protocol for converting Pydantic AI tools + into a general `Tool` format. + + This class takes a `PydanticAITool` and converts it into a standard `Tool` object, + ensuring compatibility between Pydantic AI tools and other systems that expect + the `Tool` format. It also provides a mechanism for injecting context parameters + into the tool's function. + """ + @staticmethod def inject_params( # type: ignore[no-any-unimported] ctx: Optional[RunContext[Any]], tool: PydanticAITool, ) -> Callable[..., Any]: + """ + Wraps the tool's function to inject context parameters and handle retries. + + This method ensures that context parameters are properly passed to the tool + when invoked and that retries are managed according to the tool's settings. + + Args: + ctx (Optional[RunContext[Any]]): The run context, which may include dependencies + and retry information. + tool (PydanticAITool): The Pydantic AI tool whose function is to be wrapped. + + Returns: + Callable[..., Any]: A wrapped function that includes context injection and retry handling. + + Raises: + ValueError: If the tool fails after the maximum number of retries. + """ max_retries = tool.max_retries if tool.max_retries is not None else 1 f = tool.function @@ -56,6 +83,26 @@ def wrapper(*args: Any, **kwargs: Any) -> Any: return wrapper def convert_tool(self, tool: Any, deps: Any = None, **kwargs: Any) -> AG2PydanticAITool: + """ + Converts a given Pydantic AI tool into a general `Tool` format. + + This method verifies that the provided tool is a valid `PydanticAITool`, + handles context dependencies if necessary, and returns a standardized `Tool` object. + + Args: + tool (Any): The tool to convert, expected to be an instance of `PydanticAITool`. + deps (Any, optional): The dependencies to inject into the context, required if + the tool takes a context. Defaults to None. + **kwargs (Any): Additional arguments that are not used in this method. + + Returns: + AG2PydanticAITool: A standardized `Tool` object converted from the Pydantic AI tool. + + Raises: + ValueError: If the provided tool is not an instance of `PydanticAITool`, or if + dependencies are missing for tools that require a context. + UserWarning: If the `deps` argument is provided for a tool that does not take a context. + """ if not isinstance(tool, PydanticAITool): raise ValueError(f"Expected an instance of `pydantic_ai.tools.Tool`, got {type(tool)}") diff --git a/autogen/tools/pydantic_ai_tool.py b/autogen/tools/pydantic_ai_tool.py index 5c999eba3a..a106cd4b70 100644 --- a/autogen/tools/pydantic_ai_tool.py +++ b/autogen/tools/pydantic_ai_tool.py @@ -12,9 +12,33 @@ class PydanticAITool(Tool): + """ + A class representing a Pydantic AI Tool that extends the general Tool functionality + with additional functionality specific to Pydantic AI tools. + + This class inherits from the Tool class and adds functionality for registering + tools with a ConversableAgent, along with providing additional schema information + specific to Pydantic AI tools, such as parameters and function signatures. + + Attributes: + parameters_json_schema (Dict[str, Any]): A schema describing the parameters + that the tool's function expects. + """ + def __init__( self, name: str, description: str, func: Callable[..., Any], parameters_json_schema: Dict[str, Any] ) -> None: + """ + Initializes a PydanticAITool object with the provided name, description, + function, and parameter schema. + + Args: + name (str): The name of the tool. + description (str): A description of what the tool does. + func (Callable[..., Any]): The function that is executed when the tool is called. + parameters_json_schema (Dict[str, Any]): A schema describing the parameters + that the function accepts. + """ super().__init__(name, description, func) self._func_schema = { "type": "function", @@ -26,4 +50,13 @@ def __init__( } def register_for_llm(self, agent: ConversableAgent) -> None: + """ + Registers the tool with the ConversableAgent for use with a language model (LLM). + + This method updates the agent's tool signature to include the function schema, + allowing the agent to invoke the tool correctly during interactions with the LLM. + + Args: + agent (ConversableAgent): The agent with which the tool will be registered. + """ agent.update_tool_signature(self._func_schema, is_remove=False) diff --git a/autogen/tools/tool.py b/autogen/tools/tool.py index b01367235c..c0e615f37c 100644 --- a/autogen/tools/tool.py +++ b/autogen/tools/tool.py @@ -16,6 +16,18 @@ class Tool: + """ + A class representing a Tool that can be used by an agent for various tasks. + + This class encapsulates a tool with a name, description, and an executable function. + The tool can be registered with a ConversableAgent for use either with an LLM or for direct execution. + + Attributes: + name (str): The name of the tool. + description (str): A brief description of the tool's purpose or function. + func (Callable[..., Any]): The function to be executed when the tool is called. + """ + def __init__(self, name: str, description: str, func: Callable[..., Any]) -> None: """Create a new Tool object. @@ -41,7 +53,25 @@ def func(self) -> Callable[..., Any]: return self._func def register_for_llm(self, agent: ConversableAgent) -> None: + """ + Registers the tool for use with a ConversableAgent's language model (LLM). + + This method registers the tool so that it can be invoked by the agent during + interactions with the language model. + + Args: + agent (ConversableAgent): The agent to which the tool will be registered. + """ agent.register_for_llm(name=self._name, description=self._description)(self._func) def register_for_execution(self, agent: ConversableAgent) -> None: + """ + Registers the tool for direct execution by a ConversableAgent. + + This method registers the tool so that it can be executed by the agent, + typically outside of the context of an LLM interaction. + + Args: + agent (ConversableAgent): The agent to which the tool will be registered. + """ agent.register_for_execution(name=self._name)(self._func)