PraisonAI 0.0.1__py3-none-any.whl → 0.0.22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PraisonAI might be problematic. Click here for more details.
- praisonai/__init__.py +2 -0
- praisonai/__main__.py +10 -0
- praisonai/agents_generator.py +272 -0
- praisonai/auto.py +186 -0
- praisonai/cli.py +198 -0
- praisonai/deploy.py +138 -0
- praisonai/inbuilt_tools/__init__.py +2 -0
- praisonai/inbuilt_tools/autogen_tools.py +203 -0
- {praisonAI → praisonai}/test.py +12 -1
- praisonai-0.0.22.dist-info/LICENSE +20 -0
- praisonai-0.0.22.dist-info/METADATA +314 -0
- praisonai-0.0.22.dist-info/RECORD +15 -0
- {praisonAI-0.0.1.dist-info → praisonai-0.0.22.dist-info}/WHEEL +1 -2
- praisonai-0.0.22.dist-info/entry_points.txt +3 -0
- praisonAI/__init__.py +0 -1
- praisonAI/__main__.py +0 -4
- praisonAI/cli.py +0 -114
- praisonAI-0.0.1.dist-info/METADATA +0 -22
- praisonAI-0.0.1.dist-info/RECORD +0 -9
- praisonAI-0.0.1.dist-info/top_level.txt +0 -1
- {praisonAI → praisonai}/version.py +0 -0
praisonai/__init__.py
ADDED
praisonai/__main__.py
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# praisonai/agents_generator.py
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from .version import __version__
|
|
5
|
+
import yaml, os
|
|
6
|
+
from rich import print
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
from crewai import Agent, Task, Crew
|
|
9
|
+
from crewai.telemetry import Telemetry
|
|
10
|
+
load_dotenv()
|
|
11
|
+
import autogen
|
|
12
|
+
import gradio as gr
|
|
13
|
+
import argparse
|
|
14
|
+
from .auto import AutoGenerator
|
|
15
|
+
from crewai_tools import (
|
|
16
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
|
17
|
+
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
|
18
|
+
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
|
|
19
|
+
YoutubeVideoSearchTool
|
|
20
|
+
)
|
|
21
|
+
from .inbuilt_tools import *
|
|
22
|
+
import inspect
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
import importlib
|
|
25
|
+
import importlib.util
|
|
26
|
+
from praisonai_tools import BaseTool
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
os.environ["OTEL_SDK_DISABLED"] = "true"
|
|
30
|
+
|
|
31
|
+
def noop(*args, **kwargs):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
def disable_crewai_telemetry():
|
|
35
|
+
for attr in dir(Telemetry):
|
|
36
|
+
if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
|
|
37
|
+
setattr(Telemetry, attr, noop)
|
|
38
|
+
|
|
39
|
+
disable_crewai_telemetry()
|
|
40
|
+
|
|
41
|
+
class AgentsGenerator:
|
|
42
|
+
def __init__(self, agent_file, framework, config_list):
|
|
43
|
+
"""
|
|
44
|
+
Initialize the AgentsGenerator object.
|
|
45
|
+
|
|
46
|
+
Parameters:
|
|
47
|
+
agent_file (str): The path to the agent file.
|
|
48
|
+
framework (str): The framework to be used for the agents.
|
|
49
|
+
config_list (list): A list of configurations for the agents.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
agent_file (str): The path to the agent file.
|
|
53
|
+
framework (str): The framework to be used for the agents.
|
|
54
|
+
config_list (list): A list of configurations for the agents.
|
|
55
|
+
"""
|
|
56
|
+
self.agent_file = agent_file
|
|
57
|
+
self.framework = framework
|
|
58
|
+
self.config_list = config_list
|
|
59
|
+
|
|
60
|
+
def is_function_or_decorated(self, obj):
|
|
61
|
+
"""
|
|
62
|
+
Checks if the given object is a function or has a __call__ method.
|
|
63
|
+
|
|
64
|
+
Parameters:
|
|
65
|
+
obj (object): The object to be checked.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
bool: True if the object is a function or has a __call__ method, False otherwise.
|
|
69
|
+
"""
|
|
70
|
+
return inspect.isfunction(obj) or hasattr(obj, '__call__')
|
|
71
|
+
|
|
72
|
+
def load_tools_from_module(self, module_path):
|
|
73
|
+
"""
|
|
74
|
+
Loads tools from a specified module path.
|
|
75
|
+
|
|
76
|
+
Parameters:
|
|
77
|
+
module_path (str): The path to the module containing the tools.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
FileNotFoundError: If the specified module path does not exist.
|
|
84
|
+
"""
|
|
85
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
86
|
+
module = importlib.util.module_from_spec(spec)
|
|
87
|
+
spec.loader.exec_module(module)
|
|
88
|
+
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
|
|
89
|
+
|
|
90
|
+
def load_tools_from_module_class(self, module_path):
|
|
91
|
+
"""
|
|
92
|
+
Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
|
|
93
|
+
|
|
94
|
+
Parameters:
|
|
95
|
+
module_path (str): The path to the module containing the tools.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
FileNotFoundError: If the specified module path does not exist.
|
|
102
|
+
"""
|
|
103
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
104
|
+
module = importlib.util.module_from_spec(spec)
|
|
105
|
+
spec.loader.exec_module(module)
|
|
106
|
+
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)}
|
|
107
|
+
|
|
108
|
+
def load_tools_from_package(self, package_path):
|
|
109
|
+
"""
|
|
110
|
+
Loads tools from a specified package path containing modules with functions or classes.
|
|
111
|
+
|
|
112
|
+
Parameters:
|
|
113
|
+
package_path (str): The path to the package containing the tools.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
|
|
117
|
+
|
|
118
|
+
Raises:
|
|
119
|
+
FileNotFoundError: If the specified package path does not exist.
|
|
120
|
+
|
|
121
|
+
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.
|
|
122
|
+
"""
|
|
123
|
+
tools_dict = {}
|
|
124
|
+
for module_file in os.listdir(package_path):
|
|
125
|
+
if module_file.endswith('.py') and not module_file.startswith('__'):
|
|
126
|
+
module_name = f"{package_path.name}.{module_file[:-3]}" # Remove .py for import
|
|
127
|
+
module = importlib.import_module(module_name)
|
|
128
|
+
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
|
|
129
|
+
tools_dict[name] = obj
|
|
130
|
+
return tools_dict
|
|
131
|
+
|
|
132
|
+
def generate_crew_and_kickoff(self):
|
|
133
|
+
"""
|
|
134
|
+
Generates a crew of agents and initiates tasks based on the provided configuration.
|
|
135
|
+
|
|
136
|
+
Parameters:
|
|
137
|
+
agent_file (str): The path to the agent file.
|
|
138
|
+
framework (str): The framework to be used for the agents.
|
|
139
|
+
config_list (list): A list of configurations for the agents.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
str: The output of the tasks performed by the crew of agents.
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
FileNotFoundError: If the specified agent file does not exist.
|
|
146
|
+
|
|
147
|
+
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.
|
|
148
|
+
"""
|
|
149
|
+
if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
|
|
150
|
+
self.agent_file = 'agents.yaml'
|
|
151
|
+
try:
|
|
152
|
+
with open(self.agent_file, 'r') as f:
|
|
153
|
+
config = yaml.safe_load(f)
|
|
154
|
+
except FileNotFoundError:
|
|
155
|
+
print(f"File not found: {self.agent_file}")
|
|
156
|
+
return
|
|
157
|
+
|
|
158
|
+
topic = config['topic']
|
|
159
|
+
tools_dict = {
|
|
160
|
+
'CodeDocsSearchTool': CodeDocsSearchTool(),
|
|
161
|
+
'CSVSearchTool': CSVSearchTool(),
|
|
162
|
+
'DirectorySearchTool': DirectorySearchTool(),
|
|
163
|
+
'DOCXSearchTool': DOCXSearchTool(),
|
|
164
|
+
'DirectoryReadTool': DirectoryReadTool(),
|
|
165
|
+
'FileReadTool': FileReadTool(),
|
|
166
|
+
# 'GithubSearchTool': GithubSearchTool(),
|
|
167
|
+
# 'SeperDevTool': SeperDevTool(),
|
|
168
|
+
'TXTSearchTool': TXTSearchTool(),
|
|
169
|
+
'JSONSearchTool': JSONSearchTool(),
|
|
170
|
+
'MDXSearchTool': MDXSearchTool(),
|
|
171
|
+
'PDFSearchTool': PDFSearchTool(),
|
|
172
|
+
# 'PGSearchTool': PGSearchTool(),
|
|
173
|
+
'RagTool': RagTool(),
|
|
174
|
+
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
|
|
175
|
+
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
|
|
176
|
+
'WebsiteSearchTool': WebsiteSearchTool(),
|
|
177
|
+
'XMLSearchTool': XMLSearchTool(),
|
|
178
|
+
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
|
179
|
+
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
|
180
|
+
}
|
|
181
|
+
root_directory = os.getcwd()
|
|
182
|
+
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
183
|
+
tools_dir_path = Path(root_directory) / 'tools'
|
|
184
|
+
|
|
185
|
+
if os.path.isfile(tools_py_path):
|
|
186
|
+
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
|
|
187
|
+
# print("tools.py exists in the root directory. Loading tools.py and skipping tools folder.")
|
|
188
|
+
elif tools_dir_path.is_dir():
|
|
189
|
+
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
|
|
190
|
+
# print("tools folder exists in the root directory")
|
|
191
|
+
|
|
192
|
+
framework = self.framework or config.get('framework')
|
|
193
|
+
|
|
194
|
+
agents = {}
|
|
195
|
+
tasks = []
|
|
196
|
+
if framework == "autogen":
|
|
197
|
+
# Load the LLM configuration dynamically
|
|
198
|
+
# print(self.config_list)
|
|
199
|
+
llm_config = {"config_list": self.config_list}
|
|
200
|
+
|
|
201
|
+
# Assuming the user proxy agent is set up as per your requirements
|
|
202
|
+
user_proxy = autogen.UserProxyAgent(
|
|
203
|
+
name="User",
|
|
204
|
+
human_input_mode="NEVER",
|
|
205
|
+
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
206
|
+
code_execution_config={
|
|
207
|
+
"work_dir": "coding",
|
|
208
|
+
"use_docker": False,
|
|
209
|
+
},
|
|
210
|
+
# additional setup for the user proxy agent
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
for role, details in config['roles'].items():
|
|
214
|
+
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
|
|
215
|
+
agent_goal = details['goal'].format(topic=topic)
|
|
216
|
+
# Creating an AssistantAgent for each role dynamically
|
|
217
|
+
agents[role] = autogen.AssistantAgent(
|
|
218
|
+
name=agent_name,
|
|
219
|
+
llm_config=llm_config,
|
|
220
|
+
system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
221
|
+
)
|
|
222
|
+
for tool in details.get('tools', []):
|
|
223
|
+
if tool in tools_dict:
|
|
224
|
+
try:
|
|
225
|
+
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
|
226
|
+
print(f"Found {tool_class.__name__} for {tool}")
|
|
227
|
+
except KeyError:
|
|
228
|
+
print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
|
|
229
|
+
continue
|
|
230
|
+
tool_class(agents[role], user_proxy)
|
|
231
|
+
|
|
232
|
+
# Preparing tasks for initiate_chats
|
|
233
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
234
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
235
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
236
|
+
|
|
237
|
+
chat_task = {
|
|
238
|
+
"recipient": agents[role],
|
|
239
|
+
"message": description_filled,
|
|
240
|
+
"summary_method": "last_msg",
|
|
241
|
+
# Additional fields like carryover can be added based on dependencies
|
|
242
|
+
}
|
|
243
|
+
tasks.append(chat_task)
|
|
244
|
+
|
|
245
|
+
response = user_proxy.initiate_chats(tasks)
|
|
246
|
+
result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
247
|
+
else:
|
|
248
|
+
for role, details in config['roles'].items():
|
|
249
|
+
role_filled = details['role'].format(topic=topic)
|
|
250
|
+
goal_filled = details['goal'].format(topic=topic)
|
|
251
|
+
backstory_filled = details['backstory'].format(topic=topic)
|
|
252
|
+
|
|
253
|
+
# Adding tools to the agent if exists
|
|
254
|
+
agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
|
|
255
|
+
agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, tools=agent_tools, allow_delegation=False)
|
|
256
|
+
agents[role] = agent
|
|
257
|
+
|
|
258
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
259
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
260
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
261
|
+
|
|
262
|
+
task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
|
|
263
|
+
tasks.append(task)
|
|
264
|
+
crew = Crew(
|
|
265
|
+
agents=list(agents.values()),
|
|
266
|
+
tasks=tasks,
|
|
267
|
+
verbose=2
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
response = crew.kickoff()
|
|
271
|
+
result = f"### Task Output ###\n{response}"
|
|
272
|
+
return result
|
praisonai/auto.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from openai import OpenAI
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
from typing import Dict, List
|
|
4
|
+
import instructor
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
import yaml
|
|
8
|
+
from rich import print
|
|
9
|
+
|
|
10
|
+
# Define Pydantic models outside of the generate method
|
|
11
|
+
class TaskDetails(BaseModel):
|
|
12
|
+
description: str
|
|
13
|
+
expected_output: str
|
|
14
|
+
|
|
15
|
+
class RoleDetails(BaseModel):
|
|
16
|
+
role: str
|
|
17
|
+
goal: str
|
|
18
|
+
backstory: str
|
|
19
|
+
tasks: Dict[str, TaskDetails]
|
|
20
|
+
tools: List[str]
|
|
21
|
+
|
|
22
|
+
class TeamStructure(BaseModel):
|
|
23
|
+
roles: Dict[str, RoleDetails]
|
|
24
|
+
|
|
25
|
+
class AutoGenerator:
|
|
26
|
+
def __init__(self, topic="Movie Story writing about AI", agent_file="test.yaml", framework="crewai"):
|
|
27
|
+
"""
|
|
28
|
+
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
|
|
29
|
+
note: autogen framework is different from this AutoGenerator class.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
topic (str, optional): The topic for the generated team structure. Defaults to "Movie Story writing about AI".
|
|
33
|
+
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to "test.yaml".
|
|
34
|
+
framework (str, optional): The framework for the generated team structure. Defaults to "crewai".
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
config_list (list): A list containing the configuration details for the OpenAI API.
|
|
38
|
+
topic (str): The specified topic for the generated team structure.
|
|
39
|
+
agent_file (str): The specified name of the YAML file to save the generated team structure.
|
|
40
|
+
framework (str): The specified framework for the generated team structure.
|
|
41
|
+
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
|
|
42
|
+
"""
|
|
43
|
+
self.config_list = [
|
|
44
|
+
{
|
|
45
|
+
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"),
|
|
46
|
+
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
self.topic = topic
|
|
50
|
+
self.agent_file = agent_file
|
|
51
|
+
self.framework = framework or "crewai"
|
|
52
|
+
self.client = instructor.patch(
|
|
53
|
+
OpenAI(
|
|
54
|
+
base_url=self.config_list[0]['base_url'],
|
|
55
|
+
api_key=os.getenv("OPENAI_API_KEY"),
|
|
56
|
+
),
|
|
57
|
+
mode=instructor.Mode.JSON,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def generate(self):
|
|
61
|
+
"""
|
|
62
|
+
Generates a team structure for the specified topic.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
None
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
str: The full path of the YAML file containing the generated team structure.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
Exception: If the generation process fails.
|
|
72
|
+
|
|
73
|
+
Usage:
|
|
74
|
+
generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
|
|
75
|
+
path = generator.generate()
|
|
76
|
+
print(path)
|
|
77
|
+
"""
|
|
78
|
+
response = self.client.chat.completions.create(
|
|
79
|
+
model=self.config_list[0]['model'],
|
|
80
|
+
response_model=TeamStructure,
|
|
81
|
+
max_retries=10,
|
|
82
|
+
messages=[
|
|
83
|
+
{"role": "system", "content": "You are a helpful assistant designed to output complex team structures."},
|
|
84
|
+
{"role": "user", "content": self.get_user_content()}
|
|
85
|
+
]
|
|
86
|
+
)
|
|
87
|
+
json_data = json.loads(response.model_dump_json())
|
|
88
|
+
self.convert_and_save(json_data)
|
|
89
|
+
full_path = os.path.abspath(self.agent_file)
|
|
90
|
+
return full_path
|
|
91
|
+
|
|
92
|
+
def convert_and_save(self, json_data):
|
|
93
|
+
"""Converts the provided JSON data into the desired YAML format and saves it to a file.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
json_data (dict): The JSON data representing the team structure.
|
|
97
|
+
topic (str, optional): The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".
|
|
98
|
+
agent_file (str, optional): The name of the YAML file to save. Defaults to "test.yaml".
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
yaml_data = {
|
|
102
|
+
"framework": self.framework,
|
|
103
|
+
"topic": self.topic,
|
|
104
|
+
"roles": {},
|
|
105
|
+
"dependencies": []
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for role_id, role_details in json_data['roles'].items():
|
|
109
|
+
yaml_data['roles'][role_id] = {
|
|
110
|
+
"backstory": "" + role_details['backstory'],
|
|
111
|
+
"goal": role_details['goal'],
|
|
112
|
+
"role": role_details['role'],
|
|
113
|
+
"tasks": {},
|
|
114
|
+
# "tools": role_details.get('tools', []),
|
|
115
|
+
"tools": ['']
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for task_id, task_details in role_details['tasks'].items():
|
|
119
|
+
yaml_data['roles'][role_id]['tasks'][task_id] = {
|
|
120
|
+
"description": "" + task_details['description'],
|
|
121
|
+
"expected_output": "" + task_details['expected_output']
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Save to YAML file, maintaining the order
|
|
125
|
+
with open(self.agent_file, 'w') as f:
|
|
126
|
+
yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
|
|
127
|
+
|
|
128
|
+
def get_user_content(self):
|
|
129
|
+
"""
|
|
130
|
+
Generates a prompt for the OpenAI API to generate a team structure.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
None
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
str: The prompt for the OpenAI API.
|
|
137
|
+
|
|
138
|
+
Usage:
|
|
139
|
+
generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
|
|
140
|
+
prompt = generator.get_user_content()
|
|
141
|
+
print(prompt)
|
|
142
|
+
"""
|
|
143
|
+
user_content = """Generate a team structure for \"""" + self.topic + """\" task.
|
|
144
|
+
No Input data will be provided to the team.
|
|
145
|
+
The team will work in sequence. First role will pass the output to the next role, and so on.
|
|
146
|
+
The last role will generate the final output.
|
|
147
|
+
Think step by step.
|
|
148
|
+
With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
|
|
149
|
+
List of Available Tools: CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool, YoutubeVideoSearchTool.
|
|
150
|
+
Only use Available Tools. Do Not use any other tools.
|
|
151
|
+
Example Below:
|
|
152
|
+
Use below example to understand the structure of the output.
|
|
153
|
+
The final role you create should satisfy the provided task: """ + self.topic + """.
|
|
154
|
+
{
|
|
155
|
+
"roles": {
|
|
156
|
+
"narrative_designer": {
|
|
157
|
+
"role": "Narrative Designer",
|
|
158
|
+
"goal": "Create AI storylines",
|
|
159
|
+
"backstory": "Skilled in narrative development for AI, with a focus on story resonance.",
|
|
160
|
+
"tools": ["ScrapeWebsiteTool"],
|
|
161
|
+
"tasks": {
|
|
162
|
+
"story_concept_development": {
|
|
163
|
+
"description": "Craft a unique AI story concept with depth and engagement using concept from this page the content https://www.asthebirdfliesblog.com/posts/how-to-write-book-story-development .",
|
|
164
|
+
"expected_output": "Document with narrative arcs, character bios, and settings."
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"scriptwriter": {
|
|
169
|
+
"role": "Scriptwriter",
|
|
170
|
+
"goal": "Write scripts from AI concepts",
|
|
171
|
+
"backstory": "Expert in dialogue and script structure, translating concepts into scripts.",
|
|
172
|
+
"tasks": {
|
|
173
|
+
"scriptwriting_task": {
|
|
174
|
+
"description": "Turn narrative concepts into scripts, including dialogue and scenes.",
|
|
175
|
+
"expected_output": "Production-ready script with dialogue and scene details."
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
"""
|
|
182
|
+
return user_content
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
|
|
186
|
+
# print(generator.generate())
|
praisonai/cli.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# praisonai/cli.py
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from .version import __version__
|
|
5
|
+
import yaml, os
|
|
6
|
+
from rich import print
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
from crewai import Agent, Task, Crew
|
|
9
|
+
load_dotenv()
|
|
10
|
+
import autogen
|
|
11
|
+
import gradio as gr
|
|
12
|
+
import argparse
|
|
13
|
+
from .auto import AutoGenerator
|
|
14
|
+
from .agents_generator import AgentsGenerator
|
|
15
|
+
from .inbuilt_tools import *
|
|
16
|
+
|
|
17
|
+
class PraisonAI:
|
|
18
|
+
def __init__(self, agent_file="agents.yaml", framework="", auto=False, init=False):
|
|
19
|
+
"""
|
|
20
|
+
Initialize the PraisonAI object with default parameters.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
agent_file (str): The default agent file to use. Defaults to "agents.yaml".
|
|
24
|
+
framework (str): The default framework to use. Defaults to "crewai".
|
|
25
|
+
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
|
|
26
|
+
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
config_list (list): A list of configuration dictionaries for the OpenAI API.
|
|
30
|
+
agent_file (str): The agent file to use.
|
|
31
|
+
framework (str): The framework to use.
|
|
32
|
+
auto (bool): A flag indicating whether to enable auto mode.
|
|
33
|
+
init (bool): A flag indicating whether to enable initialization mode.
|
|
34
|
+
"""
|
|
35
|
+
self.config_list = [
|
|
36
|
+
{
|
|
37
|
+
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"),
|
|
38
|
+
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
self.agent_file = agent_file
|
|
42
|
+
self.framework = framework
|
|
43
|
+
self.auto = auto
|
|
44
|
+
self.init = init
|
|
45
|
+
|
|
46
|
+
def main(self):
|
|
47
|
+
"""
|
|
48
|
+
The main function of the PraisonAI object. It parses the command-line arguments,
|
|
49
|
+
initializes the necessary attributes, and then calls the appropriate methods based on the
|
|
50
|
+
provided arguments.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Any: Depending on the arguments provided, the function may return a result from the
|
|
57
|
+
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
|
|
58
|
+
the successful creation of a file.
|
|
59
|
+
"""
|
|
60
|
+
args = self.parse_args()
|
|
61
|
+
if args is None:
|
|
62
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
63
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
64
|
+
return result
|
|
65
|
+
if args.deploy:
|
|
66
|
+
from .deploy import CloudDeployer
|
|
67
|
+
deployer = CloudDeployer()
|
|
68
|
+
deployer.run_commands()
|
|
69
|
+
return
|
|
70
|
+
invocation_cmd = "praisonai"
|
|
71
|
+
version_string = f"PraisonAI version {__version__}"
|
|
72
|
+
|
|
73
|
+
self.framework = args.framework or self.framework
|
|
74
|
+
|
|
75
|
+
ui = args.ui
|
|
76
|
+
if args.agent_file:
|
|
77
|
+
if args.agent_file.startswith("tests.test"): # Argument used for testing purposes
|
|
78
|
+
print("test")
|
|
79
|
+
else:
|
|
80
|
+
self.agent_file = args.agent_file
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if args.auto or args.init:
|
|
84
|
+
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
|
|
85
|
+
self.topic = temp_topic
|
|
86
|
+
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
|
|
87
|
+
self.topic = self.auto
|
|
88
|
+
|
|
89
|
+
if args.auto or self.auto:
|
|
90
|
+
self.agent_file = "test.yaml"
|
|
91
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
92
|
+
self.agent_file = generator.generate()
|
|
93
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
94
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
95
|
+
return result
|
|
96
|
+
elif args.init or self.init:
|
|
97
|
+
self.agent_file = "agents.yaml"
|
|
98
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
99
|
+
self.agent_file = generator.generate()
|
|
100
|
+
print("File {} created successfully".format(self.agent_file))
|
|
101
|
+
return "File {} created successfully".format(self.agent_file)
|
|
102
|
+
|
|
103
|
+
if ui:
|
|
104
|
+
self.create_gradio_interface()
|
|
105
|
+
else:
|
|
106
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
107
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
108
|
+
return result
|
|
109
|
+
|
|
110
|
+
def parse_args(self):
|
|
111
|
+
"""
|
|
112
|
+
Parse the command-line arguments for the PraisonAI CLI.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
argparse.Namespace: An object containing the parsed command-line arguments.
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
argparse.ArgumentError: If the arguments provided are invalid.
|
|
122
|
+
|
|
123
|
+
Example:
|
|
124
|
+
>>> args = praison_ai.parse_args()
|
|
125
|
+
>>> print(args.agent_file) # Output: 'agents.yaml'
|
|
126
|
+
"""
|
|
127
|
+
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
|
|
128
|
+
parser.add_argument("--framework", choices=["crewai", "autogen"], help="Specify the framework")
|
|
129
|
+
parser.add_argument("--ui", action="store_true", help="Enable UI mode")
|
|
130
|
+
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
131
|
+
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
132
|
+
parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
|
|
133
|
+
parser.add_argument("--deploy", action="store_true", help="Deploy the application") # New argument
|
|
134
|
+
|
|
135
|
+
args, unknown_args = parser.parse_known_args()
|
|
136
|
+
|
|
137
|
+
if unknown_args and unknown_args[0] == '-b' and unknown_args[1] == 'api:app':
|
|
138
|
+
args.agent_file = 'agents.yaml'
|
|
139
|
+
if args.agent_file == 'api:app' or args.agent_file == '/app/api:app':
|
|
140
|
+
args.agent_file = 'agents.yaml'
|
|
141
|
+
|
|
142
|
+
return args
|
|
143
|
+
|
|
144
|
+
def create_gradio_interface(self):
|
|
145
|
+
"""
|
|
146
|
+
Create a Gradio interface for generating agents and performing tasks.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
None: This method does not return any value. It launches the Gradio interface.
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
None: This method does not raise any exceptions.
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
>>> praison_ai.create_gradio_interface()
|
|
159
|
+
"""
|
|
160
|
+
def generate_crew_and_kickoff_interface(auto_args, framework):
|
|
161
|
+
"""
|
|
162
|
+
Generate a crew and kick off tasks based on the provided auto arguments and framework.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
auto_args (list): Topic.
|
|
166
|
+
framework (str): The framework to use for generating agents.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
str: A string representing the result of generating the crew and kicking off tasks.
|
|
170
|
+
|
|
171
|
+
Raises:
|
|
172
|
+
None: This method does not raise any exceptions.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> result = generate_crew_and_kickoff_interface("Create a movie about Cat in Mars", "crewai")
|
|
176
|
+
>>> print(result)
|
|
177
|
+
"""
|
|
178
|
+
self.framework = framework
|
|
179
|
+
self.agent_file = "test.yaml"
|
|
180
|
+
generator = AutoGenerator(topic=auto_args , framework=self.framework)
|
|
181
|
+
self.agent_file = generator.generate()
|
|
182
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
183
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
184
|
+
return result
|
|
185
|
+
|
|
186
|
+
gr.Interface(
|
|
187
|
+
fn=generate_crew_and_kickoff_interface,
|
|
188
|
+
inputs=[gr.Textbox(lines=2, label="Auto Args"), gr.Dropdown(choices=["crewai", "autogen"], label="Framework")],
|
|
189
|
+
outputs="textbox",
|
|
190
|
+
title="Praison AI Studio",
|
|
191
|
+
description="Create Agents and perform tasks",
|
|
192
|
+
theme="default"
|
|
193
|
+
).launch()
|
|
194
|
+
|
|
195
|
+
if __name__ == "__main__":
|
|
196
|
+
praison_ai = PraisonAI()
|
|
197
|
+
praison_ai.main()
|
|
198
|
+
|