PraisonAI 0.1.10__cp312-cp312-manylinux_2_35_x86_64.whl → 1.0.1__cp312-cp312-manylinux_2_35_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/agents_generator.py +288 -206
- praisonai/auto.py +49 -13
- praisonai/cli.py +194 -175
- praisonai/deploy.py +1 -1
- praisonai/inbuilt_tools/__init__.py +24 -2
- praisonai/inbuilt_tools/autogen_tools.py +113 -205
- praisonai/setup/post_install.py +16 -13
- praisonai/setup.py +16 -0
- praisonai/ui/chat.py +27 -31
- praisonai/ui/code.py +26 -29
- {praisonai-0.1.10.dist-info → praisonai-1.0.1.dist-info}/METADATA +108 -13
- {praisonai-0.1.10.dist-info → praisonai-1.0.1.dist-info}/RECORD +15 -14
- {praisonai-0.1.10.dist-info → praisonai-1.0.1.dist-info}/entry_points.txt +0 -1
- {praisonai-0.1.10.dist-info → praisonai-1.0.1.dist-info}/LICENSE +0 -0
- {praisonai-0.1.10.dist-info → praisonai-1.0.1.dist-info}/WHEEL +0 -0
praisonai/agents_generator.py
CHANGED
|
@@ -5,34 +5,55 @@ from .version import __version__
|
|
|
5
5
|
import yaml, os
|
|
6
6
|
from rich import print
|
|
7
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 argparse
|
|
13
8
|
from .auto import AutoGenerator
|
|
14
|
-
from praisonai_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
9
|
from .inbuilt_tools import *
|
|
21
10
|
from .inc import PraisonAIModel
|
|
22
11
|
import inspect
|
|
23
12
|
from pathlib import Path
|
|
24
13
|
import importlib
|
|
25
14
|
import importlib.util
|
|
26
|
-
from praisonai_tools import BaseTool
|
|
27
15
|
import os
|
|
28
16
|
import logging
|
|
29
17
|
|
|
30
|
-
|
|
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
|
+
|
|
24
|
+
try:
|
|
25
|
+
from crewai import Agent, Task, Crew
|
|
26
|
+
from crewai.telemetry import Telemetry
|
|
27
|
+
CREWAI_AVAILABLE = True
|
|
28
|
+
except ImportError:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
import autogen
|
|
33
|
+
AUTOGEN_AVAILABLE = True
|
|
34
|
+
except ImportError:
|
|
35
|
+
pass
|
|
36
|
+
|
|
31
37
|
try:
|
|
32
38
|
import agentops
|
|
33
|
-
|
|
39
|
+
AGENTOPS_AVAILABLE = True
|
|
34
40
|
except ImportError:
|
|
35
|
-
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
# Only try to import praisonai_tools if either CrewAI or AutoGen is available
|
|
44
|
+
if CREWAI_AVAILABLE or AUTOGEN_AVAILABLE:
|
|
45
|
+
try:
|
|
46
|
+
from praisonai_tools import (
|
|
47
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
|
|
48
|
+
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
|
|
49
|
+
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
|
|
50
|
+
YoutubeChannelSearchTool, YoutubeVideoSearchTool, BaseTool
|
|
51
|
+
)
|
|
52
|
+
PRAISONAI_TOOLS_AVAILABLE = True
|
|
53
|
+
except ImportError:
|
|
54
|
+
# If import fails, define BaseTool as a simple base class
|
|
55
|
+
class BaseTool:
|
|
56
|
+
pass
|
|
36
57
|
|
|
37
58
|
os.environ["OTEL_SDK_DISABLED"] = "true"
|
|
38
59
|
|
|
@@ -40,11 +61,14 @@ def noop(*args, **kwargs):
|
|
|
40
61
|
pass
|
|
41
62
|
|
|
42
63
|
def disable_crewai_telemetry():
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
if CREWAI_AVAILABLE:
|
|
65
|
+
for attr in dir(Telemetry):
|
|
66
|
+
if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
|
|
67
|
+
setattr(Telemetry, attr, noop)
|
|
68
|
+
|
|
69
|
+
# Only disable telemetry if CrewAI is available
|
|
70
|
+
if CREWAI_AVAILABLE:
|
|
71
|
+
disable_crewai_telemetry()
|
|
48
72
|
|
|
49
73
|
class AgentsGenerator:
|
|
50
74
|
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
|
|
@@ -86,6 +110,12 @@ class AgentsGenerator:
|
|
|
86
110
|
self.logger = logging.getLogger(__name__)
|
|
87
111
|
self.logger.setLevel(self.log_level)
|
|
88
112
|
|
|
113
|
+
# Validate framework availability
|
|
114
|
+
if framework == "crewai" and not CREWAI_AVAILABLE:
|
|
115
|
+
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
|
|
116
|
+
elif framework == "autogen" and not AUTOGEN_AVAILABLE:
|
|
117
|
+
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
|
|
118
|
+
|
|
89
119
|
def is_function_or_decorated(self, obj):
|
|
90
120
|
"""
|
|
91
121
|
Checks if the given object is a function or has a __call__ method.
|
|
@@ -118,21 +148,21 @@ class AgentsGenerator:
|
|
|
118
148
|
|
|
119
149
|
def load_tools_from_module_class(self, module_path):
|
|
120
150
|
"""
|
|
121
|
-
Loads tools from a specified module path containing classes that inherit from BaseTool
|
|
122
|
-
|
|
123
|
-
Parameters:
|
|
124
|
-
module_path (str): The path to the module containing the tools.
|
|
125
|
-
|
|
126
|
-
Returns:
|
|
127
|
-
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
|
|
128
|
-
|
|
129
|
-
Raises:
|
|
130
|
-
FileNotFoundError: If the specified module path does not exist.
|
|
151
|
+
Loads tools from a specified module path containing classes that inherit from BaseTool
|
|
152
|
+
or are part of langchain_community.tools package.
|
|
131
153
|
"""
|
|
132
154
|
spec = importlib.util.spec_from_file_location("tools_module", module_path)
|
|
133
155
|
module = importlib.util.module_from_spec(spec)
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
try:
|
|
157
|
+
spec.loader.exec_module(module)
|
|
158
|
+
return {name: obj() for name, obj in inspect.getmembers(module,
|
|
159
|
+
lambda x: inspect.isclass(x) and (
|
|
160
|
+
x.__module__.startswith('langchain_community.tools') or
|
|
161
|
+
(PRAISONAI_TOOLS_AVAILABLE and issubclass(x, BaseTool))
|
|
162
|
+
) and x is not BaseTool)}
|
|
163
|
+
except ImportError as e:
|
|
164
|
+
self.logger.warning(f"Error loading tools from {module_path}: {e}")
|
|
165
|
+
return {}
|
|
136
166
|
|
|
137
167
|
def load_tools_from_package(self, package_path):
|
|
138
168
|
"""
|
|
@@ -188,36 +218,37 @@ class AgentsGenerator:
|
|
|
188
218
|
return
|
|
189
219
|
|
|
190
220
|
topic = config['topic']
|
|
191
|
-
tools_dict = {
|
|
192
|
-
'CodeDocsSearchTool': CodeDocsSearchTool(),
|
|
193
|
-
'CSVSearchTool': CSVSearchTool(),
|
|
194
|
-
'DirectorySearchTool': DirectorySearchTool(),
|
|
195
|
-
'DOCXSearchTool': DOCXSearchTool(),
|
|
196
|
-
'DirectoryReadTool': DirectoryReadTool(),
|
|
197
|
-
'FileReadTool': FileReadTool(),
|
|
198
|
-
# 'GithubSearchTool': GithubSearchTool(),
|
|
199
|
-
# 'SeperDevTool': SeperDevTool(),
|
|
200
|
-
'TXTSearchTool': TXTSearchTool(),
|
|
201
|
-
'JSONSearchTool': JSONSearchTool(),
|
|
202
|
-
'MDXSearchTool': MDXSearchTool(),
|
|
203
|
-
'PDFSearchTool': PDFSearchTool(),
|
|
204
|
-
# 'PGSearchTool': PGSearchTool(),
|
|
205
|
-
'RagTool': RagTool(),
|
|
206
|
-
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
|
|
207
|
-
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
|
|
208
|
-
'WebsiteSearchTool': WebsiteSearchTool(),
|
|
209
|
-
'XMLSearchTool': XMLSearchTool(),
|
|
210
|
-
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
|
211
|
-
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
# Add tools from class names
|
|
215
|
-
for tool_class in self.tools:
|
|
216
|
-
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
|
|
217
|
-
tool_name = tool_class.__name__
|
|
218
|
-
tools_dict[tool_name] = tool_class()
|
|
219
|
-
self.logger.debug(f"Added tool: {tool_name}")
|
|
221
|
+
tools_dict = {}
|
|
220
222
|
|
|
223
|
+
# Only try to use praisonai_tools if it's available and needed
|
|
224
|
+
if PRAISONAI_TOOLS_AVAILABLE and (CREWAI_AVAILABLE or AUTOGEN_AVAILABLE):
|
|
225
|
+
tools_dict = {
|
|
226
|
+
'CodeDocsSearchTool': CodeDocsSearchTool(),
|
|
227
|
+
'CSVSearchTool': CSVSearchTool(),
|
|
228
|
+
'DirectorySearchTool': DirectorySearchTool(),
|
|
229
|
+
'DOCXSearchTool': DOCXSearchTool(),
|
|
230
|
+
'DirectoryReadTool': DirectoryReadTool(),
|
|
231
|
+
'FileReadTool': FileReadTool(),
|
|
232
|
+
'TXTSearchTool': TXTSearchTool(),
|
|
233
|
+
'JSONSearchTool': JSONSearchTool(),
|
|
234
|
+
'MDXSearchTool': MDXSearchTool(),
|
|
235
|
+
'PDFSearchTool': PDFSearchTool(),
|
|
236
|
+
'RagTool': RagTool(),
|
|
237
|
+
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
|
|
238
|
+
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
|
|
239
|
+
'WebsiteSearchTool': WebsiteSearchTool(),
|
|
240
|
+
'XMLSearchTool': XMLSearchTool(),
|
|
241
|
+
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
|
|
242
|
+
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# Add tools from class names
|
|
246
|
+
for tool_class in self.tools:
|
|
247
|
+
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
|
|
248
|
+
tool_name = tool_class.__name__
|
|
249
|
+
tools_dict[tool_name] = tool_class()
|
|
250
|
+
self.logger.debug(f"Added tool: {tool_name}")
|
|
251
|
+
|
|
221
252
|
root_directory = os.getcwd()
|
|
222
253
|
tools_py_path = os.path.join(root_directory, 'tools.py')
|
|
223
254
|
tools_dir_path = Path(root_directory) / 'tools'
|
|
@@ -231,162 +262,213 @@ class AgentsGenerator:
|
|
|
231
262
|
|
|
232
263
|
framework = self.framework or config.get('framework')
|
|
233
264
|
|
|
265
|
+
if framework == "autogen":
|
|
266
|
+
if not AUTOGEN_AVAILABLE:
|
|
267
|
+
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
|
|
268
|
+
if AGENTOPS_AVAILABLE:
|
|
269
|
+
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["autogen"])
|
|
270
|
+
return self._run_autogen(config, topic, tools_dict)
|
|
271
|
+
else: # framework=crewai
|
|
272
|
+
if not CREWAI_AVAILABLE:
|
|
273
|
+
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
|
|
274
|
+
if AGENTOPS_AVAILABLE:
|
|
275
|
+
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["crewai"])
|
|
276
|
+
return self._run_crewai(config, topic, tools_dict)
|
|
277
|
+
|
|
278
|
+
def _run_autogen(self, config, topic, tools_dict):
|
|
279
|
+
"""
|
|
280
|
+
Run agents using the AutoGen framework.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
config (dict): Configuration dictionary
|
|
284
|
+
topic (str): The topic to process
|
|
285
|
+
tools_dict (dict): Dictionary of available tools
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
str: Result of the agent interactions
|
|
289
|
+
"""
|
|
290
|
+
llm_config = {"config_list": self.config_list}
|
|
291
|
+
|
|
292
|
+
# Set up user proxy agent
|
|
293
|
+
user_proxy = autogen.UserProxyAgent(
|
|
294
|
+
name="User",
|
|
295
|
+
human_input_mode="NEVER",
|
|
296
|
+
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
297
|
+
code_execution_config={
|
|
298
|
+
"work_dir": "coding",
|
|
299
|
+
"use_docker": False,
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
|
|
234
303
|
agents = {}
|
|
235
304
|
tasks = []
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
305
|
+
|
|
306
|
+
# Create agents and tasks from config
|
|
307
|
+
for role, details in config['roles'].items():
|
|
308
|
+
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
|
|
309
|
+
agent_goal = details['goal'].format(topic=topic)
|
|
240
310
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
|
|
248
|
-
code_execution_config={
|
|
249
|
-
"work_dir": "coding",
|
|
250
|
-
"use_docker": False,
|
|
251
|
-
},
|
|
252
|
-
# additional setup for the user proxy agent
|
|
311
|
+
# Create AutoGen assistant agent
|
|
312
|
+
agents[role] = autogen.AssistantAgent(
|
|
313
|
+
name=agent_name,
|
|
314
|
+
llm_config=llm_config,
|
|
315
|
+
system_message=details['backstory'].format(topic=topic) +
|
|
316
|
+
". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
253
317
|
)
|
|
254
318
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
llm_config=llm_config,
|
|
262
|
-
system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
|
|
263
|
-
)
|
|
264
|
-
for tool in details.get('tools', []):
|
|
265
|
-
if tool in tools_dict:
|
|
266
|
-
try:
|
|
267
|
-
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
|
268
|
-
print(f"Found {tool_class.__name__} for {tool}")
|
|
269
|
-
except KeyError:
|
|
270
|
-
print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
|
|
271
|
-
continue
|
|
319
|
+
# Add tools to agent if specified
|
|
320
|
+
for tool in details.get('tools', []):
|
|
321
|
+
if tool in tools_dict:
|
|
322
|
+
try:
|
|
323
|
+
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
|
|
324
|
+
self.logger.debug(f"Found {tool_class.__name__} for {tool}")
|
|
272
325
|
tool_class(agents[role], user_proxy)
|
|
326
|
+
except KeyError:
|
|
327
|
+
self.logger.warning(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
|
|
328
|
+
continue
|
|
329
|
+
|
|
330
|
+
# Prepare tasks
|
|
331
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
332
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
333
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
334
|
+
|
|
335
|
+
chat_task = {
|
|
336
|
+
"recipient": agents[role],
|
|
337
|
+
"message": description_filled,
|
|
338
|
+
"summary_method": "last_msg",
|
|
339
|
+
}
|
|
340
|
+
tasks.append(chat_task)
|
|
341
|
+
|
|
342
|
+
# Execute tasks
|
|
343
|
+
response = user_proxy.initiate_chats(tasks)
|
|
344
|
+
result = "### Output ###\n" + response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
345
|
+
|
|
346
|
+
if AGENTOPS_AVAILABLE:
|
|
347
|
+
agentops.end_session("Success")
|
|
348
|
+
|
|
349
|
+
return result
|
|
273
350
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
"summary_method": "last_msg",
|
|
283
|
-
# Additional fields like carryover can be added based on dependencies
|
|
284
|
-
}
|
|
285
|
-
tasks.append(chat_task)
|
|
286
|
-
response = user_proxy.initiate_chats(tasks)
|
|
287
|
-
result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
|
|
288
|
-
if agentops_exists:
|
|
289
|
-
agentops.end_session("Success")
|
|
290
|
-
else: # framework=crewai
|
|
291
|
-
if agentops_exists:
|
|
292
|
-
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["crewai"])
|
|
351
|
+
def _run_crewai(self, config, topic, tools_dict):
|
|
352
|
+
"""
|
|
353
|
+
Run agents using the CrewAI framework.
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
config (dict): Configuration dictionary
|
|
357
|
+
topic (str): The topic to process
|
|
358
|
+
tools_dict (dict): Dictionary of available tools
|
|
293
359
|
|
|
294
|
-
|
|
360
|
+
Returns:
|
|
361
|
+
str: Result of the agent interactions
|
|
362
|
+
"""
|
|
363
|
+
agents = {}
|
|
364
|
+
tasks = []
|
|
365
|
+
tasks_dict = {}
|
|
366
|
+
|
|
367
|
+
# Create agents from config
|
|
368
|
+
for role, details in config['roles'].items():
|
|
369
|
+
role_filled = details['role'].format(topic=topic)
|
|
370
|
+
goal_filled = details['goal'].format(topic=topic)
|
|
371
|
+
backstory_filled = details['backstory'].format(topic=topic)
|
|
295
372
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
else:
|
|
318
|
-
function_calling_llm = PraisonAIModel().get_model()
|
|
319
|
-
|
|
320
|
-
agent = Agent(
|
|
321
|
-
role=role_filled,
|
|
322
|
-
goal=goal_filled,
|
|
323
|
-
backstory=backstory_filled,
|
|
324
|
-
tools=agent_tools,
|
|
325
|
-
allow_delegation=details.get('allow_delegation', False),
|
|
326
|
-
llm=llm,
|
|
327
|
-
function_calling_llm=function_calling_llm,
|
|
328
|
-
max_iter=details.get('max_iter', 15),
|
|
329
|
-
max_rpm=details.get('max_rpm'),
|
|
330
|
-
max_execution_time=details.get('max_execution_time'),
|
|
331
|
-
verbose=details.get('verbose', True),
|
|
332
|
-
cache=details.get('cache', True),
|
|
333
|
-
system_template=details.get('system_template'),
|
|
334
|
-
prompt_template=details.get('prompt_template'),
|
|
335
|
-
response_template=details.get('response_template'),
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
# Set agent callback if provided
|
|
339
|
-
if self.agent_callback:
|
|
340
|
-
agent.step_callback = self.agent_callback
|
|
341
|
-
|
|
342
|
-
agents[role] = agent
|
|
343
|
-
|
|
344
|
-
for task_name, task_details in details.get('tasks', {}).items():
|
|
345
|
-
description_filled = task_details['description'].format(topic=topic)
|
|
346
|
-
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
347
|
-
|
|
348
|
-
task = Task(
|
|
349
|
-
description=description_filled, # Clear, concise statement of what the task entails
|
|
350
|
-
expected_output=expected_output_filled, # Detailed description of what task's completion looks like
|
|
351
|
-
agent=agent, # The agent responsible for the task
|
|
352
|
-
tools=task_details.get('tools', []), # Functions or capabilities the agent can utilize
|
|
353
|
-
async_execution=task_details.get('async_execution') if task_details.get('async_execution') is not None else False, # Execute asynchronously if set
|
|
354
|
-
context=[], ## TODO:
|
|
355
|
-
config=task_details.get('config') if task_details.get('config') is not None else {}, # Additional configuration details
|
|
356
|
-
output_json=task_details.get('output_json') if task_details.get('output_json') is not None else None, # Outputs a JSON object
|
|
357
|
-
output_pydantic=task_details.get('output_pydantic') if task_details.get('output_pydantic') is not None else None, # Outputs a Pydantic model object
|
|
358
|
-
output_file=task_details.get('output_file') if task_details.get('output_file') is not None else "", # Saves the task output to a file
|
|
359
|
-
callback=task_details.get('callback') if task_details.get('callback') is not None else None, # Python callable executed with the task's output
|
|
360
|
-
human_input=task_details.get('human_input') if task_details.get('human_input') is not None else False, # Indicates if the task requires human feedback
|
|
361
|
-
create_directory=task_details.get('create_directory') if task_details.get('create_directory') is not None else False # Indicates if a directory needs to be created
|
|
362
|
-
)
|
|
363
|
-
|
|
364
|
-
# Set tool callback if provided
|
|
365
|
-
if self.task_callback:
|
|
366
|
-
task.callback = self.task_callback
|
|
367
|
-
|
|
368
|
-
tasks.append(task)
|
|
369
|
-
tasks_dict[task_name] = task
|
|
373
|
+
# Get agent tools
|
|
374
|
+
agent_tools = [tools_dict[tool] for tool in details.get('tools', [])
|
|
375
|
+
if tool in tools_dict]
|
|
376
|
+
|
|
377
|
+
# Configure LLM
|
|
378
|
+
llm_model = details.get('llm')
|
|
379
|
+
if llm_model:
|
|
380
|
+
llm = PraisonAIModel(
|
|
381
|
+
model=llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
|
|
382
|
+
).get_model()
|
|
383
|
+
else:
|
|
384
|
+
llm = PraisonAIModel().get_model()
|
|
385
|
+
|
|
386
|
+
# Configure function calling LLM
|
|
387
|
+
function_calling_llm_model = details.get('function_calling_llm')
|
|
388
|
+
if function_calling_llm_model:
|
|
389
|
+
function_calling_llm = PraisonAIModel(
|
|
390
|
+
model=function_calling_llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
|
|
391
|
+
).get_model()
|
|
392
|
+
else:
|
|
393
|
+
function_calling_llm = PraisonAIModel().get_model()
|
|
370
394
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
395
|
+
# Create CrewAI agent
|
|
396
|
+
agent = Agent(
|
|
397
|
+
role=role_filled,
|
|
398
|
+
goal=goal_filled,
|
|
399
|
+
backstory=backstory_filled,
|
|
400
|
+
tools=agent_tools,
|
|
401
|
+
allow_delegation=details.get('allow_delegation', False),
|
|
402
|
+
llm=llm,
|
|
403
|
+
function_calling_llm=function_calling_llm,
|
|
404
|
+
max_iter=details.get('max_iter', 15),
|
|
405
|
+
max_rpm=details.get('max_rpm'),
|
|
406
|
+
max_execution_time=details.get('max_execution_time'),
|
|
407
|
+
verbose=details.get('verbose', True),
|
|
408
|
+
cache=details.get('cache', True),
|
|
409
|
+
system_template=details.get('system_template'),
|
|
410
|
+
prompt_template=details.get('prompt_template'),
|
|
411
|
+
response_template=details.get('response_template'),
|
|
381
412
|
)
|
|
382
413
|
|
|
383
|
-
|
|
384
|
-
self.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
414
|
+
# Set agent callback if provided
|
|
415
|
+
if self.agent_callback:
|
|
416
|
+
agent.step_callback = self.agent_callback
|
|
417
|
+
|
|
418
|
+
agents[role] = agent
|
|
419
|
+
|
|
420
|
+
# Create tasks for the agent
|
|
421
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
422
|
+
description_filled = task_details['description'].format(topic=topic)
|
|
423
|
+
expected_output_filled = task_details['expected_output'].format(topic=topic)
|
|
424
|
+
|
|
425
|
+
task = Task(
|
|
426
|
+
description=description_filled,
|
|
427
|
+
expected_output=expected_output_filled,
|
|
428
|
+
agent=agent,
|
|
429
|
+
tools=task_details.get('tools', []),
|
|
430
|
+
async_execution=task_details.get('async_execution', False),
|
|
431
|
+
context=[],
|
|
432
|
+
config=task_details.get('config', {}),
|
|
433
|
+
output_json=task_details.get('output_json'),
|
|
434
|
+
output_pydantic=task_details.get('output_pydantic'),
|
|
435
|
+
output_file=task_details.get('output_file', ""),
|
|
436
|
+
callback=task_details.get('callback'),
|
|
437
|
+
human_input=task_details.get('human_input', False),
|
|
438
|
+
create_directory=task_details.get('create_directory', False)
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
# Set task callback if provided
|
|
442
|
+
if self.task_callback:
|
|
443
|
+
task.callback = self.task_callback
|
|
444
|
+
|
|
445
|
+
tasks.append(task)
|
|
446
|
+
tasks_dict[task_name] = task
|
|
447
|
+
|
|
448
|
+
# Set up task contexts
|
|
449
|
+
for role, details in config['roles'].items():
|
|
450
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
451
|
+
task = tasks_dict[task_name]
|
|
452
|
+
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', [])
|
|
453
|
+
if ctx in tasks_dict]
|
|
454
|
+
task.context = context_tasks
|
|
455
|
+
|
|
456
|
+
# Create and run the crew
|
|
457
|
+
crew = Crew(
|
|
458
|
+
agents=list(agents.values()),
|
|
459
|
+
tasks=tasks,
|
|
460
|
+
verbose=2
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
self.logger.debug("Final Crew Configuration:")
|
|
464
|
+
self.logger.debug(f"Agents: {crew.agents}")
|
|
465
|
+
self.logger.debug(f"Tasks: {crew.tasks}")
|
|
466
|
+
|
|
467
|
+
response = crew.kickoff()
|
|
468
|
+
result = f"### Task Output ###\n{response}"
|
|
469
|
+
|
|
470
|
+
if AGENTOPS_AVAILABLE:
|
|
471
|
+
agentops.end_session("Success")
|
|
472
|
+
|
|
391
473
|
return result
|
|
392
474
|
|
praisonai/auto.py
CHANGED
|
@@ -7,6 +7,36 @@ import json
|
|
|
7
7
|
import yaml
|
|
8
8
|
from rich import print
|
|
9
9
|
import logging
|
|
10
|
+
|
|
11
|
+
# Framework-specific imports with availability checks
|
|
12
|
+
CREWAI_AVAILABLE = False
|
|
13
|
+
AUTOGEN_AVAILABLE = False
|
|
14
|
+
PRAISONAI_TOOLS_AVAILABLE = False
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from crewai import Agent, Task, Crew
|
|
18
|
+
CREWAI_AVAILABLE = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import autogen
|
|
24
|
+
AUTOGEN_AVAILABLE = True
|
|
25
|
+
except ImportError:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
from praisonai_tools import (
|
|
30
|
+
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool,
|
|
31
|
+
DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool,
|
|
32
|
+
MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool,
|
|
33
|
+
ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
|
|
34
|
+
YoutubeChannelSearchTool, YoutubeVideoSearchTool
|
|
35
|
+
)
|
|
36
|
+
PRAISONAI_TOOLS_AVAILABLE = True
|
|
37
|
+
except ImportError:
|
|
38
|
+
PRAISONAI_TOOLS_AVAILABLE = False
|
|
39
|
+
|
|
10
40
|
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO').upper(), format='%(asctime)s - %(levelname)s - %(message)s')
|
|
11
41
|
|
|
12
42
|
# Define Pydantic models outside of the generate method
|
|
@@ -29,20 +59,26 @@ class AutoGenerator:
|
|
|
29
59
|
"""
|
|
30
60
|
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
|
|
31
61
|
Note: autogen framework is different from this AutoGenerator class.
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
topic (str, optional): The topic for the generated team structure. Defaults to "Movie Story writing about AI".
|
|
35
|
-
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to "test.yaml".
|
|
36
|
-
framework (str, optional): The framework for the generated team structure. Defaults to "crewai".
|
|
37
|
-
config_list (Optional[List[Dict]], optional): A list containing the configuration details for the OpenAI API.
|
|
38
|
-
If None, it defaults to using environment variables or hardcoded values.
|
|
39
|
-
Attributes:
|
|
40
|
-
config_list (list): A list containing the configuration details for the OpenAI API.
|
|
41
|
-
topic (str): The specified topic for the generated team structure.
|
|
42
|
-
agent_file (str): The specified name of the YAML file to save the generated team structure.
|
|
43
|
-
framework (str): The specified framework for the generated team structure.
|
|
44
|
-
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
|
|
45
62
|
"""
|
|
63
|
+
# Validate framework availability and show framework-specific messages
|
|
64
|
+
if framework == "crewai" and not CREWAI_AVAILABLE:
|
|
65
|
+
raise ImportError("""
|
|
66
|
+
CrewAI is not installed. Please install with:
|
|
67
|
+
pip install "praisonai[crewai]"
|
|
68
|
+
""")
|
|
69
|
+
elif framework == "autogen" and not AUTOGEN_AVAILABLE:
|
|
70
|
+
raise ImportError("""
|
|
71
|
+
AutoGen is not installed. Please install with:
|
|
72
|
+
pip install "praisonai[autogen]"
|
|
73
|
+
""")
|
|
74
|
+
|
|
75
|
+
# Only show tools message if using a framework and tools are needed
|
|
76
|
+
if (framework in ["crewai", "autogen"]) and not PRAISONAI_TOOLS_AVAILABLE:
|
|
77
|
+
logging.warning(f"""
|
|
78
|
+
Tools are not available for {framework}. To use tools, install:
|
|
79
|
+
pip install "praisonai[{framework}]"
|
|
80
|
+
""")
|
|
81
|
+
|
|
46
82
|
self.config_list = config_list or [
|
|
47
83
|
{
|
|
48
84
|
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"),
|