PraisonAI 2.0.61__cp313-cp313-manylinux_2_39_x86_64.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 +6 -0
- praisonai/__main__.py +10 -0
- praisonai/agents_generator.py +648 -0
- praisonai/api/call.py +292 -0
- praisonai/auto.py +238 -0
- praisonai/chainlit_ui.py +304 -0
- praisonai/cli.py +518 -0
- praisonai/deploy.py +138 -0
- praisonai/inbuilt_tools/__init__.py +24 -0
- praisonai/inbuilt_tools/autogen_tools.py +117 -0
- praisonai/inc/__init__.py +2 -0
- praisonai/inc/config.py +96 -0
- praisonai/inc/models.py +128 -0
- praisonai/public/android-chrome-192x192.png +0 -0
- praisonai/public/android-chrome-512x512.png +0 -0
- praisonai/public/apple-touch-icon.png +0 -0
- praisonai/public/fantasy.svg +3 -0
- praisonai/public/favicon-16x16.png +0 -0
- praisonai/public/favicon-32x32.png +0 -0
- praisonai/public/favicon.ico +0 -0
- praisonai/public/game.svg +3 -0
- praisonai/public/logo_dark.png +0 -0
- praisonai/public/logo_light.png +0 -0
- praisonai/public/movie.svg +3 -0
- praisonai/public/praison-ai-agents-architecture-dark.png +0 -0
- praisonai/public/praison-ai-agents-architecture.png +0 -0
- praisonai/public/thriller.svg +3 -0
- praisonai/setup/__init__.py +1 -0
- praisonai/setup/build.py +21 -0
- praisonai/setup/config.yaml +60 -0
- praisonai/setup/post_install.py +23 -0
- praisonai/setup/setup_conda_env.py +25 -0
- praisonai/setup/setup_conda_env.sh +72 -0
- praisonai/setup.py +16 -0
- praisonai/test.py +105 -0
- praisonai/train.py +276 -0
- praisonai/ui/README.md +21 -0
- praisonai/ui/agents.py +822 -0
- praisonai/ui/callbacks.py +57 -0
- praisonai/ui/chat.py +387 -0
- praisonai/ui/code.py +440 -0
- praisonai/ui/colab.py +474 -0
- praisonai/ui/colab_chainlit.py +81 -0
- praisonai/ui/components/aicoder.py +269 -0
- praisonai/ui/config/.chainlit/config.toml +120 -0
- praisonai/ui/config/.chainlit/translations/bn.json +231 -0
- praisonai/ui/config/.chainlit/translations/en-US.json +229 -0
- praisonai/ui/config/.chainlit/translations/gu.json +231 -0
- praisonai/ui/config/.chainlit/translations/he-IL.json +231 -0
- praisonai/ui/config/.chainlit/translations/hi.json +231 -0
- praisonai/ui/config/.chainlit/translations/kn.json +231 -0
- praisonai/ui/config/.chainlit/translations/ml.json +231 -0
- praisonai/ui/config/.chainlit/translations/mr.json +231 -0
- praisonai/ui/config/.chainlit/translations/ta.json +231 -0
- praisonai/ui/config/.chainlit/translations/te.json +231 -0
- praisonai/ui/config/.chainlit/translations/zh-CN.json +229 -0
- praisonai/ui/config/chainlit.md +1 -0
- praisonai/ui/config/translations/bn.json +231 -0
- praisonai/ui/config/translations/en-US.json +229 -0
- praisonai/ui/config/translations/gu.json +231 -0
- praisonai/ui/config/translations/he-IL.json +231 -0
- praisonai/ui/config/translations/hi.json +231 -0
- praisonai/ui/config/translations/kn.json +231 -0
- praisonai/ui/config/translations/ml.json +231 -0
- praisonai/ui/config/translations/mr.json +231 -0
- praisonai/ui/config/translations/ta.json +231 -0
- praisonai/ui/config/translations/te.json +231 -0
- praisonai/ui/config/translations/zh-CN.json +229 -0
- praisonai/ui/context.py +283 -0
- praisonai/ui/db.py +291 -0
- praisonai/ui/public/fantasy.svg +3 -0
- praisonai/ui/public/game.svg +3 -0
- praisonai/ui/public/logo_dark.png +0 -0
- praisonai/ui/public/logo_light.png +0 -0
- praisonai/ui/public/movie.svg +3 -0
- praisonai/ui/public/praison.css +3 -0
- praisonai/ui/public/thriller.svg +3 -0
- praisonai/ui/realtime.py +476 -0
- praisonai/ui/realtimeclient/__init__.py +653 -0
- praisonai/ui/realtimeclient/realtimedocs.txt +1484 -0
- praisonai/ui/realtimeclient/tools.py +236 -0
- praisonai/ui/sql_alchemy.py +707 -0
- praisonai/ui/tools.md +133 -0
- praisonai/version.py +1 -0
- praisonai-2.0.61.dist-info/LICENSE +20 -0
- praisonai-2.0.61.dist-info/METADATA +679 -0
- praisonai-2.0.61.dist-info/RECORD +89 -0
- praisonai-2.0.61.dist-info/WHEEL +4 -0
- praisonai-2.0.61.dist-info/entry_points.txt +5 -0
praisonai/__init__.py
ADDED
praisonai/__main__.py
ADDED
|
@@ -0,0 +1,648 @@
|
|
|
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 .auto import AutoGenerator
|
|
9
|
+
from .inbuilt_tools import *
|
|
10
|
+
from .inc import PraisonAIModel
|
|
11
|
+
import inspect
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
import importlib
|
|
14
|
+
import importlib.util
|
|
15
|
+
import os
|
|
16
|
+
import logging
|
|
17
|
+
|
|
18
|
+
# Framework-specific imports with availability checks
|
|
19
|
+
CREWAI_AVAILABLE = False
|
|
20
|
+
AUTOGEN_AVAILABLE = False
|
|
21
|
+
PRAISONAI_TOOLS_AVAILABLE = False
|
|
22
|
+
AGENTOPS_AVAILABLE = False
|
|
23
|
+
PRAISONAI_AVAILABLE = False
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
from praisonaiagents import Agent as PraisonAgent, Task as PraisonTask, PraisonAIAgents
|
|
27
|
+
PRAISONAI_AVAILABLE = True
|
|
28
|
+
except ImportError:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
from crewai import Agent, Task, Crew
|
|
33
|
+
from crewai.telemetry import Telemetry
|
|
34
|
+
CREWAI_AVAILABLE = True
|
|
35
|
+
except ImportError:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
import autogen
|
|
40
|
+
AUTOGEN_AVAILABLE = True
|
|
41
|
+
except ImportError:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
import agentops
|
|
46
|
+
AGENTOPS_AVAILABLE = True
|
|
47
|
+
AGENTOPS_API_KEY = os.getenv("AGENTOPS_API_KEY")
|
|
48
|
+
if not AGENTOPS_API_KEY:
|
|
49
|
+
AGENTOPS_AVAILABLE = False
|
|
50
|
+
except ImportError:
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
# Only try to import praisonai_tools if either CrewAI or AutoGen is available
|
|
54
|
+
if CREWAI_AVAILABLE or AUTOGEN_AVAILABLE or PRAISONAI_AVAILABLE:
|
|
55
|
+
try:
|
|
56
|
+
from praisonai_tools import (
|
|
57
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
|
58
|
+
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
|
59
|
+
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
|
|
60
|
+
YoutubeChannelSearchTool, YoutubeVideoSearchTool, BaseTool
|
|
61
|
+
)
|
|
62
|
+
PRAISONAI_TOOLS_AVAILABLE = True
|
|
63
|
+
except ImportError:
|
|
64
|
+
# If import fails, define BaseTool as a simple base class
|
|
65
|
+
class BaseTool:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
os.environ["OTEL_SDK_DISABLED"] = "true"
|
|
69
|
+
|
|
70
|
+
def noop(*args, **kwargs):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def disable_crewai_telemetry():
|
|
74
|
+
if CREWAI_AVAILABLE:
|
|
75
|
+
for attr in dir(Telemetry):
|
|
76
|
+
if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
|
|
77
|
+
setattr(Telemetry, attr, noop)
|
|
78
|
+
|
|
79
|
+
# Only disable telemetry if CrewAI is available
|
|
80
|
+
if CREWAI_AVAILABLE:
|
|
81
|
+
disable_crewai_telemetry()
|
|
82
|
+
|
|
83
|
+
class AgentsGenerator:
|
|
84
|
+
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
|
|
85
|
+
"""
|
|
86
|
+
Initialize the AgentsGenerator object.
|
|
87
|
+
|
|
88
|
+
Parameters:
|
|
89
|
+
agent_file (str): The path to the agent file.
|
|
90
|
+
framework (str): The framework to be used for the agents.
|
|
91
|
+
config_list (list): A list of configurations for the agents.
|
|
92
|
+
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
|
|
93
|
+
agent_callback (callable, optional): A callback function to be executed after each agent step.
|
|
94
|
+
task_callback (callable, optional): A callback function to be executed after each tool run.
|
|
95
|
+
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
|
|
96
|
+
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.
|
|
97
|
+
|
|
98
|
+
Attributes:
|
|
99
|
+
agent_file (str): The path to the agent file.
|
|
100
|
+
framework (str): The framework to be used for the agents.
|
|
101
|
+
config_list (list): A list of configurations for the agents.
|
|
102
|
+
log_level (int): The logging level to use.
|
|
103
|
+
agent_callback (callable, optional): A callback function to be executed after each agent step.
|
|
104
|
+
task_callback (callable, optional): A callback function to be executed after each tool run.
|
|
105
|
+
tools (dict): A dictionary containing the tools to be used for the agents.
|
|
106
|
+
"""
|
|
107
|
+
self.agent_file = agent_file
|
|
108
|
+
self.framework = framework
|
|
109
|
+
self.config_list = config_list
|
|
110
|
+
self.log_level = log_level
|
|
111
|
+
self.agent_callback = agent_callback
|
|
112
|
+
self.task_callback = task_callback
|
|
113
|
+
self.agent_yaml = agent_yaml
|
|
114
|
+
self.tools = tools or [] # Store tool class names as a list
|
|
115
|
+
self.log_level = log_level or logging.getLogger().getEffectiveLevel()
|
|
116
|
+
if self.log_level == logging.NOTSET:
|
|
117
|
+
self.log_level = os.environ.get('LOGLEVEL', 'INFO').upper()
|
|
118
|
+
|
|
119
|
+
logging.basicConfig(level=self.log_level, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
120
|
+
self.logger = logging.getLogger(__name__)
|
|
121
|
+
self.logger.setLevel(self.log_level)
|
|
122
|
+
|
|
123
|
+
# Validate framework availability
|
|
124
|
+
if framework == "crewai" and not CREWAI_AVAILABLE:
|
|
125
|
+
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
|
|
126
|
+
elif framework == "autogen" and not AUTOGEN_AVAILABLE:
|
|
127
|
+
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
|
|
128
|
+
elif framework == "praisonai" and not PRAISONAI_AVAILABLE:
|
|
129
|
+
raise ImportError("PraisonAI is not installed. Please install it with 'pip install praisonaiagents'")
|
|
130
|
+
|
|
131
|
+
def is_function_or_decorated(self, obj):
|
|
132
|
+
"""
|
|
133
|
+
Checks if the given object is a function or has a __call__ method.
|
|
134
|
+
|
|
135
|
+
Parameters:
|
|
136
|
+
obj (object): The object to be checked.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
bool: True if the object is a function or has a __call__ method, False otherwise.
|
|
140
|
+
"""
|
|
141
|
+
return inspect.isfunction(obj) or hasattr(obj, '__call__')
|
|
142
|
+
|
|
143
|
+
def load_tools_from_module(self, module_path):
|
|
144
|
+
"""
|
|
145
|
+
Loads tools from a specified module path.
|
|
146
|
+
|
|
147
|
+
Parameters:
|
|
148
|
+
module_path (str): The path to the module containing the tools.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
|
|
152
|
+
|
|
153
|
+
Raises:
|
|
154
|
+
FileNotFoundError: If the specified module path does not exist.
|
|
155
|
+
"""
|
|
156
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
157
|
+
module = importlib.util.module_from_spec(spec)
|
|
158
|
+
spec.loader.exec_module(module)
|
|
159
|
+
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
|
|
160
|
+
|
|
161
|
+
def load_tools_from_module_class(self, module_path):
|
|
162
|
+
"""
|
|
163
|
+
Loads tools from a specified module path containing classes that inherit from BaseTool
|
|
164
|
+
or are part of langchain_community.tools package.
|
|
165
|
+
"""
|
|
166
|
+
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
167
|
+
module = importlib.util.module_from_spec(spec)
|
|
168
|
+
try:
|
|
169
|
+
spec.loader.exec_module(module)
|
|
170
|
+
return {name: obj() for name, obj in inspect.getmembers(module,
|
|
171
|
+
lambda x: inspect.isclass(x) and (
|
|
172
|
+
x.__module__.startswith('langchain_community.tools') or
|
|
173
|
+
(PRAISONAI_TOOLS_AVAILABLE and issubclass(x, BaseTool))
|
|
174
|
+
) and x is not BaseTool)}
|
|
175
|
+
except ImportError as e:
|
|
176
|
+
self.logger.warning(f"Error loading tools from {module_path}: {e}")
|
|
177
|
+
return {}
|
|
178
|
+
|
|
179
|
+
def load_tools_from_package(self, package_path):
|
|
180
|
+
"""
|
|
181
|
+
Loads tools from a specified package path containing modules with functions or classes.
|
|
182
|
+
|
|
183
|
+
Parameters:
|
|
184
|
+
package_path (str): The path to the package containing the tools.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
|
|
188
|
+
|
|
189
|
+
Raises:
|
|
190
|
+
FileNotFoundError: If the specified package path does not exist.
|
|
191
|
+
|
|
192
|
+
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.
|
|
193
|
+
"""
|
|
194
|
+
tools_dict = {}
|
|
195
|
+
for module_file in os.listdir(package_path):
|
|
196
|
+
if module_file.endswith('.py') and not module_file.startswith('__'):
|
|
197
|
+
module_name = f"{package_path.name}.{module_file[:-3]}" # Remove .py for import
|
|
198
|
+
module = importlib.import_module(module_name)
|
|
199
|
+
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
|
|
200
|
+
tools_dict[name] = obj
|
|
201
|
+
return tools_dict
|
|
202
|
+
|
|
203
|
+
def load_tools_from_tools_py(self):
|
|
204
|
+
"""
|
|
205
|
+
Imports and returns all contents from tools.py file.
|
|
206
|
+
Also adds the tools to the global namespace.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
list: A list of callable functions with proper formatting
|
|
210
|
+
"""
|
|
211
|
+
tools_list = []
|
|
212
|
+
try:
|
|
213
|
+
# Try to import tools.py from current directory
|
|
214
|
+
spec = importlib.util.spec_from_file_location("tools", "tools.py")
|
|
215
|
+
self.logger.debug(f"Spec: {spec}")
|
|
216
|
+
if spec is None:
|
|
217
|
+
self.logger.debug("tools.py not found in current directory")
|
|
218
|
+
return tools_list
|
|
219
|
+
|
|
220
|
+
module = importlib.util.module_from_spec(spec)
|
|
221
|
+
spec.loader.exec_module(module)
|
|
222
|
+
|
|
223
|
+
# Get all module attributes except private ones and classes
|
|
224
|
+
for name, obj in inspect.getmembers(module):
|
|
225
|
+
if (not name.startswith('_') and
|
|
226
|
+
callable(obj) and
|
|
227
|
+
not inspect.isclass(obj)):
|
|
228
|
+
# Add the function to global namespace
|
|
229
|
+
globals()[name] = obj
|
|
230
|
+
# Add to tools list
|
|
231
|
+
tools_list.append(obj)
|
|
232
|
+
self.logger.debug(f"Loaded and globalized tool function: {name}")
|
|
233
|
+
|
|
234
|
+
self.logger.debug(f"Loaded {len(tools_list)} tool functions from tools.py")
|
|
235
|
+
self.logger.debug(f"Tools list: {tools_list}")
|
|
236
|
+
|
|
237
|
+
except FileNotFoundError:
|
|
238
|
+
self.logger.debug("tools.py not found in current directory")
|
|
239
|
+
except Exception as e:
|
|
240
|
+
self.logger.warning(f"Error loading tools from tools.py: {e}")
|
|
241
|
+
|
|
242
|
+
return tools_list
|
|
243
|
+
|
|
244
|
+
def generate_crew_and_kickoff(self):
|
|
245
|
+
"""
|
|
246
|
+
Generates a crew of agents and initiates tasks based on the provided configuration.
|
|
247
|
+
|
|
248
|
+
Parameters:
|
|
249
|
+
agent_file (str): The path to the agent file.
|
|
250
|
+
framework (str): The framework to be used for the agents.
|
|
251
|
+
config_list (list): A list of configurations for the agents.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
str: The output of the tasks performed by the crew of agents.
|
|
255
|
+
|
|
256
|
+
Raises:
|
|
257
|
+
FileNotFoundError: If the specified agent file does not exist.
|
|
258
|
+
|
|
259
|
+
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.
|
|
260
|
+
"""
|
|
261
|
+
if self.agent_yaml:
|
|
262
|
+
config = yaml.safe_load(self.agent_yaml)
|
|
263
|
+
else:
|
|
264
|
+
if self.agent_file == '/app/api:app' or self.agent_file == 'api:app':
|
|
265
|
+
self.agent_file = 'agents.yaml'
|
|
266
|
+
try:
|
|
267
|
+
with open(self.agent_file, 'r') as f:
|
|
268
|
+
config = yaml.safe_load(f)
|
|
269
|
+
except FileNotFoundError:
|
|
270
|
+
print(f"File not found: {self.agent_file}")
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
topic = config['topic']
|
|
274
|
+
tools_dict = {}
|
|
275
|
+
|
|
276
|
+
# Only try to use praisonai_tools if it's available and needed
|
|
277
|
+
if PRAISONAI_TOOLS_AVAILABLE and (CREWAI_AVAILABLE or AUTOGEN_AVAILABLE or PRAISONAI_AVAILABLE):
|
|
278
|
+
tools_dict = {
|
|
279
|
+
'CodeDocsSearchTool': CodeDocsSearchTool(),
|
|
280
|
+
'CSVSearchTool': CSVSearchTool(),
|
|
281
|
+
'DirectorySearchTool': DirectorySearchTool(),
|
|
282
|
+
'DOCXSearchTool': DOCXSearchTool(),
|
|
283
|
+
'DirectoryReadTool': DirectoryReadTool(),
|
|
284
|
+
'FileReadTool': FileReadTool(),
|
|
285
|
+
'TXTSearchTool': TXTSearchTool(),
|
|
286
|
+
'JSONSearchTool': JSONSearchTool(),
|
|
287
|
+
'MDXSearchTool': MDXSearchTool(),
|
|
288
|
+
'PDFSearchTool': PDFSearchTool(),
|
|
289
|
+
'RagTool': RagTool(),
|
|
290
|
+
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
|
|
291
|
+
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
|
|
292
|
+
'WebsiteSearchTool': WebsiteSearchTool(),
|
|
293
|
+
'XMLSearchTool': XMLSearchTool(),
|
|
294
|
+
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
|
295
|
+
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
# Add tools from class names
|
|
299
|
+
for tool_class in self.tools:
|
|
300
|
+
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
|
|
301
|
+
tool_name = tool_class.__name__
|
|
302
|
+
tools_dict[tool_name] = tool_class()
|
|
303
|
+
self.logger.debug(f"Added tool: {tool_name}")
|
|
304
|
+
|
|
305
|
+
root_directory = os.getcwd()
|
|
306
|
+
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
307
|
+
tools_dir_path = Path(root_directory) / 'tools'
|
|
308
|
+
|
|
309
|
+
if os.path.isfile(tools_py_path):
|
|
310
|
+
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
|
|
311
|
+
self.logger.debug("tools.py exists in the root directory. Loading tools.py and skipping tools folder.")
|
|
312
|
+
elif tools_dir_path.is_dir():
|
|
313
|
+
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
|
|
314
|
+
self.logger.debug("tools folder exists in the root directory")
|
|
315
|
+
|
|
316
|
+
framework = self.framework or config.get('framework')
|
|
317
|
+
|
|
318
|
+
if framework == "autogen":
|
|
319
|
+
if not AUTOGEN_AVAILABLE:
|
|
320
|
+
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
|
|
321
|
+
if AGENTOPS_AVAILABLE:
|
|
322
|
+
agentops.init(os.environ.get("AGENTOPS_API_KEY"), default_tags=["autogen"])
|
|
323
|
+
return self._run_autogen(config, topic, tools_dict)
|
|
324
|
+
elif framework == "praisonai":
|
|
325
|
+
if not PRAISONAI_AVAILABLE:
|
|
326
|
+
raise ImportError("PraisonAI is not installed. Please install it with 'pip install praisonaiagents'")
|
|
327
|
+
if AGENTOPS_AVAILABLE:
|
|
328
|
+
agentops.init(os.environ.get("AGENTOPS_API_KEY"), default_tags=["praisonai"])
|
|
329
|
+
return self._run_praisonai(config, topic, tools_dict)
|
|
330
|
+
else: # framework=crewai
|
|
331
|
+
if not CREWAI_AVAILABLE:
|
|
332
|
+
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
|
|
333
|
+
if AGENTOPS_AVAILABLE:
|
|
334
|
+
agentops.init(os.environ.get("AGENTOPS_API_KEY"), default_tags=["crewai"])
|
|
335
|
+
return self._run_crewai(config, topic, tools_dict)
|
|
336
|
+
|
|
337
|
+
def _run_autogen(self, config, topic, tools_dict):
|
|
338
|
+
"""
|
|
339
|
+
Run agents using the AutoGen framework.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
config (dict): Configuration dictionary
|
|
343
|
+
topic (str): The topic to process
|
|
344
|
+
tools_dict (dict): Dictionary of available tools
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
str: Result of the agent interactions
|
|
348
|
+
"""
|
|
349
|
+
llm_config = {"config_list": self.config_list}
|
|
350
|
+
|
|
351
|
+
# Set up user proxy agent
|
|
352
|
+
user_proxy = autogen.UserProxyAgent(
|
|
353
|
+
name="User",
|
|
354
|
+
human_input_mode="NEVER",
|
|
355
|
+
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
356
|
+
code_execution_config={
|
|
357
|
+
"work_dir": "coding",
|
|
358
|
+
"use_docker": False,
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
agents = {}
|
|
363
|
+
tasks = []
|
|
364
|
+
|
|
365
|
+
# Create agents and tasks from config
|
|
366
|
+
for role, details in config['roles'].items():
|
|
367
|
+
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
|
|
368
|
+
agent_goal = details['goal'].format(topic=topic)
|
|
369
|
+
|
|
370
|
+
# Create AutoGen assistant agent
|
|
371
|
+
agents[role] = autogen.AssistantAgent(
|
|
372
|
+
name=agent_name,
|
|
373
|
+
llm_config=llm_config,
|
|
374
|
+
system_message=details['backstory'].format(topic=topic) +
|
|
375
|
+
". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
# Add tools to agent if specified
|
|
379
|
+
for tool in details.get('tools', []):
|
|
380
|
+
if tool in tools_dict:
|
|
381
|
+
try:
|
|
382
|
+
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
|
383
|
+
self.logger.debug(f"Found {tool_class.__name__} for {tool}")
|
|
384
|
+
tool_class(agents[role], user_proxy)
|
|
385
|
+
except KeyError:
|
|
386
|
+
self.logger.warning(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
|
|
387
|
+
continue
|
|
388
|
+
|
|
389
|
+
# Prepare tasks
|
|
390
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
391
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
392
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
393
|
+
|
|
394
|
+
chat_task = {
|
|
395
|
+
"recipient": agents[role],
|
|
396
|
+
"message": description_filled,
|
|
397
|
+
"summary_method": "last_msg",
|
|
398
|
+
}
|
|
399
|
+
tasks.append(chat_task)
|
|
400
|
+
|
|
401
|
+
# Execute tasks
|
|
402
|
+
response = user_proxy.initiate_chats(tasks)
|
|
403
|
+
result = "### Output ###\n" + response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
404
|
+
|
|
405
|
+
if AGENTOPS_AVAILABLE:
|
|
406
|
+
agentops.end_session("Success")
|
|
407
|
+
|
|
408
|
+
return result
|
|
409
|
+
|
|
410
|
+
def _run_crewai(self, config, topic, tools_dict):
|
|
411
|
+
"""
|
|
412
|
+
Run agents using the CrewAI framework.
|
|
413
|
+
|
|
414
|
+
Args:
|
|
415
|
+
config (dict): Configuration dictionary
|
|
416
|
+
topic (str): The topic to process
|
|
417
|
+
tools_dict (dict): Dictionary of available tools
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
str: Result of the agent interactions
|
|
421
|
+
"""
|
|
422
|
+
agents = {}
|
|
423
|
+
tasks = []
|
|
424
|
+
tasks_dict = {}
|
|
425
|
+
|
|
426
|
+
# Create agents from config
|
|
427
|
+
for role, details in config['roles'].items():
|
|
428
|
+
role_filled = details['role'].format(topic=topic)
|
|
429
|
+
goal_filled = details['goal'].format(topic=topic)
|
|
430
|
+
backstory_filled = details['backstory'].format(topic=topic)
|
|
431
|
+
|
|
432
|
+
# Get agent tools
|
|
433
|
+
agent_tools = [tools_dict[tool] for tool in details.get('tools', [])
|
|
434
|
+
if tool in tools_dict]
|
|
435
|
+
|
|
436
|
+
# Configure LLM
|
|
437
|
+
llm_model = details.get('llm')
|
|
438
|
+
if llm_model:
|
|
439
|
+
llm = PraisonAIModel(
|
|
440
|
+
model=llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
|
|
441
|
+
).get_model()
|
|
442
|
+
else:
|
|
443
|
+
llm = PraisonAIModel().get_model()
|
|
444
|
+
|
|
445
|
+
# Configure function calling LLM
|
|
446
|
+
function_calling_llm_model = details.get('function_calling_llm')
|
|
447
|
+
if function_calling_llm_model:
|
|
448
|
+
function_calling_llm = PraisonAIModel(
|
|
449
|
+
model=function_calling_llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
|
|
450
|
+
).get_model()
|
|
451
|
+
else:
|
|
452
|
+
function_calling_llm = PraisonAIModel().get_model()
|
|
453
|
+
|
|
454
|
+
# Create CrewAI agent
|
|
455
|
+
agent = Agent(
|
|
456
|
+
role=role_filled,
|
|
457
|
+
goal=goal_filled,
|
|
458
|
+
backstory=backstory_filled,
|
|
459
|
+
tools=agent_tools,
|
|
460
|
+
allow_delegation=details.get('allow_delegation', False),
|
|
461
|
+
llm=llm,
|
|
462
|
+
function_calling_llm=function_calling_llm,
|
|
463
|
+
max_iter=details.get('max_iter', 15),
|
|
464
|
+
max_rpm=details.get('max_rpm'),
|
|
465
|
+
max_execution_time=details.get('max_execution_time'),
|
|
466
|
+
verbose=details.get('verbose', True),
|
|
467
|
+
cache=details.get('cache', True),
|
|
468
|
+
system_template=details.get('system_template'),
|
|
469
|
+
prompt_template=details.get('prompt_template'),
|
|
470
|
+
response_template=details.get('response_template'),
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
# Set agent callback if provided
|
|
474
|
+
if self.agent_callback:
|
|
475
|
+
agent.step_callback = self.agent_callback
|
|
476
|
+
|
|
477
|
+
agents[role] = agent
|
|
478
|
+
|
|
479
|
+
# Create tasks for the agent
|
|
480
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
481
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
482
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
483
|
+
|
|
484
|
+
task = Task(
|
|
485
|
+
description=description_filled,
|
|
486
|
+
expected_output=expected_output_filled,
|
|
487
|
+
agent=agent,
|
|
488
|
+
tools=task_details.get('tools', []),
|
|
489
|
+
async_execution=task_details.get('async_execution', False),
|
|
490
|
+
context=[],
|
|
491
|
+
config=task_details.get('config', {}),
|
|
492
|
+
output_json=task_details.get('output_json'),
|
|
493
|
+
output_pydantic=task_details.get('output_pydantic'),
|
|
494
|
+
output_file=task_details.get('output_file', ""),
|
|
495
|
+
callback=task_details.get('callback'),
|
|
496
|
+
human_input=task_details.get('human_input', False),
|
|
497
|
+
create_directory=task_details.get('create_directory', False)
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
# Set task callback if provided
|
|
501
|
+
if self.task_callback:
|
|
502
|
+
task.callback = self.task_callback
|
|
503
|
+
|
|
504
|
+
tasks.append(task)
|
|
505
|
+
tasks_dict[task_name] = task
|
|
506
|
+
|
|
507
|
+
# Set up task contexts
|
|
508
|
+
for role, details in config['roles'].items():
|
|
509
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
510
|
+
task = tasks_dict[task_name]
|
|
511
|
+
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', [])
|
|
512
|
+
if ctx in tasks_dict]
|
|
513
|
+
task.context = context_tasks
|
|
514
|
+
|
|
515
|
+
# Create and run the crew
|
|
516
|
+
crew = Crew(
|
|
517
|
+
agents=list(agents.values()),
|
|
518
|
+
tasks=tasks,
|
|
519
|
+
verbose=2
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
self.logger.debug("Final Crew Configuration:")
|
|
523
|
+
self.logger.debug(f"Agents: {crew.agents}")
|
|
524
|
+
self.logger.debug(f"Tasks: {crew.tasks}")
|
|
525
|
+
|
|
526
|
+
response = crew.kickoff()
|
|
527
|
+
result = f"### Task Output ###\n{response}"
|
|
528
|
+
|
|
529
|
+
if AGENTOPS_AVAILABLE:
|
|
530
|
+
agentops.end_session("Success")
|
|
531
|
+
|
|
532
|
+
return result
|
|
533
|
+
|
|
534
|
+
def _run_praisonai(self, config, topic, tools_dict):
|
|
535
|
+
"""
|
|
536
|
+
Run agents using the PraisonAI framework.
|
|
537
|
+
"""
|
|
538
|
+
agents = {}
|
|
539
|
+
tasks = []
|
|
540
|
+
tasks_dict = {}
|
|
541
|
+
|
|
542
|
+
# Load tools once at the beginning
|
|
543
|
+
tools_list = self.load_tools_from_tools_py()
|
|
544
|
+
self.logger.debug(f"Loaded tools: {tools_list}")
|
|
545
|
+
|
|
546
|
+
# Create agents from config
|
|
547
|
+
for role, details in config['roles'].items():
|
|
548
|
+
role_filled = details['role'].format(topic=topic)
|
|
549
|
+
goal_filled = details['goal'].format(topic=topic)
|
|
550
|
+
backstory_filled = details['backstory'].format(topic=topic)
|
|
551
|
+
|
|
552
|
+
# Pass all loaded tools to the agent
|
|
553
|
+
agent = PraisonAgent(
|
|
554
|
+
name=role_filled,
|
|
555
|
+
role=role_filled,
|
|
556
|
+
goal=goal_filled,
|
|
557
|
+
backstory=backstory_filled,
|
|
558
|
+
tools=tools_list, # Pass the entire tools list to the agent
|
|
559
|
+
allow_delegation=details.get('allow_delegation', False),
|
|
560
|
+
llm=details.get('llm', {}).get("model", os.environ.get("MODEL_NAME", "gpt-4o")),
|
|
561
|
+
function_calling_llm=details.get('function_calling_llm', {}).get("model", os.environ.get("MODEL_NAME", "gpt-4o")),
|
|
562
|
+
max_iter=details.get('max_iter', 15),
|
|
563
|
+
max_rpm=details.get('max_rpm'),
|
|
564
|
+
max_execution_time=details.get('max_execution_time'),
|
|
565
|
+
verbose=details.get('verbose', True),
|
|
566
|
+
cache=details.get('cache', True),
|
|
567
|
+
system_template=details.get('system_template'),
|
|
568
|
+
prompt_template=details.get('prompt_template'),
|
|
569
|
+
response_template=details.get('response_template'),
|
|
570
|
+
reflect_llm=details.get('reflect_llm', {}).get("model", os.environ.get("MODEL_NAME", "gpt-4o")),
|
|
571
|
+
min_reflect=details.get('min_reflect', 1),
|
|
572
|
+
max_reflect=details.get('max_reflect', 3),
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
if self.agent_callback:
|
|
576
|
+
agent.step_callback = self.agent_callback
|
|
577
|
+
|
|
578
|
+
agents[role] = agent
|
|
579
|
+
self.logger.debug(f"Created agent {role_filled} with tools: {agent.tools}")
|
|
580
|
+
|
|
581
|
+
# Create tasks for the agent
|
|
582
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
583
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
584
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
585
|
+
|
|
586
|
+
task = PraisonTask(
|
|
587
|
+
description=description_filled,
|
|
588
|
+
expected_output=expected_output_filled,
|
|
589
|
+
agent=agent,
|
|
590
|
+
tools=tools_list, # Pass the same tools list to the task
|
|
591
|
+
async_execution=task_details.get('async_execution', False),
|
|
592
|
+
context=[],
|
|
593
|
+
config=task_details.get('config', {}),
|
|
594
|
+
output_json=task_details.get('output_json'),
|
|
595
|
+
output_pydantic=task_details.get('output_pydantic'),
|
|
596
|
+
output_file=task_details.get('output_file', ""),
|
|
597
|
+
callback=task_details.get('callback'),
|
|
598
|
+
create_directory=task_details.get('create_directory', False)
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
self.logger.debug(f"Created task {task_name} with tools: {task.tools}")
|
|
602
|
+
|
|
603
|
+
if self.task_callback:
|
|
604
|
+
task.callback = self.task_callback
|
|
605
|
+
|
|
606
|
+
tasks.append(task)
|
|
607
|
+
tasks_dict[task_name] = task
|
|
608
|
+
|
|
609
|
+
# Set up task contexts
|
|
610
|
+
for role, details in config['roles'].items():
|
|
611
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
612
|
+
task = tasks_dict[task_name]
|
|
613
|
+
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', [])
|
|
614
|
+
if ctx in tasks_dict]
|
|
615
|
+
task.context = context_tasks
|
|
616
|
+
|
|
617
|
+
# Create and run the PraisonAI agents
|
|
618
|
+
memory = config.get('memory', False)
|
|
619
|
+
self.logger.debug(f"Memory: {memory}")
|
|
620
|
+
if config.get('process') == 'hierarchical':
|
|
621
|
+
agents = PraisonAIAgents(
|
|
622
|
+
agents=list(agents.values()),
|
|
623
|
+
tasks=tasks,
|
|
624
|
+
verbose=True,
|
|
625
|
+
process="hierarchical",
|
|
626
|
+
manager_llm=config.get('manager_llm', 'gpt-4o'),
|
|
627
|
+
memory=memory
|
|
628
|
+
)
|
|
629
|
+
else:
|
|
630
|
+
agents = PraisonAIAgents(
|
|
631
|
+
agents=list(agents.values()),
|
|
632
|
+
tasks=tasks,
|
|
633
|
+
verbose=2,
|
|
634
|
+
memory=memory
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
self.logger.debug("Final Configuration:")
|
|
638
|
+
self.logger.debug(f"Agents: {agents.agents}")
|
|
639
|
+
self.logger.debug(f"Tasks: {agents.tasks}")
|
|
640
|
+
|
|
641
|
+
response = agents.start()
|
|
642
|
+
self.logger.debug(f"Result: {response}")
|
|
643
|
+
result = ""
|
|
644
|
+
|
|
645
|
+
if AGENTOPS_AVAILABLE:
|
|
646
|
+
agentops.end_session("Success")
|
|
647
|
+
|
|
648
|
+
return result
|