mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-10 03:31:28 -10:00
Compare commits
18
Commits
fix-issue-20
...
v0.0.20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c35a4e973a | ||
|
|
89db863fd0 | ||
|
|
6bf1fa6c61 | ||
|
|
27a4597c37 | ||
|
|
0a27c9f64c | ||
|
|
932afad679 | ||
|
|
4ddd0bc5a9 | ||
|
|
d814aa66eb | ||
|
|
f2d76d2d56 | ||
|
|
af88f121e3 | ||
|
|
b21d48c51d | ||
|
|
ba2dfe1909 | ||
|
|
865aa65448 | ||
|
|
e5ceca314d | ||
|
|
2dacd09724 | ||
|
|
b92f6e0bb3 | ||
|
|
2c74084eaf | ||
|
|
3a0cb0e33a |
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==0.0.18 gunicorn markdown
|
||||
RUN pip install flask praisonai==0.0.20 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -0,0 +1,42 @@
|
||||
framework: crewai
|
||||
topic: create a movie about cat in mars based on https://blog.celtx.com/how-to-write-a-good-story/
|
||||
roles:
|
||||
story_developer:
|
||||
backstory: Experienced in crafting compelling narratives for a diverse audience.
|
||||
goal: Develop an engaging storyline for a movie about cats in Mars
|
||||
role: Story Developer
|
||||
tasks:
|
||||
storyline_creation:
|
||||
description: Create a captivating storyline for a movie about cats in Mars
|
||||
inspired by the blog post at https://blog.celtx.com/how-to-write-a-good-story/
|
||||
expected_output: Detailed storyline with key plot points, character motivations,
|
||||
and setting descriptions.
|
||||
tools:
|
||||
- 'ScrapeWebsiteTool'
|
||||
screenwriter:
|
||||
backstory: Proficient in translating complex narratives into engaging screenplay
|
||||
format.
|
||||
goal: Transform the storyline into a script
|
||||
role: Screenwriter
|
||||
tasks:
|
||||
script_creation:
|
||||
description: Transform the developed storyline into a script for the movie
|
||||
about cats in Mars.
|
||||
expected_output: Complete script with dialogues, scenes, and stage directions
|
||||
ready for production.
|
||||
tools:
|
||||
- ''
|
||||
director:
|
||||
backstory: Experienced in visual storytelling and bringing scripts to life on
|
||||
screen.
|
||||
goal: Oversee the production of the movie
|
||||
role: Director
|
||||
tasks:
|
||||
movie_production:
|
||||
description: Take the script and lead the team to produce the movie 'Cats
|
||||
in Mars' based on the provided content and script.
|
||||
expected_output: Completed movie ready for distribution with compelling visuals
|
||||
and engaging storytelling.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
+18
-34
@@ -1,42 +1,26 @@
|
||||
framework: crewai
|
||||
topic: create a movie about cat in mars based on https://blog.celtx.com/how-to-write-a-good-story/
|
||||
topic: research about the latest AI News and prepare a detailed report
|
||||
roles:
|
||||
story_developer:
|
||||
backstory: Experienced in crafting compelling narratives for a diverse audience.
|
||||
goal: Develop an engaging storyline for a movie about cats in Mars
|
||||
role: Story Developer
|
||||
research_analyst:
|
||||
backstory: Experienced in gathering and analyzing data related to AI news trends.
|
||||
goal: Analyze AI News trends
|
||||
role: Research Analyst
|
||||
tasks:
|
||||
storyline_creation:
|
||||
description: Create a captivating storyline for a movie about cats in Mars
|
||||
inspired by the blog post at https://blog.celtx.com/how-to-write-a-good-story/
|
||||
expected_output: Detailed storyline with key plot points, character motivations,
|
||||
and setting descriptions.
|
||||
gather_data:
|
||||
description: Conduct in-depth research on the latest AI News trends from reputable
|
||||
sources.
|
||||
expected_output: Comprehensive report on current AI News trends.
|
||||
tools:
|
||||
- 'ScrapeWebsiteTool'
|
||||
screenwriter:
|
||||
backstory: Proficient in translating complex narratives into engaging screenplay
|
||||
format.
|
||||
goal: Transform the storyline into a script
|
||||
role: Screenwriter
|
||||
- 'InternetSearchTool'
|
||||
content_creator:
|
||||
backstory: Skilled in writing informative and engaging content about AI News.
|
||||
goal: Create detailed reports on AI News
|
||||
role: Content Creator
|
||||
tasks:
|
||||
script_creation:
|
||||
description: Transform the developed storyline into a script for the movie
|
||||
about cats in Mars.
|
||||
expected_output: Complete script with dialogues, scenes, and stage directions
|
||||
ready for production.
|
||||
tools:
|
||||
- ''
|
||||
director:
|
||||
backstory: Experienced in visual storytelling and bringing scripts to life on
|
||||
screen.
|
||||
goal: Oversee the production of the movie
|
||||
role: Director
|
||||
tasks:
|
||||
movie_production:
|
||||
description: Take the script and lead the team to produce the movie 'Cats
|
||||
in Mars' based on the provided content and script.
|
||||
expected_output: Completed movie ready for distribution with compelling visuals
|
||||
and engaging storytelling.
|
||||
compile_report:
|
||||
description: Compile all gathered data into a detailed report with analysis
|
||||
and insights.
|
||||
expected_output: Well-structured report on the latest AI News with key insights.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
@@ -0,0 +1,42 @@
|
||||
framework: crewai
|
||||
topic: create a movie about cat in mars based on https://www.grammarly.com/blog/how-to-write-a-story/
|
||||
roles:
|
||||
story_developer:
|
||||
backstory: Experienced in crafting compelling narratives for a diverse audience.
|
||||
goal: Develop an engaging storyline for a movie about cats in Mars
|
||||
role: Story Developer
|
||||
tasks:
|
||||
storyline_creation:
|
||||
description: Create a captivating storyline for a movie about cats in Mars
|
||||
inspired by the blog post at https://www.grammarly.com/blog/how-to-write-a-story/
|
||||
expected_output: Detailed storyline with key plot points, character motivations,
|
||||
and setting descriptions.
|
||||
tools:
|
||||
- 'ScrapeWebsiteTool'
|
||||
screenwriter:
|
||||
backstory: Proficient in translating complex narratives into engaging screenplay
|
||||
format.
|
||||
goal: Transform the storyline into a script
|
||||
role: Screenwriter
|
||||
tasks:
|
||||
script_creation:
|
||||
description: Transform the developed storyline into a script for the movie
|
||||
about cats in Mars.
|
||||
expected_output: Complete script with dialogues, scenes, and stage directions
|
||||
ready for production.
|
||||
tools:
|
||||
- ''
|
||||
director:
|
||||
backstory: Experienced in visual storytelling and bringing scripts to life on
|
||||
screen.
|
||||
goal: Oversee the production of the movie
|
||||
role: Director
|
||||
tasks:
|
||||
movie_production:
|
||||
description: Take the script and lead the team to produce the movie 'Cats
|
||||
in Mars' based on the provided content and script.
|
||||
expected_output: Completed movie ready for distribution with compelling visuals
|
||||
and engaging storytelling.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
@@ -0,0 +1,26 @@
|
||||
framework: crewai
|
||||
topic: research about the latest AI News and prepare a detailed report
|
||||
roles:
|
||||
research_analyst:
|
||||
backstory: Experienced in gathering and analyzing data related to AI news trends.
|
||||
goal: Analyze AI News trends
|
||||
role: Research Analyst
|
||||
tasks:
|
||||
gather_data:
|
||||
description: Conduct in-depth research on the latest AI News trends from reputable
|
||||
sources.
|
||||
expected_output: Comprehensive report on current AI News trends.
|
||||
tools:
|
||||
- 'InternetSearchTool'
|
||||
content_creator:
|
||||
backstory: Skilled in writing informative and engaging content about AI News.
|
||||
goal: Create detailed reports on AI News
|
||||
role: Content Creator
|
||||
tasks:
|
||||
compile_report:
|
||||
description: Compile all gathered data into a detailed report with analysis
|
||||
and insights.
|
||||
expected_output: Well-structured report on the latest AI News with key insights.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
Generated
+955
-933
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,4 @@
|
||||
# agents_generator.py
|
||||
# praisonai/agents_generator.py
|
||||
|
||||
import sys
|
||||
from .version import __version__
|
||||
@@ -11,14 +11,49 @@ import autogen
|
||||
import gradio as gr
|
||||
import argparse
|
||||
from .auto import AutoGenerator
|
||||
from crewai_tools import *
|
||||
from .tools import *
|
||||
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
|
||||
|
||||
class AgentsGenerator:
|
||||
def __init__(self, agent_file, framework, config_list):
|
||||
self.agent_file = agent_file
|
||||
self.framework = framework
|
||||
self.config_list = config_list
|
||||
|
||||
def is_function_or_decorated(self, obj):
|
||||
return inspect.isfunction(obj) or hasattr(obj, '__call__')
|
||||
|
||||
def load_tools_from_module(self, module_path):
|
||||
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):
|
||||
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 issubclass(x, BaseTool) and x is not BaseTool)}
|
||||
|
||||
def load_tools_from_package(self, package_path):
|
||||
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):
|
||||
if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
|
||||
@@ -51,9 +86,19 @@ class AgentsGenerator:
|
||||
'WebsiteSearchTool': WebsiteSearchTool(),
|
||||
'XMLSearchTool': XMLSearchTool(),
|
||||
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
||||
'YoutubeVideoSearchTool': YoutubeVideoSearchTool()
|
||||
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
||||
}
|
||||
# config['tools'] = [tools_dict[tool] for tool in config.get('tools', []) if tool in tools_dict]
|
||||
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 = {}
|
||||
@@ -86,7 +131,12 @@ class AgentsGenerator:
|
||||
)
|
||||
for tool in details.get('tools', []):
|
||||
if tool in tools_dict:
|
||||
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
||||
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
|
||||
@@ -121,7 +171,6 @@ class AgentsGenerator:
|
||||
|
||||
task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
|
||||
tasks.append(task)
|
||||
# print(agents)
|
||||
crew = Crew(
|
||||
agents=list(agents.values()),
|
||||
tasks=tasks,
|
||||
@@ -130,92 +179,4 @@ class AgentsGenerator:
|
||||
|
||||
response = crew.kickoff()
|
||||
result = f"### Task Output ###\n{response}"
|
||||
return result
|
||||
|
||||
|
||||
# # AutoGen Tools example below
|
||||
# from typing import Any, Optional
|
||||
# import os
|
||||
# from autogen import ConversableAgent
|
||||
# from autogen_tools import autogen_ScrapeWebsiteTool
|
||||
|
||||
# assistant = ConversableAgent(
|
||||
# name="Assistant",
|
||||
# system_message="You are a helpful AI assistant. "
|
||||
# "You can help with website scraping. "
|
||||
# "Return 'TERMINATE' when the task is done.",
|
||||
# llm_config={"config_list": [{"model": "gpt-3.5-turbo", "api_key": os.environ["OPENAI_API_KEY"]}]},
|
||||
# )
|
||||
|
||||
# user_proxy = ConversableAgent(
|
||||
# name="User",
|
||||
# llm_config=False,
|
||||
# is_termination_msg=lambda msg: msg.get("content") is not None and "TERMINATE" in msg["content"],
|
||||
# human_input_mode="NEVER",
|
||||
# )
|
||||
|
||||
# autogen_ScrapeWebsiteTool(assistant, user_proxy)
|
||||
|
||||
# chat_result = user_proxy.initiate_chat(assistant, message="Scrape the official Nodejs website.")
|
||||
|
||||
# # CrewAI Tools example below
|
||||
# import os
|
||||
# from crewai import Agent, Task, Crew
|
||||
# # Importing crewAI tools
|
||||
# from crewai_tools import (
|
||||
# DirectoryReadTool,
|
||||
# FileReadTool,
|
||||
# SerperDevTool,
|
||||
# WebsiteSearchTool
|
||||
# )
|
||||
|
||||
# # Set up API keys
|
||||
# os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
|
||||
# os.environ["OPENAI_API_KEY"] = "Your Key"
|
||||
|
||||
# # Instantiate tools
|
||||
# docs_tool = DirectoryReadTool(directory='./blog-posts')
|
||||
# file_tool = FileReadTool()
|
||||
# search_tool = SerperDevTool()
|
||||
# web_rag_tool = WebsiteSearchTool()
|
||||
|
||||
# # Create agents
|
||||
# researcher = Agent(
|
||||
# role='Market Research Analyst',
|
||||
# goal='Provide up-to-date market analysis of the AI industry',
|
||||
# backstory='An expert analyst with a keen eye for market trends.',
|
||||
# tools=[search_tool, web_rag_tool],
|
||||
# verbose=True
|
||||
# )
|
||||
|
||||
# writer = Agent(
|
||||
# role='Content Writer',
|
||||
# goal='Craft engaging blog posts about the AI industry',
|
||||
# backstory='A skilled writer with a passion for technology.',
|
||||
# tools=[docs_tool, file_tool],
|
||||
# verbose=True
|
||||
# )
|
||||
|
||||
# # Define tasks
|
||||
# research = Task(
|
||||
# description='Research the latest trends in the AI industry and provide a summary.',
|
||||
# expected_output='A summary of the top 3 trending developments in the AI industry with a unique perspective on their significance.',
|
||||
# agent=researcher
|
||||
# )
|
||||
|
||||
# write = Task(
|
||||
# description='Write an engaging blog post about the AI industry, based on the research analyst’s summary. Draw inspiration from the latest blog posts in the directory.',
|
||||
# expected_output='A 4-paragraph blog post formatted in markdown with engaging, informative, and accessible content, avoiding complex jargon.',
|
||||
# agent=writer,
|
||||
# output_file='blog-posts/new_post.md' # The final blog post will be saved here
|
||||
# )
|
||||
|
||||
# # Assemble a crew
|
||||
# crew = Crew(
|
||||
# agents=[researcher, writer],
|
||||
# tasks=[research, write],
|
||||
# verbose=2
|
||||
# )
|
||||
|
||||
# # Execute tasks
|
||||
# crew.kickoff()
|
||||
return result
|
||||
+6
-51
@@ -12,8 +12,7 @@ import gradio as gr
|
||||
import argparse
|
||||
from .auto import AutoGenerator
|
||||
from .agents_generator import AgentsGenerator
|
||||
from crewai_tools import *
|
||||
from .tools import *
|
||||
from .inbuilt_tools import *
|
||||
|
||||
class PraisonAI:
|
||||
def __init__(self, agent_file="agents.yaml", framework="crewai", auto=False, init=False):
|
||||
@@ -41,21 +40,15 @@ class PraisonAI:
|
||||
return
|
||||
invocation_cmd = "praisonai"
|
||||
version_string = f"PraisonAI version {__version__}"
|
||||
|
||||
if args.framework:
|
||||
self.framework = args.framework
|
||||
|
||||
ui = args.ui
|
||||
|
||||
if args.agent_file:
|
||||
if args.agent_file == "tests.test": # Argument used for testing purposes
|
||||
full_path = os.path.abspath("agents.yaml")
|
||||
if args.agent_file.startswith("tests.test"): # Argument used for testing purposes
|
||||
print("test")
|
||||
else:
|
||||
full_path = os.path.abspath(args.agent_file)
|
||||
self.agent_file = full_path
|
||||
else:
|
||||
full_path = os.path.abspath(self.agent_file)
|
||||
self.agent_file = full_path
|
||||
self.agent_file = args.agent_file
|
||||
|
||||
|
||||
if args.auto or args.init:
|
||||
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
|
||||
@@ -86,7 +79,7 @@ class PraisonAI:
|
||||
|
||||
def parse_args(self):
|
||||
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
|
||||
parser.add_argument("--framework", choices=["crewai", "autogen"], default="crewai", help="Specify the framework")
|
||||
parser.add_argument("--framework", choices=["crewai", "autogen"], help="Specify the framework")
|
||||
parser.add_argument("--ui", action="store_true", help="Enable UI mode")
|
||||
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
||||
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
||||
@@ -124,41 +117,3 @@ class PraisonAI:
|
||||
if __name__ == "__main__":
|
||||
praison_ai = PraisonAI()
|
||||
praison_ai.main()
|
||||
|
||||
|
||||
|
||||
## agents.yaml
|
||||
# framework: autogen
|
||||
# topic: create movie script about cat in mars
|
||||
# roles:
|
||||
# concept_developer:
|
||||
# backstory: Experienced in creating captivating and original story concepts.
|
||||
# goal: Generate a unique concept for a movie script about a cat in Mars
|
||||
# role: Concept Developer
|
||||
# tools:
|
||||
# - search_tool
|
||||
# tasks:
|
||||
# concept_generation:
|
||||
# description: Develop a unique and engaging concept for a movie script about
|
||||
# a cat in Mars.
|
||||
# expected_output: A detailed concept document for the movie script.
|
||||
# scriptwriter:
|
||||
# backstory: Expert in dialogue and script structure, translating concepts into
|
||||
# scripts.
|
||||
# goal: Write a script based on the movie concept
|
||||
# role: Scriptwriter
|
||||
# tasks:
|
||||
# scriptwriting_task:
|
||||
# description: Turn the movie concept into a script, including dialogue and
|
||||
# scenes.
|
||||
# expected_output: A production-ready script for the movie about a cat in Mars.
|
||||
# director:
|
||||
# backstory: Experienced in visualizing scripts and creating compelling storyboards.
|
||||
# goal: Create a storyboard and visualize the script
|
||||
# role: Director
|
||||
# tasks:
|
||||
# storyboard_creation:
|
||||
# description: Create a storyboard for the movie script about a cat in Mars.
|
||||
# expected_output: A detailed storyboard for the movie about a cat in Mars.
|
||||
# dependencies: []
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==0.0.18 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==0.0.20 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# from .base_tool import BaseTool, Tool, tool
|
||||
from .autogen_tools import *
|
||||
@@ -1,3 +1,5 @@
|
||||
# praisonai/inbuilt_tools/autogen_tools.py
|
||||
|
||||
from crewai_tools import (
|
||||
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
||||
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
||||
@@ -6,6 +8,60 @@ from crewai_tools import (
|
||||
)
|
||||
from typing import Any
|
||||
from autogen import register_function
|
||||
import os
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
import os
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
def create_autogen_tool_function(tool_name):
|
||||
def autogen_tool(assistant, user_proxy):
|
||||
def register_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
||||
def tool_func(query: str) -> Any:
|
||||
tool_instance = tool_class()
|
||||
return tool_instance.run(query=query)
|
||||
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
||||
|
||||
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):
|
||||
print(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
|
||||
tool_module = importlib.import_module("tools")
|
||||
elif tools_dir_path.is_dir():
|
||||
print(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
|
||||
tool_module = importlib.import_module(f"tools.{tool_name}")
|
||||
else:
|
||||
raise ImportError("Neither tools.py nor tools directory found in the root directory.")
|
||||
|
||||
Tool = getattr(tool_module, tool_name)
|
||||
|
||||
register_tool(Tool, tool_name, f"Description for {tool_name}", assistant, user_proxy)
|
||||
|
||||
return autogen_tool
|
||||
|
||||
# Load tools.py
|
||||
sys.path.insert(0, os.getcwd())
|
||||
root_directory = os.getcwd()
|
||||
tools_py_path = os.path.join(root_directory, 'tools.py')
|
||||
tools_dir_path = Path(root_directory) / 'tools'
|
||||
|
||||
tools_module = None
|
||||
|
||||
if os.path.isfile(tools_py_path):
|
||||
print(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
|
||||
tools_module = importlib.import_module("tools")
|
||||
elif tools_dir_path.is_dir():
|
||||
print(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
|
||||
tools_module = importlib.import_module(f"tools.{tool_name}")
|
||||
|
||||
# Create autogen_TOOL_NAME_HERE function for each tool
|
||||
if tools_module is not None:
|
||||
for name, obj in inspect.getmembers(tools_module):
|
||||
if inspect.isclass(obj):
|
||||
globals()[f"autogen_{name}"] = create_autogen_tool_function(name)
|
||||
|
||||
def autogen_CodeDocsSearchTool(assistant, user_proxy):
|
||||
def register_code_docs_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
||||
@@ -1,2 +0,0 @@
|
||||
from .base_tool import BaseTool, Tool, tool
|
||||
from .autogen_tools import *
|
||||
@@ -1,146 +0,0 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Callable, Optional, Type
|
||||
|
||||
from langchain_core.tools import StructuredTool
|
||||
from pydantic import BaseModel, ConfigDict, Field, validator
|
||||
from pydantic.v1 import BaseModel as V1BaseModel
|
||||
|
||||
|
||||
class BaseTool(BaseModel, ABC):
|
||||
class _ArgsSchemaPlaceholder(V1BaseModel):
|
||||
pass
|
||||
|
||||
model_config = ConfigDict()
|
||||
|
||||
name: str
|
||||
"""The unique name of the tool that clearly communicates its purpose."""
|
||||
description: str
|
||||
"""Used to tell the model how/when/why to use the tool."""
|
||||
args_schema: Type[V1BaseModel] = Field(default_factory=_ArgsSchemaPlaceholder)
|
||||
"""The schema for the arguments that the tool accepts."""
|
||||
description_updated: bool = False
|
||||
"""Flag to check if the description has been updated."""
|
||||
cache_function: Optional[Callable] = lambda _args, _result: True
|
||||
"""Function that will be used to determine if the tool should be cached, should return a boolean. If None, the tool will be cached."""
|
||||
|
||||
@validator("args_schema", always=True, pre=True)
|
||||
def _default_args_schema(cls, v: Type[V1BaseModel]) -> Type[V1BaseModel]:
|
||||
if not isinstance(v, cls._ArgsSchemaPlaceholder):
|
||||
return v
|
||||
|
||||
return type(
|
||||
f"{cls.__name__}Schema",
|
||||
(V1BaseModel,),
|
||||
{
|
||||
"__annotations__": {
|
||||
k: v for k, v in cls._run.__annotations__.items() if k != "return"
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def model_post_init(self, __context: Any) -> None:
|
||||
self._generate_description()
|
||||
|
||||
super().model_post_init(__context)
|
||||
|
||||
def run(
|
||||
self,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
print(f"Using Tool: {self.name}")
|
||||
return self._run(*args, **kwargs)
|
||||
|
||||
@abstractmethod
|
||||
def _run(
|
||||
self,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
"""Here goes the actual implementation of the tool."""
|
||||
|
||||
def to_langchain(self) -> StructuredTool:
|
||||
self._set_args_schema()
|
||||
return StructuredTool(
|
||||
name=self.name,
|
||||
description=self.description,
|
||||
args_schema=self.args_schema,
|
||||
func=self._run,
|
||||
)
|
||||
|
||||
def _set_args_schema(self):
|
||||
if self.args_schema is None:
|
||||
class_name = f"{self.__class__.__name__}Schema"
|
||||
self.args_schema = type(
|
||||
class_name,
|
||||
(V1BaseModel,),
|
||||
{
|
||||
"__annotations__": {
|
||||
k: v
|
||||
for k, v in self._run.__annotations__.items()
|
||||
if k != "return"
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def _generate_description(self):
|
||||
args = []
|
||||
for arg, attribute in self.args_schema.schema()["properties"].items():
|
||||
if "type" in attribute:
|
||||
args.append(f"{arg}: '{attribute['type']}'")
|
||||
|
||||
description = self.description.replace("\n", " ")
|
||||
self.description = f"{self.name}({', '.join(args)}) - {description}"
|
||||
|
||||
|
||||
class Tool(BaseTool):
|
||||
func: Callable
|
||||
"""The function that will be executed when the tool is called."""
|
||||
|
||||
def _run(self, *args: Any, **kwargs: Any) -> Any:
|
||||
return self.func(*args, **kwargs)
|
||||
|
||||
|
||||
def to_langchain(
|
||||
tools: list[BaseTool | StructuredTool],
|
||||
) -> list[StructuredTool]:
|
||||
return [t.to_langchain() if isinstance(t, BaseTool) else t for t in tools]
|
||||
|
||||
|
||||
def tool(*args):
|
||||
"""
|
||||
Decorator to create a tool from a function.
|
||||
"""
|
||||
|
||||
def _make_with_name(tool_name: str) -> Callable:
|
||||
def _make_tool(f: Callable) -> BaseTool:
|
||||
if f.__doc__ is None:
|
||||
raise ValueError("Function must have a docstring")
|
||||
if f.__annotations__ is None:
|
||||
raise ValueError("Function must have type annotations")
|
||||
|
||||
class_name = "".join(tool_name.split()).title()
|
||||
args_schema = type(
|
||||
class_name,
|
||||
(V1BaseModel,),
|
||||
{
|
||||
"__annotations__": {
|
||||
k: v for k, v in f.__annotations__.items() if k != "return"
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return Tool(
|
||||
name=tool_name,
|
||||
description=f.__doc__,
|
||||
func=f,
|
||||
args_schema=args_schema,
|
||||
)
|
||||
|
||||
return _make_tool
|
||||
|
||||
if len(args) == 1 and callable(args[0]):
|
||||
return _make_with_name(args[0].__name__)(args[0])
|
||||
if len(args) == 1 and isinstance(args[0], str):
|
||||
return _make_with_name(args[0])
|
||||
raise ValueError("Invalid arguments")
|
||||
@@ -1,116 +0,0 @@
|
||||
from crewai_tools import (
|
||||
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
||||
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
||||
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
|
||||
YoutubeVideoSearchTool
|
||||
)
|
||||
import inspect
|
||||
|
||||
# Assuming the tool classes are imported correctly as in the original request
|
||||
|
||||
tools_classes = {
|
||||
'CodeDocsSearchTool': CodeDocsSearchTool,
|
||||
'CSVSearchTool': CSVSearchTool,
|
||||
'DirectorySearchTool': DirectorySearchTool,
|
||||
'DOCXSearchTool': DOCXSearchTool,
|
||||
'DirectoryReadTool': DirectoryReadTool,
|
||||
'FileReadTool': FileReadTool,
|
||||
'TXTSearchTool': TXTSearchTool,
|
||||
'JSONSearchTool': JSONSearchTool,
|
||||
'MDXSearchTool': MDXSearchTool,
|
||||
'PDFSearchTool': PDFSearchTool,
|
||||
'RagTool': RagTool,
|
||||
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool,
|
||||
'ScrapeWebsiteTool': ScrapeWebsiteTool,
|
||||
'WebsiteSearchTool': WebsiteSearchTool,
|
||||
'XMLSearchTool': XMLSearchTool,
|
||||
'YoutubeChannelSearchTool': YoutubeChannelSearchTool,
|
||||
'YoutubeVideoSearchTool': YoutubeVideoSearchTool,
|
||||
}
|
||||
|
||||
for tool_name, tool_class in tools_classes.items():
|
||||
# Inspect the constructor (__init__) to get its parameters, excluding 'self'
|
||||
constructor_params = inspect.signature(tool_class.__init__).parameters
|
||||
param_names = [p for p in constructor_params if p != 'self']
|
||||
|
||||
# Attempt to instantiate the tool with dummy or default values for parameters
|
||||
try:
|
||||
# Creating a dummy parameters dict with None or empty values based on parameter name
|
||||
dummy_params = {param: None if param != 'website_url' else 'http://example.com' for param in param_names}
|
||||
instance = tool_class(**dummy_params)
|
||||
tool_description = getattr(instance, "description", "No description attribute")
|
||||
except Exception as e:
|
||||
tool_description = f"Error instantiating tool for description extraction: {str(e)}"
|
||||
|
||||
# Printing tool class name, its constructor parameters, and description
|
||||
print(f"Tool Class: {tool_name}")
|
||||
print(f"Constructor Parameters: {', '.join(param_names)}")
|
||||
print(f"Description: {tool_description}\n")
|
||||
|
||||
# Tool Class: CodeDocsSearchTool
|
||||
# Constructor Parameters: docs_url, kwargs
|
||||
# Description: Search a Code Docs content(search_query: 'string', docs_url: 'string') - A tool that can be used to semantic search a query from a Code Docs content.
|
||||
|
||||
# Tool Class: CSVSearchTool
|
||||
# Constructor Parameters: csv, kwargs
|
||||
# Description: Search a CSV's content(search_query: 'string', csv: 'string') - A tool that can be used to semantic search a query from a CSV's content.
|
||||
|
||||
# Tool Class: DirectorySearchTool
|
||||
# Constructor Parameters: directory, kwargs
|
||||
# Description: Search a directory's content(search_query: 'string', directory: 'string') - A tool that can be used to semantic search a query from a directory's content.
|
||||
|
||||
# Tool Class: DOCXSearchTool
|
||||
# Constructor Parameters: docx, kwargs
|
||||
# Description: Search a DOCX's content(search_query: 'string', docx: 'string') - A tool that can be used to semantic search a query from a DOCX's content.
|
||||
|
||||
# Tool Class: DirectoryReadTool
|
||||
# Constructor Parameters: directory, kwargs
|
||||
# Description: List files in directory(directory: 'string') - A tool that can be used to recursively list a directory's content.
|
||||
|
||||
# Tool Class: FileReadTool
|
||||
# Constructor Parameters: file_path, kwargs
|
||||
# Description: Read a file's content(file_path: 'string') - A tool that can be used to read a file's content.
|
||||
|
||||
# Tool Class: TXTSearchTool
|
||||
# Constructor Parameters: txt, kwargs
|
||||
# Description: Search a txt's content(search_query: 'string', txt: 'string') - A tool that can be used to semantic search a query from a txt's content.
|
||||
|
||||
# Tool Class: JSONSearchTool
|
||||
# Constructor Parameters: json_path, kwargs
|
||||
# Description: Search a JSON's content(search_query: 'string', json_path: 'string') - A tool that can be used to semantic search a query from a JSON's content.
|
||||
|
||||
# Tool Class: MDXSearchTool
|
||||
# Constructor Parameters: mdx, kwargs
|
||||
# Description: Search a MDX's content(search_query: 'string', mdx: 'string') - A tool that can be used to semantic search a query from a MDX's content.
|
||||
|
||||
# Tool Class: PDFSearchTool
|
||||
# Constructor Parameters: pdf, kwargs
|
||||
# Description: Search a PDF's content(query: 'string', pdf: 'string') - A tool that can be used to semantic search a query from a PDF's content.
|
||||
|
||||
# Tool Class: RagTool
|
||||
# Constructor Parameters: data
|
||||
# Description: Knowledge base(query: 'string') - A knowledge base that can be used to answer questions.
|
||||
|
||||
# Tool Class: ScrapeElementFromWebsiteTool
|
||||
# Constructor Parameters: website_url, cookies, css_element, kwargs
|
||||
# Description: Read a website content() - A tool that can be used to read http://example.com's content.
|
||||
|
||||
# Tool Class: ScrapeWebsiteTool
|
||||
# Constructor Parameters: website_url, cookies, kwargs
|
||||
# Description: Read website content() - A tool that can be used to read http://example.com's content.
|
||||
|
||||
# Tool Class: WebsiteSearchTool
|
||||
# Constructor Parameters: website, kwargs
|
||||
# Description: Search in a specific website(search_query: 'string', website: 'string') - A tool that can be used to semantic search a query from a specific URL content.
|
||||
|
||||
# Tool Class: XMLSearchTool
|
||||
# Constructor Parameters: xml, kwargs
|
||||
# Description: Search a XML's content(search_query: 'string', xml: 'string') - A tool that can be used to semantic search a query from a XML's content.
|
||||
|
||||
# Tool Class: YoutubeChannelSearchTool
|
||||
# Constructor Parameters: youtube_channel_handle, kwargs
|
||||
# Description: Search a Youtube Channels content(search_query: 'string', youtube_channel_handle: 'string') - A tool that can be used to semantic search a query from a Youtube Channels content.
|
||||
|
||||
# Tool Class: YoutubeVideoSearchTool
|
||||
# Constructor Parameters: youtube_video_url, kwargs
|
||||
# Description: Search a Youtube Video content(search_query: 'string', youtube_video_url: 'string') - A tool that can be used to semantic search a query from a Youtube Video content.
|
||||
@@ -1,38 +0,0 @@
|
||||
from typing import Any, Optional
|
||||
import os
|
||||
from autogen import ConversableAgent
|
||||
from scrape_website_tool.scrape_website_tool import ScrapeWebsiteTool
|
||||
|
||||
assistant = ConversableAgent(
|
||||
name="Assistant",
|
||||
system_message="You are a helpful AI assistant. "
|
||||
"You can help with website scraping. "
|
||||
"Return 'TERMINATE' when the task is done.",
|
||||
llm_config={"config_list": [{"model": "gpt-3.5-turbo", "api_key": os.environ["OPENAI_API_KEY"]}]},
|
||||
)
|
||||
|
||||
user_proxy = ConversableAgent(
|
||||
name="User",
|
||||
llm_config=False,
|
||||
is_termination_msg=lambda msg: msg.get("content") is not None and "TERMINATE" in msg["content"],
|
||||
human_input_mode="NEVER",
|
||||
)
|
||||
|
||||
from autogen import register_function
|
||||
from typing import Any
|
||||
|
||||
def register_tool(tool_class, tool_name, tool_description):
|
||||
def tool_func(website_url: str) -> Any:
|
||||
tool_instance = tool_class(website_url=website_url)
|
||||
return tool_instance.run()
|
||||
|
||||
register_function(
|
||||
tool_func,
|
||||
caller=assistant, # The assistant agent can suggest calls to the tool.
|
||||
executor=user_proxy, # The user proxy agent can execute the tool calls.
|
||||
name=tool_name, # By default, the function name is used as the tool name.
|
||||
description=tool_description, # A description of the tool.
|
||||
)
|
||||
register_tool(ScrapeWebsiteTool, "scrape_website_tool", "A tool for scraping specific websites")
|
||||
|
||||
chat_result = user_proxy.initiate_chat(assistant, message="Scrape the official Nodejs website.")
|
||||
@@ -1,35 +0,0 @@
|
||||
from typing import Any, Optional
|
||||
import os
|
||||
from autogen import ConversableAgent
|
||||
from scrape_website_tool.scrape_website_tool import ScrapeWebsiteTool
|
||||
|
||||
def scrape_website_tool(website_url: str) -> Any:
|
||||
scrape_tool = ScrapeWebsiteTool(website_url=website_url)
|
||||
return scrape_tool.run()
|
||||
|
||||
assistant = ConversableAgent(
|
||||
name="Assistant",
|
||||
system_message="You are a helpful AI assistant. "
|
||||
"You can help with website scraping. "
|
||||
"Return 'TERMINATE' when the task is done.",
|
||||
llm_config={"config_list": [{"model": "gpt-3.5-turbo", "api_key": os.environ["OPENAI_API_KEY"]}]},
|
||||
)
|
||||
|
||||
user_proxy = ConversableAgent(
|
||||
name="User",
|
||||
llm_config=False,
|
||||
is_termination_msg=lambda msg: msg.get("content") is not None and "TERMINATE" in msg["content"],
|
||||
human_input_mode="NEVER",
|
||||
)
|
||||
|
||||
from autogen import register_function
|
||||
# Register the ScrapeWebsiteTool function to the agent and user proxy to add a website scraping tool.
|
||||
register_function(
|
||||
scrape_website_tool,
|
||||
caller=assistant, # The assistant agent can suggest calls to the scrape website tool.
|
||||
executor=user_proxy, # The user proxy agent can execute the scrape website tool calls.
|
||||
name="scrape_website_tool", # By default, the function name is used as the tool name.
|
||||
description="A tool for scraping specific websites", # A description of the tool.
|
||||
)
|
||||
|
||||
chat_result = user_proxy.initiate_chat(assistant, message="Scrape the official Python website.")
|
||||
@@ -1,23 +0,0 @@
|
||||
from typing import Any, Optional
|
||||
import os
|
||||
from autogen import ConversableAgent
|
||||
from autogen_tools import autogen_ScrapeWebsiteTool
|
||||
|
||||
assistant = ConversableAgent(
|
||||
name="Assistant",
|
||||
system_message="You are a helpful AI assistant. "
|
||||
"You can help with website scraping. "
|
||||
"Return 'TERMINATE' when the task is done.",
|
||||
llm_config={"config_list": [{"model": "gpt-3.5-turbo", "api_key": os.environ["OPENAI_API_KEY"]}]},
|
||||
)
|
||||
|
||||
user_proxy = ConversableAgent(
|
||||
name="User",
|
||||
llm_config=False,
|
||||
is_termination_msg=lambda msg: msg.get("content") is not None and "TERMINATE" in msg["content"],
|
||||
human_input_mode="NEVER",
|
||||
)
|
||||
|
||||
autogen_ScrapeWebsiteTool(assistant, user_proxy)
|
||||
|
||||
chat_result = user_proxy.initiate_chat(assistant, message="Scrape the official Nodejs website.")
|
||||
@@ -1,134 +0,0 @@
|
||||
|
||||
import os
|
||||
from crewai import Agent, Task, Crew
|
||||
from crewai_tools import (
|
||||
DirectoryReadTool,
|
||||
FileReadTool,
|
||||
SerperDevTool,
|
||||
WebsiteSearchTool
|
||||
)
|
||||
|
||||
os.environ["SERPER_API_KEY"] = "Your Key"
|
||||
os.environ["OPENAI_API_KEY"] = "Your Key"
|
||||
|
||||
docs_tool = DirectoryReadTool(directory='./blog-posts')
|
||||
file_tool = FileReadTool()
|
||||
search_tool = SerperDevTool()
|
||||
web_rag_tool = WebsiteSearchTool()
|
||||
|
||||
researcher = Agent(
|
||||
role='Market Research Analyst',
|
||||
goal='Provide up-to-date market analysis of the AI industry',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[search_tool, web_rag_tool],
|
||||
verbose=True
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role='Content Writer',
|
||||
goal='Craft engaging blog posts about the AI industry',
|
||||
backstory='A skilled writer with a passion for technology.',
|
||||
tools=[docs_tool, file_tool],
|
||||
verbose=True
|
||||
)
|
||||
|
||||
research = Task(
|
||||
description='Research the latest trends in the AI industry and provide a summary.',
|
||||
expected_output='A summary of the top 3 trending developments in the AI industry with a unique perspective on their significance.',
|
||||
agent=researcher
|
||||
)
|
||||
|
||||
write = Task(
|
||||
description='Write an engaging blog post about the AI industry, based on the research analyst\'s summary. Draw inspiration from the latest blog posts in the directory.',
|
||||
expected_output='A 4-paragraph blog post formatted in markdown with engaging, informative, and accessible content, avoiding complex jargon.',
|
||||
agent=writer,
|
||||
output_file='blog-posts/new_post.md'
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research, write],
|
||||
verbose=2
|
||||
)
|
||||
|
||||
crew.kickoff()
|
||||
|
||||
from crewai_tools import DirectoryReadTool
|
||||
|
||||
tool = DirectoryReadTool()
|
||||
|
||||
toos = DirectoryReadTool(directory='./directory')
|
||||
|
||||
from crewai_tools import BaseTool
|
||||
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
|
||||
def _run(self, argument: str) -> str:
|
||||
return "Result from custom tool"
|
||||
|
||||
from crewai_tools import tool
|
||||
|
||||
@tool("Name of my tool")
|
||||
def my_tool(question: str) -> str:
|
||||
return "Result from my tool"
|
||||
|
||||
import json
|
||||
import requests
|
||||
from crewai import Agent
|
||||
from crewai.tools import tool
|
||||
from unstructured.partition.html import partition_html
|
||||
|
||||
@tool("Integration with a given API")
|
||||
def integration_tool(argument: str) -> str:
|
||||
return "Results from integration tool"
|
||||
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[integration_tool]
|
||||
)
|
||||
|
||||
from crewai import Agent
|
||||
from langchain.agents import Tool
|
||||
from langchain.utilities import GoogleSerperAPIWrapper
|
||||
|
||||
os.environ["SERPER_API_KEY"] = "Your Key"
|
||||
|
||||
search = GoogleSerperAPIWrapper()
|
||||
|
||||
serper_tool = Tool(
|
||||
name="Intermediate Answer",
|
||||
func=search.run,
|
||||
description="Useful for search-based queries",
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[serper_tool]
|
||||
)
|
||||
# Tool Description
|
||||
# CodeDocsSearchTool A RAG tool optimized for searching through code documentation and related technical documents.
|
||||
# CSVSearchTool A RAG tool designed for searching within CSV files, tailored to handle structured data.
|
||||
# DirectorySearchTool A RAG tool for searching within directories, useful for navigating through file systems.
|
||||
# DOCXSearchTool A RAG tool aimed at searching within DOCX documents, ideal for processing Word files.
|
||||
# DirectoryReadTool Facilitates reading and processing of directory structures and their contents.
|
||||
# FileReadTool Enables reading and extracting data from files, supporting various file formats.
|
||||
# GithubSearchTool A RAG tool for searching within GitHub repositories, useful for code and documentation search.
|
||||
# SeperDevTool A specialized tool for development purposes, with specific functionalities under development.
|
||||
# TXTSearchTool A RAG tool focused on searching within text (.txt) files, suitable for unstructured data.
|
||||
# JSONSearchTool A RAG tool designed for searching within JSON files, catering to structured data handling.
|
||||
# MDXSearchTool A RAG tool tailored for searching within Markdown (MDX) files, useful for documentation.
|
||||
# PDFSearchTool A RAG tool aimed at searching within PDF documents, ideal for processing scanned documents.
|
||||
# PGSearchTool A RAG tool optimized for searching within PostgreSQL databases, suitable for database queries.
|
||||
# RagTool A general-purpose RAG tool capable of handling various data sources and types.
|
||||
# ScrapeElementFromWebsiteTool Enables scraping specific elements from websites, useful for targeted data extraction.
|
||||
# ScrapeWebsiteTool Facilitates scraping entire websites, ideal for comprehensive data collection.
|
||||
# WebsiteSearchTool A RAG tool for searching website content, optimized for web data extraction.
|
||||
# XMLSearchTool A RAG tool designed for searching within XML files, suitable for structured data formats.
|
||||
# YoutubeChannelSearchTool A RAG tool for searching within YouTube channels, useful for video content analysis.
|
||||
# YoutubeVideoSearchTool A RAG tool aimed at searching within YouTube videos, ideal for video data extraction.
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "praisonAI"
|
||||
version = "0.0.18"
|
||||
version = "0.0.20"
|
||||
description = "praisonAI application combines AutoGen and CrewAI or similar frameworks into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customization, and efficient human-agent collaboration."
|
||||
authors = ["Mervin Praison"]
|
||||
license = ""
|
||||
@@ -22,6 +22,7 @@ gradio = ">=4.20.0"
|
||||
Flask = ">=3.0.0"
|
||||
markdown = ">=3.5"
|
||||
crewai-tools = "^0.1.1"
|
||||
praisonai-tools = ">=0.0.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^8.0.0"
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
rich>=13.7
|
||||
pyautogen>=0.2.19
|
||||
crewai>=0.22.5
|
||||
gradio>=4.20.0
|
||||
gradio>=4.20.0
|
||||
crewai_tools
|
||||
duckduckgo_search
|
||||
praisonai_tools
|
||||
@@ -17,4 +17,14 @@ elif [ "$1" = "openai" ] || [ -z "$1" ]; then
|
||||
export OPENAI_API_BASE=https://api.openai.com/v1
|
||||
export OPENAI_API_KEY=$(echo $OAI_API_KEY)
|
||||
echo "OpenAI configuration initiated with model $MODEL_NAME."
|
||||
elif [ "$1" = "ollama" ]; then
|
||||
# Check for a second argument for the model name, default to a custom model if not provided
|
||||
MODEL_NAME=${2:-default-ollama-model}
|
||||
# Set environment variables for Ollama local configuration with dynamic model name
|
||||
export OPENAI_MODEL_NAME=$MODEL_NAME
|
||||
export OPENAI_API_BASE=http://127.0.0.1:11434
|
||||
export OPENAI_API_KEY=$(echo $OLLAMA_API_KEY)
|
||||
# Set up SSH public key
|
||||
export SSH_PUBLIC_KEY="ssh-ed25519 AAAA..."
|
||||
echo "Ollama local model configuration initiated with model $MODEL_NAME.
|
||||
fi
|
||||
@@ -5,7 +5,8 @@ def advanced():
|
||||
agent_file="agents.yaml",
|
||||
framework="autogen",
|
||||
)
|
||||
praison_ai.main()
|
||||
print(praison_ai)
|
||||
return praison_ai.main()
|
||||
|
||||
if __name__ == "__main__":
|
||||
advanced()
|
||||
print(advanced())
|
||||
@@ -6,7 +6,7 @@ def auto():
|
||||
framework="autogen"
|
||||
)
|
||||
print(praison_ai.framework)
|
||||
praison_ai.main()
|
||||
return praison_ai.main()
|
||||
|
||||
if __name__ == "__main__":
|
||||
auto()
|
||||
print(auto())
|
||||
@@ -2,7 +2,7 @@ from praisonai import PraisonAI
|
||||
|
||||
def main():
|
||||
praison_ai = PraisonAI(agent_file="agents.yaml")
|
||||
praison_ai.main()
|
||||
return praison_ai.main()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print(main())
|
||||
@@ -0,0 +1,42 @@
|
||||
framework: crewai
|
||||
topic: create a movie about cat in mars based on https://blog.celtx.com/how-to-write-a-good-story/
|
||||
roles:
|
||||
story_developer:
|
||||
backstory: Experienced in crafting compelling narratives for a diverse audience.
|
||||
goal: Develop an engaging storyline for a movie about cats in Mars
|
||||
role: Story Developer
|
||||
tasks:
|
||||
storyline_creation:
|
||||
description: Create a captivating storyline for a movie about cats in Mars
|
||||
inspired by the blog post at https://blog.celtx.com/how-to-write-a-good-story/
|
||||
expected_output: Detailed storyline with key plot points, character motivations,
|
||||
and setting descriptions.
|
||||
tools:
|
||||
- ScrapeWebsiteTool
|
||||
screenwriter:
|
||||
backstory: Proficient in translating complex narratives into engaging screenplay
|
||||
format.
|
||||
goal: Transform the storyline into a script
|
||||
role: Screenwriter
|
||||
tasks:
|
||||
script_creation:
|
||||
description: Transform the developed storyline into a script for the movie
|
||||
about cats in Mars.
|
||||
expected_output: Complete script with dialogues, scenes, and stage directions
|
||||
ready for production.
|
||||
tools:
|
||||
- ''
|
||||
director:
|
||||
backstory: Experienced in visual storytelling and bringing scripts to life on
|
||||
screen.
|
||||
goal: Oversee the production of the movie
|
||||
role: Director
|
||||
tasks:
|
||||
movie_production:
|
||||
description: Take the script and lead the team to produce the movie 'Cats
|
||||
in Mars' based on the provided content and script.
|
||||
expected_output: Completed movie ready for distribution with compelling visuals
|
||||
and engaging storytelling.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
@@ -0,0 +1,42 @@
|
||||
framework: crewai
|
||||
topic: create a movie about cat in mars
|
||||
roles:
|
||||
story_developer:
|
||||
backstory: Experienced in crafting compelling narratives for a diverse audience.
|
||||
goal: Develop an engaging storyline for a movie about cats in Mars
|
||||
role: Story Developer
|
||||
tasks:
|
||||
storyline_creation:
|
||||
description: Create a captivating storyline for a movie about cats in Mars.
|
||||
Use Internet Search Tool to understand the latest story writing ideas.
|
||||
expected_output: Detailed storyline with key plot points, character motivations,
|
||||
and setting descriptions.
|
||||
tools:
|
||||
- internet_search_tool
|
||||
screenwriter:
|
||||
backstory: Proficient in translating complex narratives into engaging screenplay
|
||||
format.
|
||||
goal: Transform the storyline into a script
|
||||
role: Screenwriter
|
||||
tasks:
|
||||
script_creation:
|
||||
description: Transform the developed storyline into a script for the movie
|
||||
about cats in Mars.
|
||||
expected_output: Complete script with dialogues, scenes, and stage directions
|
||||
ready for production.
|
||||
tools:
|
||||
- ''
|
||||
director:
|
||||
backstory: Experienced in visual storytelling and bringing scripts to life on
|
||||
screen.
|
||||
goal: Oversee the production of the movie
|
||||
role: Director
|
||||
tasks:
|
||||
movie_production:
|
||||
description: Take the script and lead the team to produce the movie 'Cats
|
||||
in Mars' based on the provided content and script.
|
||||
expected_output: Completed movie ready for distribution with compelling visuals
|
||||
and engaging storytelling.
|
||||
tools:
|
||||
- ''
|
||||
dependencies: []
|
||||
@@ -41,4 +41,4 @@ register_function(
|
||||
description="A simple calculator", # A description of the tool.
|
||||
)
|
||||
|
||||
chat_result = user_proxy.initiate_chat(assistant, message="What is (44232 + 13312 / (232 - 32)) * 5?")
|
||||
chat_result = user_proxy.initiate_chat(assistant, message="What is (44232 + 13312 / (232 - 32)) * 5?")
|
||||
@@ -0,0 +1,99 @@
|
||||
import math
|
||||
import os
|
||||
from typing import Optional, Type
|
||||
|
||||
# Starndard Langchain example
|
||||
from langchain.agents import create_spark_sql_agent
|
||||
from langchain.agents.agent_toolkits import SparkSQLToolkit
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
# Import things that are needed generically
|
||||
from langchain.pydantic_v1 import BaseModel, Field
|
||||
from langchain.tools import BaseTool
|
||||
from langchain.tools.file_management.read import ReadFileTool
|
||||
from langchain.utilities.spark_sql import SparkSQL
|
||||
|
||||
import autogen
|
||||
|
||||
class CircumferenceToolInput(BaseModel):
|
||||
radius: float = Field()
|
||||
|
||||
|
||||
class CircumferenceTool(BaseTool):
|
||||
name = "circumference_calculator"
|
||||
description = "Use this tool when you need to calculate a circumference using the radius of a circle"
|
||||
args_schema: Type[BaseModel] = CircumferenceToolInput
|
||||
|
||||
def _run(self, radius: float):
|
||||
return float(radius) * 2.0 * math.pi
|
||||
|
||||
|
||||
def get_file_path_of_example():
|
||||
current_dir = os.path.dirname(__file__)
|
||||
file_path = os.path.join(current_dir, "radius.txt")
|
||||
return file_path
|
||||
|
||||
# Define a function to generate llm_config from a LangChain tool
|
||||
def generate_llm_config(tool):
|
||||
# Define the function schema based on the tool's args_schema
|
||||
function_schema = {
|
||||
"name": tool.name.lower().replace(" ", "_"),
|
||||
"description": tool.description,
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
},
|
||||
}
|
||||
|
||||
if tool.args is not None:
|
||||
function_schema["parameters"]["properties"] = tool.args
|
||||
|
||||
return function_schema
|
||||
|
||||
|
||||
# Instantiate the ReadFileTool
|
||||
read_file_tool = ReadFileTool()
|
||||
custom_tool = CircumferenceTool()
|
||||
|
||||
# Construct the llm_config
|
||||
llm_config = {
|
||||
# Generate functions config for the Tool
|
||||
"functions": [
|
||||
generate_llm_config(custom_tool),
|
||||
generate_llm_config(read_file_tool),
|
||||
],
|
||||
"config_list": [{"model": "gpt-3.5-turbo", "api_key": os.environ["OPENAI_API_KEY"]}],
|
||||
"timeout": 120,
|
||||
}
|
||||
|
||||
user_proxy = autogen.UserProxyAgent(
|
||||
name="user_proxy",
|
||||
is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
|
||||
human_input_mode="NEVER",
|
||||
max_consecutive_auto_reply=10,
|
||||
code_execution_config={
|
||||
"work_dir": "coding",
|
||||
"use_docker": False,
|
||||
}, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.
|
||||
)
|
||||
|
||||
# Register the tool and start the conversation
|
||||
user_proxy.register_function(
|
||||
function_map={
|
||||
custom_tool.name: custom_tool._run,
|
||||
read_file_tool.name: read_file_tool._run,
|
||||
}
|
||||
)
|
||||
|
||||
chatbot = autogen.AssistantAgent(
|
||||
name="chatbot",
|
||||
system_message="For coding tasks, only use the functions you have been provided with. Reply TERMINATE when the task is done.",
|
||||
llm_config=llm_config,
|
||||
)
|
||||
|
||||
user_proxy.initiate_chat(
|
||||
chatbot,
|
||||
message=f"Read the file with the path {get_file_path_of_example()}, then calculate the circumference of a circle that has a radius of that files contents.", # 7.81mm in the file
|
||||
llm_config=llm_config,
|
||||
)
|
||||
@@ -0,0 +1,71 @@
|
||||
import os
|
||||
from crewai import Agent, Task, Crew
|
||||
from duckduckgo_search import DDGS
|
||||
from langchain.tools import tool
|
||||
|
||||
@tool("Internet Search Tool")
|
||||
def internet_search_tool(query: str) -> list:
|
||||
"""Search Internet for relevant information based on a query."""
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
|
||||
# Define agents
|
||||
researcher = Agent(
|
||||
role='Researcher',
|
||||
goal='Gather and analyze information on specific topics',
|
||||
verbose=True,
|
||||
backstory=(
|
||||
"As a seasoned researcher, you have a keen eye for detail and a "
|
||||
"deep understanding of your field. You're adept at sifting through "
|
||||
"information to find the most relevant and accurate data."
|
||||
),
|
||||
tools=[internet_search_tool],
|
||||
allow_delegation=True
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role='Writer',
|
||||
goal='Compose informative and engaging articles based on research findings',
|
||||
verbose=True,
|
||||
backstory=(
|
||||
"With a talent for storytelling, you translate complex ideas into "
|
||||
"clear, compelling narratives. Your articles are well-researched, "
|
||||
"thought-provoking, and accessible to a broad audience."
|
||||
),
|
||||
tools=[internet_search_tool],
|
||||
allow_delegation=False
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
research_task = Task(
|
||||
description=(
|
||||
"Investigate the latest trends in renewable energy technologies. "
|
||||
"Identify key advancements, challenges, and potential impacts on "
|
||||
"global energy policies."
|
||||
),
|
||||
expected_output='A detailed report summarizing the findings.',
|
||||
tools=[internet_search_tool],
|
||||
agent=researcher,
|
||||
)
|
||||
|
||||
writing_task = Task(
|
||||
description=(
|
||||
"Based on the research findings, write an article that highlights "
|
||||
"the importance of renewable energy innovations. The article should "
|
||||
"educate the public on how these technologies can contribute to "
|
||||
"sustainable development."
|
||||
),
|
||||
expected_output='An engaging and informative article suitable for publication.',
|
||||
tools=[internet_search_tool],
|
||||
agent=writer,
|
||||
)
|
||||
|
||||
# Create and kick off the crew
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, writing_task]
|
||||
)
|
||||
|
||||
result = crew.kickoff(inputs={'topic': 'renewable energy'})
|
||||
print(result)
|
||||
@@ -0,0 +1 @@
|
||||
7.81mm
|
||||
+38
-22
@@ -1,47 +1,63 @@
|
||||
# tests/test.py
|
||||
# from .debug import * # Uncomment this line to import the debug.py file for debugging
|
||||
import unittest
|
||||
import os
|
||||
import subprocess
|
||||
from praisonai.cli import PraisonAI
|
||||
from .advanced_example import advanced
|
||||
from .basic_example import main
|
||||
from .auto_example import auto
|
||||
|
||||
class TestGenerateCrewAndKickoff(unittest.TestCase):
|
||||
def test_generate_crew_and_kickoff_with_autogen_framework(self):
|
||||
class TestPraisonAIFramework(unittest.TestCase):
|
||||
def test_main_with_autogen_framework(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/autogen-agents.yaml')
|
||||
result = praison_ai.generate_crew_and_kickoff()
|
||||
# Assert the result
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
def test_generate_crew_and_kickoff_with_custom_framework(self):
|
||||
def test_main_with_custom_framework(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/crewai-agents.yaml')
|
||||
result = praison_ai.generate_crew_and_kickoff()
|
||||
# Assert the result
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
class TestPraisonAICommand(unittest.TestCase):
|
||||
|
||||
def test_main_with_internet_search_tool(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/search-tool-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
def test_main_with_built_in_tool(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/inbuilt-tool-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
class TestPraisonAICommandLine(unittest.TestCase):
|
||||
def run_command(self, command):
|
||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, text=True)
|
||||
return result.stdout
|
||||
|
||||
def test_praisonai_command(self):
|
||||
command = "praisonai --framework autogen --auto create movie script about cat in mars"
|
||||
result = os.popen(command).read()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
class TestPraisonAIInitCommand(unittest.TestCase):
|
||||
result = self.run_command(command)
|
||||
self.assertIn('TERMINATE', result)
|
||||
|
||||
def test_praisonai_init_command(self):
|
||||
command = "praisonai --framework autogen --init create movie script about cat in mars"
|
||||
result = os.popen(command).read()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
result = self.run_command(command)
|
||||
self.assertIn('created successfully', result)
|
||||
|
||||
class TestBasicExample(unittest.TestCase):
|
||||
class TestExamples(unittest.TestCase):
|
||||
def test_basic_example(self):
|
||||
main()
|
||||
# Assuming main() has been adjusted to return a value for assertion
|
||||
result = main()
|
||||
self.assertIsNotNone(result) # Adjust this assertion based on the expected outcome of main()
|
||||
|
||||
class TestAdvancedExample(unittest.TestCase):
|
||||
def test_advanced_example(self):
|
||||
advanced()
|
||||
|
||||
class TestAutoExample(unittest.TestCase):
|
||||
# Assuming advanced() returns a value suitable for assertion
|
||||
result = advanced()
|
||||
self.assertIsNotNone(result) # Adjust this assertion as needed
|
||||
|
||||
def test_auto_example(self):
|
||||
auto()
|
||||
# Assuming auto() returns a value that can be asserted
|
||||
result = auto()
|
||||
self.assertIsNotNone(result) # Adjust this assertion according to what auto() is expected to do
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,25 @@
|
||||
# tests/test_agents_playbook.py
|
||||
import unittest
|
||||
import subprocess
|
||||
from praisonai import PraisonAI
|
||||
|
||||
class TestPraisonAIFramework(unittest.TestCase):
|
||||
def test_main_with_autogen_framework(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/autogen-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
def test_main_with_custom_framework(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/crewai-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
def test_main_with_internet_search_tool(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/search-tool-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
|
||||
def test_main_with_built_in_tool(self):
|
||||
praison_ai = PraisonAI(agent_file='tests/inbuilt-tool-agents.yaml')
|
||||
result = praison_ai.main()
|
||||
self.assertIn('### Task Output ###', result)
|
||||
Whitespace-only changes.
@@ -0,0 +1,9 @@
|
||||
from duckduckgo_search import DDGS
|
||||
from langchain.tools import tool
|
||||
|
||||
@tool("Internet Search Tool")
|
||||
def internet_search_tool(query: str) -> list:
|
||||
"""Search Internet for relevant information based on a query."""
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
@@ -1,8 +1,12 @@
|
||||
# tools.py
|
||||
from duckduckgo_search import DDGS
|
||||
from praisonai_tools import BaseTool
|
||||
|
||||
@tool("Internet Search Tool")
|
||||
def internet_search_tool(query: str) -> list:
|
||||
"""Search Internet for relevant information based on a query."""
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
class InternetSearchTool(BaseTool):
|
||||
name: str = "InternetSearchTool"
|
||||
description: str = "Search Internet for relevant information based on a query or latest news"
|
||||
|
||||
def _run(self, query: str):
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
Whitespace-only changes.
@@ -0,0 +1,11 @@
|
||||
from duckduckgo_search import DDGS
|
||||
from praisonai_tools import BaseTool
|
||||
|
||||
class InternetSearchTool(BaseTool):
|
||||
name: str = "Internet Search Tool"
|
||||
description: str = "Search Internet for relevant information based on a query or latest news"
|
||||
|
||||
def _run(self, query: str):
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
Reference in new issue
Block a user