From 341e4d5ea224f87f8f799af43b126da36b3fd214 Mon Sep 17 00:00:00 2001 From: MervinPraison Date: Tue, 25 Jun 2024 10:44:24 +0100 Subject: [PATCH] v0.0.35 --- Dockerfile | 2 +- README.md | 10 +- docs/api/praisonai/agents_generator.html | 596 ++---------------- docs/api/praisonai/auto.html | 357 +---------- docs/api/praisonai/cli.html | 479 +------------- docs/api/praisonai/deploy.html | 289 +-------- .../inbuilt_tools/autogen_tools.html | 555 +--------------- docs/api/praisonai/inbuilt_tools/index.html | 35 +- docs/api/praisonai/index.html | 35 +- docs/api/praisonai/test.html | 228 +------ docs/api/praisonai/version.html | 34 +- docs/duckduckgo.md | 2 +- docs/firecrawl.md | 2 +- docs/home.md | 52 ++ docs/images/ui-step-1.png | Bin 0 -> 14382 bytes docs/images/ui-step-10.png | Bin 0 -> 128939 bytes docs/images/ui-step-11.png | Bin 0 -> 187520 bytes docs/images/ui-step-2.png | Bin 0 -> 97233 bytes docs/images/ui-step-3.png | Bin 0 -> 131135 bytes docs/images/ui-step-4.png | Bin 0 -> 101603 bytes docs/images/ui-step-5.png | Bin 0 -> 66980 bytes docs/images/ui-step-6.png | Bin 0 -> 139552 bytes docs/images/ui-step-7.png | Bin 0 -> 100855 bytes docs/images/ui-step-8.png | Bin 0 -> 140076 bytes docs/images/ui-step-9.png | Bin 0 -> 183619 bytes docs/index.md | 6 +- docs/langchain.md | 12 +- docs/other_models.md | 10 +- docs/reddit.md | 6 +- docs/requirements.txt | 3 +- docs/tavily.md | 2 +- docs/tldr.md | 13 + docs/tools.md | 2 +- docs/ui.md | 45 +- docs/wikipedia.md | 6 +- docs/you.com.md | 6 +- docs/youtube.md | 6 +- mkdocs.yml | 60 +- poetry.lock | 51 +- praisonai/agents_generator.py | 2 +- praisonai/deploy.py | 2 +- pyproject.toml | 2 +- 42 files changed, 400 insertions(+), 2510 deletions(-) create mode 100644 docs/home.md create mode 100644 docs/images/ui-step-1.png create mode 100644 docs/images/ui-step-10.png create mode 100644 docs/images/ui-step-11.png create mode 100644 docs/images/ui-step-2.png create mode 100644 docs/images/ui-step-3.png create mode 100644 docs/images/ui-step-4.png create mode 100644 docs/images/ui-step-5.png create mode 100644 docs/images/ui-step-6.png create mode 100644 docs/images/ui-step-7.png create mode 100644 docs/images/ui-step-8.png create mode 100644 docs/images/ui-step-9.png diff --git a/Dockerfile b/Dockerfile index a051eac8..a7c36a70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM python:3.11-slim WORKDIR /app COPY . . -RUN pip install flask praisonai==0.0.34 gunicorn markdown +RUN pip install flask praisonai==0.0.35 gunicorn markdown EXPOSE 8080 CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"] diff --git a/README.md b/README.md index 54aa6f17..ae307a02 100644 --- a/README.md +++ b/README.md @@ -274,22 +274,22 @@ gcloud run deploy praisonai-service \ ## Other Models ```bash -Ollama +# Ollama OPENAI_API_BASE='http://localhost:11434/v1' OPENAI_MODEL_NAME='mistral' OPENAI_API_KEY='NA' -FastChat¶ +# FastChat OPENAI_API_BASE="http://localhost:8001/v1" OPENAI_MODEL_NAME='oh-2.5m7b-q51' OPENAI_API_KEY=NA -LM Studio¶ -OPENAI_API_BASE="http://localhost:8000/v1" +# LM Studio +OPENAI_API_BASE="http://localhost:1234/v1" OPENAI_MODEL_NAME=NA OPENAI_API_KEY=NA -Mistral API¶ +# Mistral API OPENAI_API_BASE=https://api.mistral.ai/v1 OPENAI_MODEL_NAME="mistral-small" OPENAI_API_KEY=your-mistral-api-key diff --git a/docs/api/praisonai/agents_generator.html b/docs/api/praisonai/agents_generator.html index 458b8e69..eddf8fe5 100644 --- a/docs/api/praisonai/agents_generator.html +++ b/docs/api/praisonai/agents_generator.html @@ -2,18 +2,21 @@ - - + + praisonai.agents_generator API documentation - - - - - - + + + + + + - - + +
@@ -22,282 +25,6 @@

