PraisonAI 0.0.17__tar.gz → 0.0.19__tar.gz
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.
- {praisonai-0.0.17 → praisonai-0.0.19}/PKG-INFO +3 -2
- praisonai-0.0.19/praisonai/agents_generator.py +182 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/auto.py +14 -8
- praisonai-0.0.19/praisonai/cli.py +119 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/deploy.py +1 -1
- praisonai-0.0.19/praisonai/inbuilt_tools/__init__.py +2 -0
- praisonai-0.0.19/praisonai/inbuilt_tools/autogen_tools.py +201 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/pyproject.toml +5 -6
- praisonai-0.0.17/praisonai/cli.py +0 -202
- {praisonai-0.0.17 → praisonai-0.0.19}/README.md +0 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/__init__.py +0 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/__main__.py +0 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/test.py +0 -0
- {praisonai-0.0.17 → praisonai-0.0.19}/praisonai/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: praisonAI
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.19
|
|
4
4
|
Summary: 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.
|
|
5
5
|
Author: Mervin Praison
|
|
6
6
|
Requires-Python: >=3.10,<3.13
|
|
@@ -8,11 +8,12 @@ Classifier: Programming Language :: Python :: 3
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
-
Provides-Extra: tools
|
|
12
11
|
Requires-Dist: Flask (>=3.0.0)
|
|
13
12
|
Requires-Dist: crewai (>=0.22.5)
|
|
13
|
+
Requires-Dist: crewai-tools (>=0.1.1,<0.2.0)
|
|
14
14
|
Requires-Dist: gradio (>=4.20.0)
|
|
15
15
|
Requires-Dist: markdown (>=3.5)
|
|
16
|
+
Requires-Dist: praisonai-tools (>=0.0.4)
|
|
16
17
|
Requires-Dist: pyautogen (>=0.2.19)
|
|
17
18
|
Requires-Dist: rich (>=13.7)
|
|
18
19
|
Project-URL: Homepage, https://github.com/mervinpraison/praisonAI
|
|
@@ -0,0 +1,182 @@
|
|
|
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
|
+
load_dotenv()
|
|
10
|
+
import autogen
|
|
11
|
+
import gradio as gr
|
|
12
|
+
import argparse
|
|
13
|
+
from .auto import AutoGenerator
|
|
14
|
+
from crewai_tools import (
|
|
15
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
|
16
|
+
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
|
17
|
+
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
|
|
18
|
+
YoutubeVideoSearchTool
|
|
19
|
+
)
|
|
20
|
+
from .inbuilt_tools import *
|
|
21
|
+
import inspect
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
import importlib
|
|
24
|
+
import importlib.util
|
|
25
|
+
from praisonai_tools import BaseTool
|
|
26
|
+
|
|
27
|
+
class AgentsGenerator:
|
|
28
|
+
def __init__(self, agent_file, framework, config_list):
|
|
29
|
+
self.agent_file = agent_file
|
|
30
|
+
self.framework = framework
|
|
31
|
+
self.config_list = config_list
|
|
32
|
+
|
|
33
|
+
def is_function_or_decorated(self, obj):
|
|
34
|
+
return inspect.isfunction(obj) or hasattr(obj, '__call__')
|
|
35
|
+
|
|
36
|
+
def load_tools_from_module(self, module_path):
|
|
37
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
38
|
+
module = importlib.util.module_from_spec(spec)
|
|
39
|
+
spec.loader.exec_module(module)
|
|
40
|
+
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
|
|
41
|
+
|
|
42
|
+
def load_tools_from_module_class(self, module_path):
|
|
43
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
44
|
+
module = importlib.util.module_from_spec(spec)
|
|
45
|
+
spec.loader.exec_module(module)
|
|
46
|
+
return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and issubclass(x, BaseTool) and x is not BaseTool)}
|
|
47
|
+
|
|
48
|
+
def load_tools_from_package(self, package_path):
|
|
49
|
+
tools_dict = {}
|
|
50
|
+
for module_file in os.listdir(package_path):
|
|
51
|
+
if module_file.endswith('.py') and not module_file.startswith('__'):
|
|
52
|
+
module_name = f"{package_path.name}.{module_file[:-3]}" # Remove .py for import
|
|
53
|
+
module = importlib.import_module(module_name)
|
|
54
|
+
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
|
|
55
|
+
tools_dict[name] = obj
|
|
56
|
+
return tools_dict
|
|
57
|
+
|
|
58
|
+
def generate_crew_and_kickoff(self):
|
|
59
|
+
if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
|
|
60
|
+
self.agent_file = 'agents.yaml'
|
|
61
|
+
try:
|
|
62
|
+
with open(self.agent_file, 'r') as f:
|
|
63
|
+
config = yaml.safe_load(f)
|
|
64
|
+
except FileNotFoundError:
|
|
65
|
+
print(f"File not found: {self.agent_file}")
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
topic = config['topic']
|
|
69
|
+
tools_dict = {
|
|
70
|
+
'CodeDocsSearchTool': CodeDocsSearchTool(),
|
|
71
|
+
'CSVSearchTool': CSVSearchTool(),
|
|
72
|
+
'DirectorySearchTool': DirectorySearchTool(),
|
|
73
|
+
'DOCXSearchTool': DOCXSearchTool(),
|
|
74
|
+
'DirectoryReadTool': DirectoryReadTool(),
|
|
75
|
+
'FileReadTool': FileReadTool(),
|
|
76
|
+
# 'GithubSearchTool': GithubSearchTool(),
|
|
77
|
+
# 'SeperDevTool': SeperDevTool(),
|
|
78
|
+
'TXTSearchTool': TXTSearchTool(),
|
|
79
|
+
'JSONSearchTool': JSONSearchTool(),
|
|
80
|
+
'MDXSearchTool': MDXSearchTool(),
|
|
81
|
+
'PDFSearchTool': PDFSearchTool(),
|
|
82
|
+
# 'PGSearchTool': PGSearchTool(),
|
|
83
|
+
'RagTool': RagTool(),
|
|
84
|
+
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
|
|
85
|
+
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
|
|
86
|
+
'WebsiteSearchTool': WebsiteSearchTool(),
|
|
87
|
+
'XMLSearchTool': XMLSearchTool(),
|
|
88
|
+
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
|
89
|
+
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
|
90
|
+
}
|
|
91
|
+
root_directory = os.getcwd()
|
|
92
|
+
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
93
|
+
tools_dir_path = Path(root_directory) / 'tools'
|
|
94
|
+
|
|
95
|
+
if os.path.isfile(tools_py_path):
|
|
96
|
+
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
|
|
97
|
+
# print("tools.py exists in the root directory. Loading tools.py and skipping tools folder.")
|
|
98
|
+
elif tools_dir_path.is_dir():
|
|
99
|
+
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
|
|
100
|
+
# print("tools folder exists in the root directory")
|
|
101
|
+
|
|
102
|
+
framework = self.framework or config.get('framework')
|
|
103
|
+
|
|
104
|
+
agents = {}
|
|
105
|
+
tasks = []
|
|
106
|
+
if framework == "autogen":
|
|
107
|
+
# Load the LLM configuration dynamically
|
|
108
|
+
# print(self.config_list)
|
|
109
|
+
llm_config = {"config_list": self.config_list}
|
|
110
|
+
|
|
111
|
+
# Assuming the user proxy agent is set up as per your requirements
|
|
112
|
+
user_proxy = autogen.UserProxyAgent(
|
|
113
|
+
name="User",
|
|
114
|
+
human_input_mode="NEVER",
|
|
115
|
+
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
116
|
+
code_execution_config={
|
|
117
|
+
"work_dir": "coding",
|
|
118
|
+
"use_docker": False,
|
|
119
|
+
},
|
|
120
|
+
# additional setup for the user proxy agent
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
for role, details in config['roles'].items():
|
|
124
|
+
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
|
|
125
|
+
agent_goal = details['goal'].format(topic=topic)
|
|
126
|
+
# Creating an AssistantAgent for each role dynamically
|
|
127
|
+
agents[role] = autogen.AssistantAgent(
|
|
128
|
+
name=agent_name,
|
|
129
|
+
llm_config=llm_config,
|
|
130
|
+
system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
131
|
+
)
|
|
132
|
+
for tool in details.get('tools', []):
|
|
133
|
+
if tool in tools_dict:
|
|
134
|
+
try:
|
|
135
|
+
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
|
136
|
+
print(f"Found {tool_class.__name__} for {tool}")
|
|
137
|
+
except KeyError:
|
|
138
|
+
print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
|
|
139
|
+
continue
|
|
140
|
+
tool_class(agents[role], user_proxy)
|
|
141
|
+
|
|
142
|
+
# Preparing tasks for initiate_chats
|
|
143
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
144
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
145
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
146
|
+
|
|
147
|
+
chat_task = {
|
|
148
|
+
"recipient": agents[role],
|
|
149
|
+
"message": description_filled,
|
|
150
|
+
"summary_method": "last_msg",
|
|
151
|
+
# Additional fields like carryover can be added based on dependencies
|
|
152
|
+
}
|
|
153
|
+
tasks.append(chat_task)
|
|
154
|
+
|
|
155
|
+
response = user_proxy.initiate_chats(tasks)
|
|
156
|
+
result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
157
|
+
else:
|
|
158
|
+
for role, details in config['roles'].items():
|
|
159
|
+
role_filled = details['role'].format(topic=topic)
|
|
160
|
+
goal_filled = details['goal'].format(topic=topic)
|
|
161
|
+
backstory_filled = details['backstory'].format(topic=topic)
|
|
162
|
+
|
|
163
|
+
# Adding tools to the agent if exists
|
|
164
|
+
agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
|
|
165
|
+
agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, tools=agent_tools, allow_delegation=False)
|
|
166
|
+
agents[role] = agent
|
|
167
|
+
|
|
168
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
169
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
170
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
171
|
+
|
|
172
|
+
task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
|
|
173
|
+
tasks.append(task)
|
|
174
|
+
crew = Crew(
|
|
175
|
+
agents=list(agents.values()),
|
|
176
|
+
tasks=tasks,
|
|
177
|
+
verbose=2
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
response = crew.kickoff()
|
|
181
|
+
result = f"### Task Output ###\n{response}"
|
|
182
|
+
return result
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from openai import OpenAI
|
|
2
2
|
from pydantic import BaseModel
|
|
3
|
-
from typing import Dict
|
|
3
|
+
from typing import Dict, List
|
|
4
4
|
import instructor
|
|
5
5
|
import os
|
|
6
6
|
import json
|
|
@@ -17,12 +17,13 @@ class RoleDetails(BaseModel):
|
|
|
17
17
|
goal: str
|
|
18
18
|
backstory: str
|
|
19
19
|
tasks: Dict[str, TaskDetails]
|
|
20
|
+
tools: List[str]
|
|
20
21
|
|
|
21
22
|
class TeamStructure(BaseModel):
|
|
22
23
|
roles: Dict[str, RoleDetails]
|
|
23
24
|
|
|
24
25
|
class AutoGenerator:
|
|
25
|
-
def __init__(self, topic="Movie Story writing about AI",
|
|
26
|
+
def __init__(self, topic="Movie Story writing about AI", agent_file="test.yaml", framework="crewai"):
|
|
26
27
|
self.config_list = [
|
|
27
28
|
{
|
|
28
29
|
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4-turbo-preview"),
|
|
@@ -30,7 +31,7 @@ class AutoGenerator:
|
|
|
30
31
|
}
|
|
31
32
|
]
|
|
32
33
|
self.topic = topic
|
|
33
|
-
self.
|
|
34
|
+
self.agent_file = agent_file
|
|
34
35
|
self.framework = framework
|
|
35
36
|
self.client = instructor.patch(
|
|
36
37
|
OpenAI(
|
|
@@ -52,7 +53,7 @@ class AutoGenerator:
|
|
|
52
53
|
)
|
|
53
54
|
json_data = json.loads(response.model_dump_json())
|
|
54
55
|
self.convert_and_save(json_data)
|
|
55
|
-
full_path = os.path.abspath(self.
|
|
56
|
+
full_path = os.path.abspath(self.agent_file)
|
|
56
57
|
return full_path
|
|
57
58
|
|
|
58
59
|
def convert_and_save(self, json_data):
|
|
@@ -61,7 +62,7 @@ class AutoGenerator:
|
|
|
61
62
|
Args:
|
|
62
63
|
json_data (dict): The JSON data representing the team structure.
|
|
63
64
|
topic (str, optional): The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".
|
|
64
|
-
|
|
65
|
+
agent_file (str, optional): The name of the YAML file to save. Defaults to "test.yaml".
|
|
65
66
|
"""
|
|
66
67
|
|
|
67
68
|
yaml_data = {
|
|
@@ -76,7 +77,9 @@ class AutoGenerator:
|
|
|
76
77
|
"backstory": "" + role_details['backstory'],
|
|
77
78
|
"goal": role_details['goal'],
|
|
78
79
|
"role": role_details['role'],
|
|
79
|
-
"tasks": {}
|
|
80
|
+
"tasks": {},
|
|
81
|
+
# "tools": role_details.get('tools', []),
|
|
82
|
+
"tools": ['']
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
for task_id, task_details in role_details['tasks'].items():
|
|
@@ -86,7 +89,7 @@ class AutoGenerator:
|
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
# Save to YAML file, maintaining the order
|
|
89
|
-
with open(self.
|
|
92
|
+
with open(self.agent_file, 'w') as f:
|
|
90
93
|
yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
|
|
91
94
|
|
|
92
95
|
def get_user_content(self):
|
|
@@ -96,6 +99,8 @@ The team will work in sequence. First role will pass the output to the next role
|
|
|
96
99
|
The last role will generate the final output.
|
|
97
100
|
Think step by step.
|
|
98
101
|
With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
|
|
102
|
+
List of Available Tools: CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool, YoutubeVideoSearchTool.
|
|
103
|
+
Only use Available Tools. Do Not use any other tools.
|
|
99
104
|
Example Below:
|
|
100
105
|
Use below example to understand the structure of the output.
|
|
101
106
|
The final role you create should satisfy the provided task: """ + self.topic + """.
|
|
@@ -105,9 +110,10 @@ The final role you create should satisfy the provided task: """ + self.topic + "
|
|
|
105
110
|
"role": "Narrative Designer",
|
|
106
111
|
"goal": "Create AI storylines",
|
|
107
112
|
"backstory": "Skilled in narrative development for AI, with a focus on story resonance.",
|
|
113
|
+
"tools": ["ScrapeWebsiteTool"],
|
|
108
114
|
"tasks": {
|
|
109
115
|
"story_concept_development": {
|
|
110
|
-
"description": "Craft a unique AI story concept with depth and engagement.",
|
|
116
|
+
"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 .",
|
|
111
117
|
"expected_output": "Document with narrative arcs, character bios, and settings."
|
|
112
118
|
}
|
|
113
119
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
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="crewai", auto=False, init=False):
|
|
19
|
+
self.config_list = [
|
|
20
|
+
{
|
|
21
|
+
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4-turbo-preview"),
|
|
22
|
+
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
self.agent_file = agent_file
|
|
26
|
+
self.framework = framework
|
|
27
|
+
self.auto = auto
|
|
28
|
+
self.init = init
|
|
29
|
+
|
|
30
|
+
def main(self):
|
|
31
|
+
args = self.parse_args()
|
|
32
|
+
if args is None:
|
|
33
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
34
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
35
|
+
return result
|
|
36
|
+
if args.deploy:
|
|
37
|
+
from .deploy import CloudDeployer
|
|
38
|
+
deployer = CloudDeployer()
|
|
39
|
+
deployer.run_commands()
|
|
40
|
+
return
|
|
41
|
+
invocation_cmd = "praisonai"
|
|
42
|
+
version_string = f"PraisonAI version {__version__}"
|
|
43
|
+
if args.framework:
|
|
44
|
+
self.framework = args.framework
|
|
45
|
+
ui = args.ui
|
|
46
|
+
if args.agent_file:
|
|
47
|
+
if args.agent_file.startswith("tests.test"): # Argument used for testing purposes
|
|
48
|
+
print("test")
|
|
49
|
+
else:
|
|
50
|
+
self.agent_file = args.agent_file
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if args.auto or args.init:
|
|
54
|
+
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
|
|
55
|
+
self.topic = temp_topic
|
|
56
|
+
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
|
|
57
|
+
self.topic = self.auto
|
|
58
|
+
|
|
59
|
+
if args.auto or self.auto:
|
|
60
|
+
self.agent_file = "test.yaml"
|
|
61
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
62
|
+
self.agent_file = generator.generate()
|
|
63
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
64
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
65
|
+
return result
|
|
66
|
+
elif args.init or self.init:
|
|
67
|
+
self.agent_file = "agents.yaml"
|
|
68
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
69
|
+
self.agent_file = generator.generate()
|
|
70
|
+
print("File {} created successfully".format(self.agent_file))
|
|
71
|
+
return "File {} created successfully".format(self.agent_file)
|
|
72
|
+
|
|
73
|
+
if ui:
|
|
74
|
+
self.create_gradio_interface()
|
|
75
|
+
else:
|
|
76
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
77
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
78
|
+
return result
|
|
79
|
+
|
|
80
|
+
def parse_args(self):
|
|
81
|
+
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
|
|
82
|
+
parser.add_argument("--framework", choices=["crewai", "autogen"], help="Specify the framework")
|
|
83
|
+
parser.add_argument("--ui", action="store_true", help="Enable UI mode")
|
|
84
|
+
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
85
|
+
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
86
|
+
parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
|
|
87
|
+
parser.add_argument("--deploy", action="store_true", help="Deploy the application") # New argument
|
|
88
|
+
|
|
89
|
+
args, unknown_args = parser.parse_known_args()
|
|
90
|
+
|
|
91
|
+
if unknown_args and unknown_args[0] == '-b' and unknown_args[1] == 'api:app':
|
|
92
|
+
args.agent_file = 'agents.yaml'
|
|
93
|
+
if args.agent_file == 'api:app' or args.agent_file == '/app/api:app':
|
|
94
|
+
args.agent_file = 'agents.yaml'
|
|
95
|
+
|
|
96
|
+
return args
|
|
97
|
+
|
|
98
|
+
def create_gradio_interface(self):
|
|
99
|
+
def generate_crew_and_kickoff_interface(auto_args, framework):
|
|
100
|
+
self.framework = framework
|
|
101
|
+
self.agent_file = "test.yaml"
|
|
102
|
+
generator = AutoGenerator(topic=auto_args , framework=self.framework)
|
|
103
|
+
self.agent_file = generator.generate()
|
|
104
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
105
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
106
|
+
return result
|
|
107
|
+
|
|
108
|
+
gr.Interface(
|
|
109
|
+
fn=generate_crew_and_kickoff_interface,
|
|
110
|
+
inputs=[gr.Textbox(lines=2, label="Auto Args"), gr.Dropdown(choices=["crewai", "autogen"], label="Framework")],
|
|
111
|
+
outputs="textbox",
|
|
112
|
+
title="Praison AI Studio",
|
|
113
|
+
description="Create Agents and perform tasks",
|
|
114
|
+
theme="default"
|
|
115
|
+
).launch()
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
praison_ai = PraisonAI()
|
|
119
|
+
praison_ai.main()
|
|
@@ -13,7 +13,7 @@ class CloudDeployer:
|
|
|
13
13
|
file.write("FROM python:3.11-slim\n")
|
|
14
14
|
file.write("WORKDIR /app\n")
|
|
15
15
|
file.write("COPY . .\n")
|
|
16
|
-
file.write("RUN pip install flask praisonai==0.0.
|
|
16
|
+
file.write("RUN pip install flask praisonai==0.0.19 gunicorn markdown\n")
|
|
17
17
|
file.write("EXPOSE 8080\n")
|
|
18
18
|
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
|
19
19
|
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# praisonai/inbuilt_tools/autogen_tools.py
|
|
2
|
+
|
|
3
|
+
from crewai_tools import (
|
|
4
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
|
5
|
+
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
|
6
|
+
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
|
|
7
|
+
YoutubeVideoSearchTool
|
|
8
|
+
)
|
|
9
|
+
from typing import Any
|
|
10
|
+
from autogen import register_function
|
|
11
|
+
import os
|
|
12
|
+
import importlib
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
import os
|
|
15
|
+
import inspect
|
|
16
|
+
|
|
17
|
+
def create_autogen_tool_function(tool_name):
|
|
18
|
+
def autogen_tool(assistant, user_proxy):
|
|
19
|
+
def register_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
20
|
+
def tool_func(query: str) -> Any:
|
|
21
|
+
tool_instance = tool_class()
|
|
22
|
+
return tool_instance.run(query=query)
|
|
23
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
24
|
+
|
|
25
|
+
root_directory = os.getcwd()
|
|
26
|
+
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
27
|
+
tools_dir_path = Path(root_directory) / 'tools'
|
|
28
|
+
|
|
29
|
+
if os.path.isfile(tools_py_path):
|
|
30
|
+
print(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
|
|
31
|
+
tool_module = importlib.import_module("tools")
|
|
32
|
+
elif tools_dir_path.is_dir():
|
|
33
|
+
print(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
|
|
34
|
+
tool_module = importlib.import_module(f"tools.{tool_name}")
|
|
35
|
+
else:
|
|
36
|
+
raise ImportError("Neither tools.py nor tools directory found in the root directory.")
|
|
37
|
+
|
|
38
|
+
Tool = getattr(tool_module, tool_name)
|
|
39
|
+
|
|
40
|
+
register_tool(Tool, tool_name, f"Description for {tool_name}", assistant, user_proxy)
|
|
41
|
+
|
|
42
|
+
return autogen_tool
|
|
43
|
+
|
|
44
|
+
# Load tools.py
|
|
45
|
+
root_directory = os.getcwd()
|
|
46
|
+
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
47
|
+
tools_dir_path = Path(root_directory) / 'tools'
|
|
48
|
+
|
|
49
|
+
tools_module = None
|
|
50
|
+
|
|
51
|
+
if os.path.isfile(tools_py_path):
|
|
52
|
+
print(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
|
|
53
|
+
tools_module = importlib.import_module("tools")
|
|
54
|
+
elif tools_dir_path.is_dir():
|
|
55
|
+
print(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
|
|
56
|
+
tools_module = importlib.import_module(f"tools.{tool_name}")
|
|
57
|
+
|
|
58
|
+
# Create autogen_TOOL_NAME_HERE function for each tool
|
|
59
|
+
if tools_module is not None:
|
|
60
|
+
for name, obj in inspect.getmembers(tools_module):
|
|
61
|
+
if inspect.isclass(obj):
|
|
62
|
+
globals()[f"autogen_{name}"] = create_autogen_tool_function(name)
|
|
63
|
+
|
|
64
|
+
def autogen_CodeDocsSearchTool(assistant, user_proxy):
|
|
65
|
+
def register_code_docs_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
66
|
+
def tool_func(docs_url: str, search_query: str) -> Any:
|
|
67
|
+
tool_instance = tool_class(docs_url=docs_url, search_query=search_query)
|
|
68
|
+
return tool_instance.run()
|
|
69
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
70
|
+
register_code_docs_search_tool(CodeDocsSearchTool, "code_docs_search_tool", "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.", assistant, user_proxy)
|
|
71
|
+
|
|
72
|
+
def autogen_CSVSearchTool(assistant, user_proxy):
|
|
73
|
+
def register_csv_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
74
|
+
def tool_func(csv: str, search_query: str) -> Any:
|
|
75
|
+
tool_instance = tool_class(csv=csv, search_query=search_query)
|
|
76
|
+
return tool_instance.run()
|
|
77
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
78
|
+
register_csv_search_tool(CSVSearchTool, "csv_search_tool", "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.", assistant, user_proxy)
|
|
79
|
+
|
|
80
|
+
def autogen_DirectorySearchTool(assistant, user_proxy):
|
|
81
|
+
def register_directory_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
82
|
+
def tool_func(directory: str, search_query: str) -> Any:
|
|
83
|
+
tool_instance = tool_class(directory=directory, search_query=search_query)
|
|
84
|
+
return tool_instance.run()
|
|
85
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
86
|
+
register_directory_search_tool(DirectorySearchTool, "directory_search_tool", "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.", assistant, user_proxy)
|
|
87
|
+
|
|
88
|
+
def autogen_DOCXSearchTool(assistant, user_proxy):
|
|
89
|
+
def register_docx_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
90
|
+
def tool_func(docx: str, search_query: str) -> Any:
|
|
91
|
+
tool_instance = tool_class(docx=docx, search_query=search_query)
|
|
92
|
+
return tool_instance.run()
|
|
93
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
94
|
+
register_docx_search_tool(DOCXSearchTool, "docx_search_tool", "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.", assistant, user_proxy)
|
|
95
|
+
|
|
96
|
+
# DirectoryReadTool
|
|
97
|
+
def autogen_DirectoryReadTool(assistant, user_proxy):
|
|
98
|
+
def register_directory_read_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
99
|
+
def tool_func(directory: str) -> Any:
|
|
100
|
+
tool_instance = tool_class(directory=directory)
|
|
101
|
+
return tool_instance.run()
|
|
102
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
103
|
+
register_directory_read_tool(DirectoryReadTool, "directory_read_tool", "List files in directory(directory: 'string') - A tool that can be used to recursively list a directory's content.", assistant, user_proxy)
|
|
104
|
+
|
|
105
|
+
# FileReadTool
|
|
106
|
+
def autogen_FileReadTool(assistant, user_proxy):
|
|
107
|
+
def register_file_read_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
108
|
+
def tool_func(file_path: str) -> Any:
|
|
109
|
+
tool_instance = tool_class(file_path=file_path)
|
|
110
|
+
return tool_instance.run()
|
|
111
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
112
|
+
register_file_read_tool(FileReadTool, "file_read_tool", "Read a file's content(file_path: 'string') - A tool that can be used to read a file's content.", assistant, user_proxy)
|
|
113
|
+
|
|
114
|
+
# TXTSearchTool
|
|
115
|
+
def autogen_TXTSearchTool(assistant, user_proxy):
|
|
116
|
+
def register_txt_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
117
|
+
def tool_func(txt: str, search_query: str) -> Any:
|
|
118
|
+
tool_instance = tool_class(txt=txt, search_query=search_query)
|
|
119
|
+
return tool_instance.run()
|
|
120
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
121
|
+
register_txt_search_tool(TXTSearchTool, "txt_search_tool", "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.", assistant, user_proxy)
|
|
122
|
+
|
|
123
|
+
def autogen_JSONSearchTool(assistant, user_proxy):
|
|
124
|
+
def register_json_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
125
|
+
def tool_func(json_path: str, search_query: str) -> Any:
|
|
126
|
+
tool_instance = tool_class(json_path=json_path, search_query=search_query)
|
|
127
|
+
return tool_instance.run()
|
|
128
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
129
|
+
register_json_search_tool(JSONSearchTool, "json_search_tool", "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.", assistant, user_proxy)
|
|
130
|
+
|
|
131
|
+
def autogen_MDXSearchTool(assistant, user_proxy):
|
|
132
|
+
def register_mdx_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
133
|
+
def tool_func(mdx: str, search_query: str) -> Any:
|
|
134
|
+
tool_instance = tool_class(mdx=mdx, search_query=search_query)
|
|
135
|
+
return tool_instance.run()
|
|
136
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
137
|
+
register_mdx_search_tool(MDXSearchTool, "mdx_search_tool", "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.", assistant, user_proxy)
|
|
138
|
+
|
|
139
|
+
def autogen_PDFSearchTool(assistant, user_proxy):
|
|
140
|
+
def register_pdf_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
141
|
+
def tool_func(pdf: str, search_query: str) -> Any:
|
|
142
|
+
tool_instance = tool_class(pdf=pdf, search_query=search_query)
|
|
143
|
+
return tool_instance.run()
|
|
144
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
145
|
+
register_pdf_search_tool(PDFSearchTool, "pdf_search_tool", "Search a PDF's content(search_query: 'string', pdf: 'string') - A tool that can be used to semantic search a query from a PDF's content.", assistant, user_proxy)
|
|
146
|
+
|
|
147
|
+
def autogen_RagTool(assistant, user_proxy):
|
|
148
|
+
def register_rag_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
149
|
+
def tool_func(query: str, data: Any) -> Any:
|
|
150
|
+
tool_instance = tool_class(query=query, data=data)
|
|
151
|
+
return tool_instance.run()
|
|
152
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
153
|
+
register_rag_tool(RagTool, "rag_tool", "Knowledge base(query: 'string', data: Any) - A knowledge base that can be used to answer questions.", assistant, user_proxy)
|
|
154
|
+
|
|
155
|
+
def autogen_ScrapeElementFromWebsiteTool(assistant, user_proxy):
|
|
156
|
+
def register_scrape_element_from_website_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
157
|
+
def tool_func(website_url: str, element_query: str) -> Any:
|
|
158
|
+
tool_instance = tool_class(website_url=website_url, element_query=element_query)
|
|
159
|
+
return tool_instance.run()
|
|
160
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
161
|
+
register_scrape_element_from_website_tool(ScrapeElementFromWebsiteTool, "scrape_element_from_website_tool", "Scrape an element from a website(element_query: 'string', website_url: 'string') - A tool that can be used to scrape an element from a website.", assistant, user_proxy)
|
|
162
|
+
|
|
163
|
+
def autogen_ScrapeWebsiteTool(assistant, user_proxy):
|
|
164
|
+
def register_scrape_website_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
165
|
+
def tool_func(website_url: str) -> Any:
|
|
166
|
+
tool_instance = tool_class(website_url=website_url)
|
|
167
|
+
return tool_instance.run()
|
|
168
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
169
|
+
register_scrape_website_tool(ScrapeWebsiteTool, "scrape_website_tool", "Read website content(website_url: 'string') - A tool that can be used to read content from a specified website.", assistant, user_proxy)
|
|
170
|
+
|
|
171
|
+
def autogen_WebsiteSearchTool(assistant, user_proxy):
|
|
172
|
+
def register_website_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
173
|
+
def tool_func(website: str, search_query: str) -> Any:
|
|
174
|
+
tool_instance = tool_class(website=website, search_query=search_query)
|
|
175
|
+
return tool_instance.run()
|
|
176
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
177
|
+
register_website_search_tool(WebsiteSearchTool, "website_search_tool", "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.", assistant, user_proxy)
|
|
178
|
+
|
|
179
|
+
def autogen_XMLSearchTool(assistant, user_proxy):
|
|
180
|
+
def register_xml_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
181
|
+
def tool_func(xml: str, search_query: str) -> Any:
|
|
182
|
+
tool_instance = tool_class(xml=xml, search_query=search_query)
|
|
183
|
+
return tool_instance.run()
|
|
184
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
185
|
+
register_xml_search_tool(XMLSearchTool, "xml_search_tool", "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.", assistant, user_proxy)
|
|
186
|
+
|
|
187
|
+
def autogen_YoutubeChannelSearchTool(assistant, user_proxy):
|
|
188
|
+
def register_youtube_channel_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
189
|
+
def tool_func(youtube_channel_handle: str, search_query: str) -> Any:
|
|
190
|
+
tool_instance = tool_class(youtube_channel_handle=youtube_channel_handle, search_query=search_query)
|
|
191
|
+
return tool_instance.run()
|
|
192
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
193
|
+
register_youtube_channel_search_tool(YoutubeChannelSearchTool, "youtube_channel_search_tool", "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.", assistant, user_proxy)
|
|
194
|
+
|
|
195
|
+
def autogen_YoutubeVideoSearchTool(assistant, user_proxy):
|
|
196
|
+
def register_youtube_video_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
|
|
197
|
+
def tool_func(youtube_video_url: str, search_query: str) -> Any:
|
|
198
|
+
tool_instance = tool_class(youtube_video_url=youtube_video_url, search_query=search_query)
|
|
199
|
+
return tool_instance.run()
|
|
200
|
+
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
|
|
201
|
+
register_youtube_video_search_tool(YoutubeVideoSearchTool, "youtube_video_search_tool", "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.", assistant, user_proxy)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "praisonAI"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.19"
|
|
4
4
|
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."
|
|
5
5
|
authors = ["Mervin Praison"]
|
|
6
6
|
license = ""
|
|
@@ -21,13 +21,12 @@ crewai = ">=0.22.5"
|
|
|
21
21
|
gradio = ">=4.20.0"
|
|
22
22
|
Flask = ">=3.0.0"
|
|
23
23
|
markdown = ">=3.5"
|
|
24
|
+
crewai-tools = "^0.1.1"
|
|
25
|
+
praisonai-tools = ">=0.0.4"
|
|
24
26
|
|
|
25
27
|
[tool.poetry.dev-dependencies]
|
|
26
|
-
pytest = "^
|
|
27
|
-
pre-commit = "^3.
|
|
28
|
-
|
|
29
|
-
[tool.poetry.extras]
|
|
30
|
-
tools = ["crewai-tools"]
|
|
28
|
+
pytest = "^8.0.0"
|
|
29
|
+
pre-commit = "^3.7"
|
|
31
30
|
|
|
32
31
|
[build-system]
|
|
33
32
|
requires = ["poetry-core"]
|
|
@@ -1,202 +0,0 @@
|
|
|
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
|
-
|
|
15
|
-
class PraisonAI:
|
|
16
|
-
def __init__(self, agent_file="agents.yaml", framework="crewai", auto=False, init=False):
|
|
17
|
-
self.config_list = [
|
|
18
|
-
{
|
|
19
|
-
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4-turbo-preview"),
|
|
20
|
-
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
self.agent_file = agent_file
|
|
24
|
-
self.framework = framework
|
|
25
|
-
self.auto = auto
|
|
26
|
-
self.init = init
|
|
27
|
-
|
|
28
|
-
def generate_crew_and_kickoff(self):
|
|
29
|
-
if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
|
|
30
|
-
self.agent_file = 'agents.yaml'
|
|
31
|
-
try:
|
|
32
|
-
with open(self.agent_file, 'r') as f:
|
|
33
|
-
config = yaml.safe_load(f)
|
|
34
|
-
except FileNotFoundError:
|
|
35
|
-
print(f"File not found: {self.agent_file}")
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
topic = config['topic']
|
|
39
|
-
framework = self.framework or config.get('framework')
|
|
40
|
-
|
|
41
|
-
agents = {}
|
|
42
|
-
tasks = []
|
|
43
|
-
if framework == "autogen":
|
|
44
|
-
# Load the LLM configuration dynamically
|
|
45
|
-
# print(self.config_list)
|
|
46
|
-
llm_config = {"config_list": self.config_list}
|
|
47
|
-
|
|
48
|
-
for role, details in config['roles'].items():
|
|
49
|
-
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
|
|
50
|
-
agent_goal = details['goal'].format(topic=topic)
|
|
51
|
-
# Creating an AssistantAgent for each role dynamically
|
|
52
|
-
agents[role] = autogen.AssistantAgent(
|
|
53
|
-
name=agent_name,
|
|
54
|
-
llm_config=llm_config,
|
|
55
|
-
system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
# Preparing tasks for initiate_chats
|
|
59
|
-
for task_name, task_details in details.get('tasks', {}).items():
|
|
60
|
-
description_filled = task_details['description'].format(topic=topic)
|
|
61
|
-
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
62
|
-
|
|
63
|
-
chat_task = {
|
|
64
|
-
"recipient": agents[role],
|
|
65
|
-
"message": description_filled,
|
|
66
|
-
"summary_method": "last_msg",
|
|
67
|
-
# Additional fields like carryover can be added based on dependencies
|
|
68
|
-
}
|
|
69
|
-
tasks.append(chat_task)
|
|
70
|
-
|
|
71
|
-
# Assuming the user proxy agent is set up as per your requirements
|
|
72
|
-
user = autogen.UserProxyAgent(
|
|
73
|
-
name="User",
|
|
74
|
-
human_input_mode="NEVER",
|
|
75
|
-
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
76
|
-
code_execution_config={
|
|
77
|
-
"work_dir": "coding",
|
|
78
|
-
"use_docker": False,
|
|
79
|
-
},
|
|
80
|
-
# additional setup for the user proxy agent
|
|
81
|
-
)
|
|
82
|
-
response = user.initiate_chats(tasks)
|
|
83
|
-
result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
84
|
-
else:
|
|
85
|
-
for role, details in config['roles'].items():
|
|
86
|
-
role_filled = details['role'].format(topic=topic)
|
|
87
|
-
goal_filled = details['goal'].format(topic=topic)
|
|
88
|
-
backstory_filled = details['backstory'].format(topic=topic)
|
|
89
|
-
|
|
90
|
-
# Assume tools are loaded and handled here as per your requirements
|
|
91
|
-
agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, allow_delegation=False)
|
|
92
|
-
agents[role] = agent
|
|
93
|
-
|
|
94
|
-
for task_name, task_details in details.get('tasks', {}).items():
|
|
95
|
-
description_filled = task_details['description'].format(topic=topic)
|
|
96
|
-
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
97
|
-
|
|
98
|
-
task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
|
|
99
|
-
tasks.append(task)
|
|
100
|
-
|
|
101
|
-
crew = Crew(
|
|
102
|
-
agents=list(agents.values()),
|
|
103
|
-
tasks=tasks,
|
|
104
|
-
verbose=2
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
response = crew.kickoff()
|
|
108
|
-
result = f"### Output ###\n{response}"
|
|
109
|
-
return result
|
|
110
|
-
|
|
111
|
-
def main(self):
|
|
112
|
-
args = self.parse_args()
|
|
113
|
-
if args is None:
|
|
114
|
-
result = self.generate_crew_and_kickoff()
|
|
115
|
-
return result
|
|
116
|
-
if args.deploy:
|
|
117
|
-
from .deploy import CloudDeployer
|
|
118
|
-
deployer = CloudDeployer()
|
|
119
|
-
deployer.run_commands()
|
|
120
|
-
return
|
|
121
|
-
invocation_cmd = "praisonai"
|
|
122
|
-
version_string = f"praisonAI version {__version__}"
|
|
123
|
-
|
|
124
|
-
if args.framework:
|
|
125
|
-
self.framework = args.framework
|
|
126
|
-
|
|
127
|
-
ui = args.ui
|
|
128
|
-
|
|
129
|
-
if args.agent_file:
|
|
130
|
-
if args.agent_file == "tests.test": # Argument used for testing purposes
|
|
131
|
-
full_path = os.path.abspath("agents.yaml")
|
|
132
|
-
else:
|
|
133
|
-
full_path = os.path.abspath(args.agent_file)
|
|
134
|
-
self.agent_file = full_path
|
|
135
|
-
else:
|
|
136
|
-
full_path = os.path.abspath(self.agent_file)
|
|
137
|
-
self.filename = full_path
|
|
138
|
-
|
|
139
|
-
if args.auto or args.init:
|
|
140
|
-
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
|
|
141
|
-
self.topic = temp_topic
|
|
142
|
-
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
|
|
143
|
-
self.topic = self.auto
|
|
144
|
-
|
|
145
|
-
if args.auto or self.auto:
|
|
146
|
-
self.filename = "test.yaml"
|
|
147
|
-
generator = AutoGenerator(topic=self.topic , framework=self.framework)
|
|
148
|
-
self.agent_file = generator.generate()
|
|
149
|
-
result = self.generate_crew_and_kickoff()
|
|
150
|
-
return result
|
|
151
|
-
elif args.init or self.init:
|
|
152
|
-
self.filename = "agents.yaml"
|
|
153
|
-
generator = AutoGenerator(topic=self.topic , framework=self.framework, filename=self.filename)
|
|
154
|
-
self.agent_file = generator.generate()
|
|
155
|
-
print("File {} created successfully".format(self.agent_file))
|
|
156
|
-
return "File {} created successfully".format(self.agent_file)
|
|
157
|
-
|
|
158
|
-
if ui:
|
|
159
|
-
self.create_gradio_interface()
|
|
160
|
-
else:
|
|
161
|
-
result = self.generate_crew_and_kickoff()
|
|
162
|
-
return result
|
|
163
|
-
|
|
164
|
-
def parse_args(self):
|
|
165
|
-
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
|
|
166
|
-
parser.add_argument("--framework", choices=["crewai", "autogen"], default="crewai", help="Specify the framework")
|
|
167
|
-
parser.add_argument("--ui", action="store_true", help="Enable UI mode")
|
|
168
|
-
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
169
|
-
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
170
|
-
parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
|
|
171
|
-
parser.add_argument("--deploy", action="store_true", help="Deploy the application") # New argument
|
|
172
|
-
|
|
173
|
-
args, unknown_args = parser.parse_known_args()
|
|
174
|
-
|
|
175
|
-
if unknown_args and unknown_args[0] == '-b' and unknown_args[1] == 'api:app':
|
|
176
|
-
args.agent_file = 'agents.yaml'
|
|
177
|
-
if args.agent_file == 'api:app' or args.agent_file == '/app/api:app':
|
|
178
|
-
args.agent_file = 'agents.yaml'
|
|
179
|
-
|
|
180
|
-
return args
|
|
181
|
-
|
|
182
|
-
def create_gradio_interface(self):
|
|
183
|
-
def generate_crew_and_kickoff_interface(auto_args, framework):
|
|
184
|
-
self.framework = framework
|
|
185
|
-
self.agent_file = "test.yaml"
|
|
186
|
-
generator = AutoGenerator(topic=auto_args , framework=self.framework)
|
|
187
|
-
self.agent_file = generator.generate()
|
|
188
|
-
result = self.generate_crew_and_kickoff()
|
|
189
|
-
return result
|
|
190
|
-
|
|
191
|
-
gr.Interface(
|
|
192
|
-
fn=generate_crew_and_kickoff_interface,
|
|
193
|
-
inputs=[gr.Textbox(lines=2, label="Auto Args"), gr.Dropdown(choices=["crewai", "autogen"], label="Framework")],
|
|
194
|
-
outputs="textbox",
|
|
195
|
-
title="Praison AI Studio",
|
|
196
|
-
description="Create Agents and perform tasks",
|
|
197
|
-
theme="default"
|
|
198
|
-
).launch()
|
|
199
|
-
|
|
200
|
-
if __name__ == "__main__":
|
|
201
|
-
praison_ai = PraisonAI()
|
|
202
|
-
praison_ai.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|