Module praisonai.agents_generator

-
- -Expand source code - -
# praisonai/agents_generator.py
-
-import sys
-from .version import __version__
-import yaml, os
-from rich import print
-from dotenv import load_dotenv
-from crewai import Agent, Task, Crew
-from crewai.telemetry import Telemetry
-load_dotenv()
-import autogen
-import argparse
-from .auto import AutoGenerator
-from crewai_tools import (
-    CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
-    FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
-    ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
-    YoutubeVideoSearchTool
-)
-from .inbuilt_tools import *
-import inspect
-from pathlib import Path
-import importlib
-import importlib.util
-from praisonai_tools import BaseTool
-import os
-
-os.environ["OTEL_SDK_DISABLED"] = "true"
-
-def noop(*args, **kwargs):
-    pass
-
-def disable_crewai_telemetry():
-    for attr in dir(Telemetry):
-        if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
-            setattr(Telemetry, attr, noop)
-            
-disable_crewai_telemetry()
-
-class AgentsGenerator:
-    def __init__(self, agent_file, framework, config_list):
-        """
-        Initialize the AgentsGenerator object.
-
-        Parameters:
-            agent_file (str): The path to the agent file.
-            framework (str): The framework to be used for the agents.
-            config_list (list): A list of configurations for the agents.
-
-        Attributes:
-            agent_file (str): The path to the agent file.
-            framework (str): The framework to be used for the agents.
-            config_list (list): A list of configurations for the agents.
-        """
-        self.agent_file = agent_file
-        self.framework = framework
-        self.config_list = config_list
-        
-    def is_function_or_decorated(self, obj):
-        """
-        Checks if the given object is a function or has a __call__ method.
-
-        Parameters:
-            obj (object): The object to be checked.
-
-        Returns:
-            bool: True if the object is a function or has a __call__ method, False otherwise.
-        """
-        return inspect.isfunction(obj) or hasattr(obj, '__call__')
-
-    def load_tools_from_module(self, module_path):
-        """
-        Loads tools from a specified module path.
-
-        Parameters:
-            module_path (str): The path to the module containing the tools.
-
-        Returns:
-            dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
-
-        Raises:
-            FileNotFoundError: If the specified module path does not exist.
-        """
-        spec = importlib.util.spec_from_file_location("tools_module", module_path)
-        module = importlib.util.module_from_spec(spec)
-        spec.loader.exec_module(module)
-        return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
-    
-    def load_tools_from_module_class(self, module_path):
-        """
-        Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
-
-        Parameters:
-            module_path (str): The path to the module containing the tools.
-
-        Returns:
-            dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-
-        Raises:
-            FileNotFoundError: If the specified module path does not exist.
-        """
-        spec = importlib.util.spec_from_file_location("tools_module", module_path)
-        module = importlib.util.module_from_spec(spec)
-        spec.loader.exec_module(module)
-        return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith('langchain_community.tools') or issubclass(x, BaseTool)) and x is not BaseTool)}
-
-    def load_tools_from_package(self, package_path):
-        """
-        Loads tools from a specified package path containing modules with functions or classes.
-
-        Parameters:
-            package_path (str): The path to the package containing the tools.
-
-        Returns:
-            dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-
-        Raises:
-            FileNotFoundError: If the specified package path does not exist.
-
-        This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-        """
-        tools_dict = {}
-        for module_file in os.listdir(package_path):
-            if module_file.endswith('.py') and not module_file.startswith('__'):
-                module_name = f"{package_path.name}.{module_file[:-3]}"  # Remove .py for import
-                module = importlib.import_module(module_name)
-                for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
-                    tools_dict[name] = obj
-        return tools_dict
-
-    def generate_crew_and_kickoff(self):
-        """
-        Generates a crew of agents and initiates tasks based on the provided configuration.
-
-        Parameters:
-            agent_file (str): The path to the agent file.
-            framework (str): The framework to be used for the agents.
-            config_list (list): A list of configurations for the agents.
-
-        Returns:
-            str: The output of the tasks performed by the crew of agents.
-
-        Raises:
-            FileNotFoundError: If the specified agent file does not exist.
-
-        This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.
-        """
-        if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
-            self.agent_file = 'agents.yaml'
-        try:
-            with open(self.agent_file, 'r') as f:
-                config = yaml.safe_load(f)
-        except FileNotFoundError:
-            print(f"File not found: {self.agent_file}")
-            return
-
-        topic = config['topic']
-        tools_dict = {
-            'CodeDocsSearchTool': CodeDocsSearchTool(),
-            'CSVSearchTool': CSVSearchTool(),
-            'DirectorySearchTool': DirectorySearchTool(),
-            'DOCXSearchTool': DOCXSearchTool(),
-            'DirectoryReadTool': DirectoryReadTool(),
-            'FileReadTool': FileReadTool(),
-            # 'GithubSearchTool': GithubSearchTool(),
-            # 'SeperDevTool': SeperDevTool(),
-            'TXTSearchTool': TXTSearchTool(),
-            'JSONSearchTool': JSONSearchTool(),
-            'MDXSearchTool': MDXSearchTool(),
-            'PDFSearchTool': PDFSearchTool(),
-            # 'PGSearchTool': PGSearchTool(),
-            'RagTool': RagTool(),
-            'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
-            'ScrapeWebsiteTool': ScrapeWebsiteTool(),
-            'WebsiteSearchTool': WebsiteSearchTool(),
-            'XMLSearchTool': XMLSearchTool(),
-            'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
-            'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
-        }
-        root_directory = os.getcwd()
-        tools_py_path = os.path.join(root_directory, 'tools.py')
-        tools_dir_path = Path(root_directory) / 'tools'
-        
-        if os.path.isfile(tools_py_path):
-            tools_dict.update(self.load_tools_from_module_class(tools_py_path))
-            # print("tools.py exists in the root directory. Loading tools.py and skipping tools folder.")
-        elif tools_dir_path.is_dir():
-            tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
-            # print("tools folder exists in the root directory")
-        
-        framework = self.framework or config.get('framework')
-
-        agents = {}
-        tasks = []
-        if framework == "autogen":
-            # Load the LLM configuration dynamically
-            # print(self.config_list)
-            llm_config = {"config_list": self.config_list}
-            
-            # Assuming the user proxy agent is set up as per your requirements
-            user_proxy = autogen.UserProxyAgent(
-                name="User",
-                human_input_mode="NEVER",
-                is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
-                code_execution_config={
-                    "work_dir": "coding",
-                    "use_docker": False,
-                },
-                # additional setup for the user proxy agent
-            )
-            
-            for role, details in config['roles'].items():
-                agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
-                agent_goal = details['goal'].format(topic=topic)
-                # Creating an AssistantAgent for each role dynamically
-                agents[role] = autogen.AssistantAgent(
-                    name=agent_name,
-                    llm_config=llm_config,
-                    system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
-                )
-                for tool in details.get('tools', []):
-                    if tool in tools_dict:
-                        try:
-                            tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
-                            print(f"Found {tool_class.__name__} for {tool}")
-                        except KeyError:
-                            print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
-                            continue
-                        tool_class(agents[role], user_proxy)
-
-                # Preparing tasks for initiate_chats
-                for task_name, task_details in details.get('tasks', {}).items():
-                    description_filled = task_details['description'].format(topic=topic)
-                    expected_output_filled = task_details['expected_output'].format(topic=topic)
-                    
-                    chat_task = {
-                        "recipient": agents[role],
-                        "message": description_filled,
-                        "summary_method": "last_msg", 
-                        # Additional fields like carryover can be added based on dependencies
-                    }
-                    tasks.append(chat_task)
-
-            response = user_proxy.initiate_chats(tasks)
-            result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
-        else:
-            for role, details in config['roles'].items():
-                role_filled = details['role'].format(topic=topic)
-                goal_filled = details['goal'].format(topic=topic)
-                backstory_filled = details['backstory'].format(topic=topic)
-                
-                # Adding tools to the agent if exists
-                agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
-                agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, tools=agent_tools, allow_delegation=False)
-                agents[role] = agent
-
-                for task_name, task_details in details.get('tasks', {}).items():
-                    description_filled = task_details['description'].format(topic=topic)
-                    expected_output_filled = task_details['expected_output'].format(topic=topic)
-
-                    task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
-                    tasks.append(task)
-            crew = Crew(
-                agents=list(agents.values()),
-                tasks=tasks,
-                verbose=2
-            )
-
-            response = crew.kickoff()
-            result = f"### Task Output ###\n{response}"
-        return result
-
@@ -311,28 +38,12 @@

Functions

-
- -Expand source code - -
def disable_crewai_telemetry():
-    for attr in dir(Telemetry):
-        if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
-            setattr(Telemetry, attr, noop)
-
def noop(*args, **kwargs)
-
- -Expand source code - -
def noop(*args, **kwargs):
-    pass
-
@@ -341,14 +52,17 @@

Classes

class AgentsGenerator -(agent_file, framework, config_list) +(agent_file, framework, config_list, log_level=20, agent_callback=None, task_callback=None)

Initialize the AgentsGenerator object.

Parameters

agent_file (str): The path to the agent file. framework (str): The framework to be used for the agents. -config_list (list): A list of configurations for the agents.

+config_list (list): A list of configurations for the agents. +log_level (int, optional): The logging level to use. Defaults to logging.INFO. +agent_callback (callable, optional): A callback function to be executed after each agent step. +task_callback (callable, optional): A callback function to be executed after each tool run.

Attributes

agent_file : str
@@ -357,13 +71,19 @@

Attributes

The framework to be used for the agents.
config_list : list
A list of configurations for the agents.
+
log_level : int
+
The logging level to use.
+
agent_callback : callable, optional
+
A callback function to be executed after each agent step.
+
task_callback : callable, optional
+
A callback function to be executed after each tool run.
Expand source code
class AgentsGenerator:
-    def __init__(self, agent_file, framework, config_list):
+    def __init__(self, agent_file, framework, config_list, log_level=logging.INFO, agent_callback=None, task_callback=None):
         """
         Initialize the AgentsGenerator object.
 
@@ -371,15 +91,28 @@ 

Attributes

agent_file (str): The path to the agent file. framework (str): The framework to be used for the agents. config_list (list): A list of configurations for the agents. + log_level (int, optional): The logging level to use. Defaults to logging.INFO. + agent_callback (callable, optional): A callback function to be executed after each agent step. + task_callback (callable, optional): A callback function to be executed after each tool run. Attributes: agent_file (str): The path to the agent file. framework (str): The framework to be used for the agents. config_list (list): A list of configurations for the agents. + log_level (int): The logging level to use. + agent_callback (callable, optional): A callback function to be executed after each agent step. + task_callback (callable, optional): A callback function to be executed after each tool run. """ self.agent_file = agent_file self.framework = framework self.config_list = config_list + self.log_level = log_level + self.agent_callback = agent_callback + self.task_callback = task_callback + + logging.basicConfig(level=self.log_level, format='%(asctime)s - %(levelname)s - %(message)s') + self.logger = logging.getLogger(__name__) + self.logger.setLevel(self.log_level) def is_function_or_decorated(self, obj): """ @@ -577,6 +310,11 @@

Attributes

# Adding tools to the agent if exists agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict] agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, tools=agent_tools, allow_delegation=False) + + # Set agent callback if provided + if self.agent_callback: + agent.step_callback = self.agent_callback + agents[role] = agent for task_name, task_details in details.get('tasks', {}).items(): @@ -584,12 +322,21 @@

Attributes

expected_output_filled = task_details['expected_output'].format(topic=topic) task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent) + + # Set tool callback if provided + if self.task_callback: + task.callback = self.task_callback + tasks.append(task) crew = Crew( agents=list(agents.values()), tasks=tasks, verbose=2 ) + + self.logger.debug("Final Crew Configuration:") + self.logger.debug(f"Agents: {crew.agents}") + self.logger.debug(f"Tasks: {crew.tasks}") response = crew.kickoff() result = f"### Task Output ###\n{response}" @@ -617,152 +364,6 @@

Raises

If the specified agent file does not exist.

This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.

-
- -Expand source code - -
def generate_crew_and_kickoff(self):
-    """
-    Generates a crew of agents and initiates tasks based on the provided configuration.
-
-    Parameters:
-        agent_file (str): The path to the agent file.
-        framework (str): The framework to be used for the agents.
-        config_list (list): A list of configurations for the agents.
-
-    Returns:
-        str: The output of the tasks performed by the crew of agents.
-
-    Raises:
-        FileNotFoundError: If the specified agent file does not exist.
-
-    This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.
-    """
-    if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
-        self.agent_file = 'agents.yaml'
-    try:
-        with open(self.agent_file, 'r') as f:
-            config = yaml.safe_load(f)
-    except FileNotFoundError:
-        print(f"File not found: {self.agent_file}")
-        return
-
-    topic = config['topic']
-    tools_dict = {
-        'CodeDocsSearchTool': CodeDocsSearchTool(),
-        'CSVSearchTool': CSVSearchTool(),
-        'DirectorySearchTool': DirectorySearchTool(),
-        'DOCXSearchTool': DOCXSearchTool(),
-        'DirectoryReadTool': DirectoryReadTool(),
-        'FileReadTool': FileReadTool(),
-        # 'GithubSearchTool': GithubSearchTool(),
-        # 'SeperDevTool': SeperDevTool(),
-        'TXTSearchTool': TXTSearchTool(),
-        'JSONSearchTool': JSONSearchTool(),
-        'MDXSearchTool': MDXSearchTool(),
-        'PDFSearchTool': PDFSearchTool(),
-        # 'PGSearchTool': PGSearchTool(),
-        'RagTool': RagTool(),
-        'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
-        'ScrapeWebsiteTool': ScrapeWebsiteTool(),
-        'WebsiteSearchTool': WebsiteSearchTool(),
-        'XMLSearchTool': XMLSearchTool(),
-        'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
-        'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
-    }
-    root_directory = os.getcwd()
-    tools_py_path = os.path.join(root_directory, 'tools.py')
-    tools_dir_path = Path(root_directory) / 'tools'
-    
-    if os.path.isfile(tools_py_path):
-        tools_dict.update(self.load_tools_from_module_class(tools_py_path))
-        # print("tools.py exists in the root directory. Loading tools.py and skipping tools folder.")
-    elif tools_dir_path.is_dir():
-        tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
-        # print("tools folder exists in the root directory")
-    
-    framework = self.framework or config.get('framework')
-
-    agents = {}
-    tasks = []
-    if framework == "autogen":
-        # Load the LLM configuration dynamically
-        # print(self.config_list)
-        llm_config = {"config_list": self.config_list}
-        
-        # Assuming the user proxy agent is set up as per your requirements
-        user_proxy = autogen.UserProxyAgent(
-            name="User",
-            human_input_mode="NEVER",
-            is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
-            code_execution_config={
-                "work_dir": "coding",
-                "use_docker": False,
-            },
-            # additional setup for the user proxy agent
-        )
-        
-        for role, details in config['roles'].items():
-            agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
-            agent_goal = details['goal'].format(topic=topic)
-            # Creating an AssistantAgent for each role dynamically
-            agents[role] = autogen.AssistantAgent(
-                name=agent_name,
-                llm_config=llm_config,
-                system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
-            )
-            for tool in details.get('tools', []):
-                if tool in tools_dict:
-                    try:
-                        tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
-                        print(f"Found {tool_class.__name__} for {tool}")
-                    except KeyError:
-                        print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
-                        continue
-                    tool_class(agents[role], user_proxy)
-
-            # Preparing tasks for initiate_chats
-            for task_name, task_details in details.get('tasks', {}).items():
-                description_filled = task_details['description'].format(topic=topic)
-                expected_output_filled = task_details['expected_output'].format(topic=topic)
-                
-                chat_task = {
-                    "recipient": agents[role],
-                    "message": description_filled,
-                    "summary_method": "last_msg", 
-                    # Additional fields like carryover can be added based on dependencies
-                }
-                tasks.append(chat_task)
-
-        response = user_proxy.initiate_chats(tasks)
-        result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
-    else:
-        for role, details in config['roles'].items():
-            role_filled = details['role'].format(topic=topic)
-            goal_filled = details['goal'].format(topic=topic)
-            backstory_filled = details['backstory'].format(topic=topic)
-            
-            # Adding tools to the agent if exists
-            agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
-            agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, tools=agent_tools, allow_delegation=False)
-            agents[role] = agent
-
-            for task_name, task_details in details.get('tasks', {}).items():
-                description_filled = task_details['description'].format(topic=topic)
-                expected_output_filled = task_details['expected_output'].format(topic=topic)
-
-                task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
-                tasks.append(task)
-        crew = Crew(
-            agents=list(agents.values()),
-            tasks=tasks,
-            verbose=2
-        )
-
-        response = crew.kickoff()
-        result = f"### Task Output ###\n{response}"
-    return result
-
def is_function_or_decorated(self, obj) @@ -776,22 +377,6 @@

Returns

bool
True if the object is a function or has a call method, False otherwise.
-
- -Expand source code - -
def is_function_or_decorated(self, obj):
-    """
-    Checks if the given object is a function or has a __call__ method.
-
-    Parameters:
-        obj (object): The object to be checked.
-
-    Returns:
-        bool: True if the object is a function or has a __call__ method, False otherwise.
-    """
-    return inspect.isfunction(obj) or hasattr(obj, '__call__')
-
def load_tools_from_module(self, module_path) @@ -810,28 +395,6 @@

Raises

FileNotFoundError
If the specified module path does not exist.
-
- -Expand source code - -
def load_tools_from_module(self, module_path):
-    """
-    Loads tools from a specified module path.
-
-    Parameters:
-        module_path (str): The path to the module containing the tools.
-
-    Returns:
-        dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
-
-    Raises:
-        FileNotFoundError: If the specified module path does not exist.
-    """
-    spec = importlib.util.spec_from_file_location("tools_module", module_path)
-    module = importlib.util.module_from_spec(spec)
-    spec.loader.exec_module(module)
-    return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
-
def load_tools_from_module_class(self, module_path) @@ -850,28 +413,6 @@

Raises

FileNotFoundError
If the specified module path does not exist.
-
- -Expand source code - -
def load_tools_from_module_class(self, module_path):
-    """
-    Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
-
-    Parameters:
-        module_path (str): The path to the module containing the tools.
-
-    Returns:
-        dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-
-    Raises:
-        FileNotFoundError: If the specified module path does not exist.
-    """
-    spec = importlib.util.spec_from_file_location("tools_module", module_path)
-    module = importlib.util.module_from_spec(spec)
-    spec.loader.exec_module(module)
-    return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith('langchain_community.tools') or issubclass(x, BaseTool)) and x is not BaseTool)}
-
def load_tools_from_package(self, package_path) @@ -891,34 +432,6 @@

Raises

If the specified package path does not exist.

This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.

-
- -Expand source code - -
def load_tools_from_package(self, package_path):
-    """
-    Loads tools from a specified package path containing modules with functions or classes.
-
-    Parameters:
-        package_path (str): The path to the package containing the tools.
-
-    Returns:
-        dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-
-    Raises:
-        FileNotFoundError: If the specified package path does not exist.
-
-    This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
-    """
-    tools_dict = {}
-    for module_file in os.listdir(package_path):
-        if module_file.endswith('.py') and not module_file.startswith('__'):
-            module_name = f"{package_path.name}.{module_file[:-3]}"  # Remove .py for import
-            module = importlib.import_module(module_name)
-            for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
-                tools_dict[name] = obj
-    return tools_dict
-
@@ -926,7 +439,6 @@

Raises