PraisonAI 0.1.9__cp312-cp312-manylinux_2_35_x86_64.whl → 1.0.0__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.

@@ -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
- agentops_exists = False
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
- agentops_exists = True
39
+ AGENTOPS_AVAILABLE = True
34
40
  except ImportError:
35
- agentops_exists = False
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,14 +61,17 @@ def noop(*args, **kwargs):
40
61
  pass
41
62
 
42
63
  def disable_crewai_telemetry():
43
- for attr in dir(Telemetry):
44
- if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
45
- setattr(Telemetry, attr, noop)
46
-
47
- disable_crewai_telemetry()
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
- def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None):
74
+ def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
51
75
  """
52
76
  Initialize the AgentsGenerator object.
53
77
 
@@ -59,6 +83,7 @@ class AgentsGenerator:
59
83
  agent_callback (callable, optional): A callback function to be executed after each agent step.
60
84
  task_callback (callable, optional): A callback function to be executed after each tool run.
61
85
  agent_yaml (str, optional): The content of the YAML file. Defaults to None.
86
+ tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.
62
87
 
63
88
  Attributes:
64
89
  agent_file (str): The path to the agent file.
@@ -67,6 +92,7 @@ class AgentsGenerator:
67
92
  log_level (int): The logging level to use.
68
93
  agent_callback (callable, optional): A callback function to be executed after each agent step.
69
94
  task_callback (callable, optional): A callback function to be executed after each tool run.
95
+ tools (dict): A dictionary containing the tools to be used for the agents.
70
96
  """
71
97
  self.agent_file = agent_file
72
98
  self.framework = framework
@@ -75,6 +101,7 @@ class AgentsGenerator:
75
101
  self.agent_callback = agent_callback
76
102
  self.task_callback = task_callback
77
103
  self.agent_yaml = agent_yaml
104
+ self.tools = tools or [] # Store tool class names as a list
78
105
  self.log_level = log_level or logging.getLogger().getEffectiveLevel()
79
106
  if self.log_level == logging.NOTSET:
80
107
  self.log_level = os.environ.get('LOGLEVEL', 'INFO').upper()
@@ -83,6 +110,12 @@ class AgentsGenerator:
83
110
  self.logger = logging.getLogger(__name__)
84
111
  self.logger.setLevel(self.log_level)
85
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
+
86
119
  def is_function_or_decorated(self, obj):
87
120
  """
88
121
  Checks if the given object is a function or has a __call__ method.
@@ -115,21 +148,21 @@ class AgentsGenerator:
115
148
 
116
149
  def load_tools_from_module_class(self, module_path):
117
150
  """
118
- Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
119
-
120
- Parameters:
121
- module_path (str): The path to the module containing the tools.
122
-
123
- Returns:
124
- dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
125
-
126
- Raises:
127
- 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.
128
153
  """
129
154
  spec = importlib.util.spec_from_file_location("tools_module", module_path)
130
155
  module = importlib.util.module_from_spec(spec)
131
- spec.loader.exec_module(module)
132
- return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith('langchain_community.tools') or issubclass(x, BaseTool)) and x is not BaseTool)}
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 {}
133
166
 
134
167
  def load_tools_from_package(self, package_path):
135
168
  """
@@ -185,28 +218,37 @@ class AgentsGenerator:
185
218
  return
186
219
 
187
220
  topic = config['topic']
188
- tools_dict = {
189
- 'CodeDocsSearchTool': CodeDocsSearchTool(),
190
- 'CSVSearchTool': CSVSearchTool(),
191
- 'DirectorySearchTool': DirectorySearchTool(),
192
- 'DOCXSearchTool': DOCXSearchTool(),
193
- 'DirectoryReadTool': DirectoryReadTool(),
194
- 'FileReadTool': FileReadTool(),
195
- # 'GithubSearchTool': GithubSearchTool(),
196
- # 'SeperDevTool': SeperDevTool(),
197
- 'TXTSearchTool': TXTSearchTool(),
198
- 'JSONSearchTool': JSONSearchTool(),
199
- 'MDXSearchTool': MDXSearchTool(),
200
- 'PDFSearchTool': PDFSearchTool(),
201
- # 'PGSearchTool': PGSearchTool(),
202
- 'RagTool': RagTool(),
203
- 'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
204
- 'ScrapeWebsiteTool': ScrapeWebsiteTool(),
205
- 'WebsiteSearchTool': WebsiteSearchTool(),
206
- 'XMLSearchTool': XMLSearchTool(),
207
- 'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
208
- 'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
209
- }
221
+ tools_dict = {}
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
+
210
252
  root_directory = os.getcwd()
211
253
  tools_py_path = os.path.join(root_directory, 'tools.py')
212
254
  tools_dir_path = Path(root_directory) / 'tools'
@@ -220,162 +262,213 @@ class AgentsGenerator:
220
262
 
221
263
  framework = self.framework or config.get('framework')
222
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
+
223
303
  agents = {}
224
304
  tasks = []
225
- if framework == "autogen":
226
- # Load the LLM configuration dynamically
227
- # print(self.config_list)
228
- llm_config = {"config_list": self.config_list}
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)
229
310
 
230
- if agentops_exists:
231
- agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["autogen"])
232
- # Assuming the user proxy agent is set up as per your requirements
233
- user_proxy = autogen.UserProxyAgent(
234
- name="User",
235
- human_input_mode="NEVER",
236
- is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
237
- code_execution_config={
238
- "work_dir": "coding",
239
- "use_docker": False,
240
- },
241
- # 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.",
242
317
  )
243
318
 
244
- for role, details in config['roles'].items():
245
- agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
246
- agent_goal = details['goal'].format(topic=topic)
247
- # Creating an AssistantAgent for each role dynamically
248
- agents[role] = autogen.AssistantAgent(
249
- name=agent_name,
250
- llm_config=llm_config,
251
- system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
252
- )
253
- for tool in details.get('tools', []):
254
- if tool in tools_dict:
255
- try:
256
- tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
257
- print(f"Found {tool_class.__name__} for {tool}")
258
- except KeyError:
259
- print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
260
- 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}")
261
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
262
350
 
263
- # Preparing tasks for initiate_chats
264
- for task_name, task_details in details.get('tasks', {}).items():
265
- description_filled = task_details['description'].format(topic=topic)
266
- expected_output_filled = task_details['expected_output'].format(topic=topic)
267
-
268
- chat_task = {
269
- "recipient": agents[role],
270
- "message": description_filled,
271
- "summary_method": "last_msg",
272
- # Additional fields like carryover can be added based on dependencies
273
- }
274
- tasks.append(chat_task)
275
- response = user_proxy.initiate_chats(tasks)
276
- result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
277
- if agentops_exists:
278
- agentops.end_session("Success")
279
- else: # framework=crewai
280
- if agentops_exists:
281
- 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
282
359
 
283
- tasks_dict = {}
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)
284
372
 
285
- for role, details in config['roles'].items():
286
- role_filled = details['role'].format(topic=topic)
287
- goal_filled = details['goal'].format(topic=topic)
288
- backstory_filled = details['backstory'].format(topic=topic)
289
-
290
- # Adding tools to the agent if exists
291
- agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
292
-
293
- llm_model = details.get('llm') # Get the llm configuration
294
- if llm_model:
295
- llm = PraisonAIModel(
296
- model=llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
297
- ).get_model()
298
- else:
299
- llm = PraisonAIModel().get_model()
300
-
301
- function_calling_llm_model = details.get('function_calling_llm')
302
- if function_calling_llm_model:
303
- function_calling_llm = PraisonAIModel(
304
- model=function_calling_llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
305
- ).get_model()
306
- else:
307
- function_calling_llm = PraisonAIModel().get_model()
308
-
309
- agent = Agent(
310
- role=role_filled,
311
- goal=goal_filled,
312
- backstory=backstory_filled,
313
- tools=agent_tools,
314
- allow_delegation=details.get('allow_delegation', False),
315
- llm=llm,
316
- function_calling_llm=function_calling_llm,
317
- max_iter=details.get('max_iter', 15),
318
- max_rpm=details.get('max_rpm'),
319
- max_execution_time=details.get('max_execution_time'),
320
- verbose=details.get('verbose', True),
321
- cache=details.get('cache', True),
322
- system_template=details.get('system_template'),
323
- prompt_template=details.get('prompt_template'),
324
- response_template=details.get('response_template'),
325
- )
326
-
327
- # Set agent callback if provided
328
- if self.agent_callback:
329
- agent.step_callback = self.agent_callback
330
-
331
- agents[role] = agent
332
-
333
- for task_name, task_details in details.get('tasks', {}).items():
334
- description_filled = task_details['description'].format(topic=topic)
335
- expected_output_filled = task_details['expected_output'].format(topic=topic)
336
-
337
- task = Task(
338
- description=description_filled, # Clear, concise statement of what the task entails
339
- expected_output=expected_output_filled, # Detailed description of what task's completion looks like
340
- agent=agent, # The agent responsible for the task
341
- tools=task_details.get('tools', []), # Functions or capabilities the agent can utilize
342
- async_execution=task_details.get('async_execution') if task_details.get('async_execution') is not None else False, # Execute asynchronously if set
343
- context=[], ## TODO:
344
- config=task_details.get('config') if task_details.get('config') is not None else {}, # Additional configuration details
345
- output_json=task_details.get('output_json') if task_details.get('output_json') is not None else None, # Outputs a JSON object
346
- output_pydantic=task_details.get('output_pydantic') if task_details.get('output_pydantic') is not None else None, # Outputs a Pydantic model object
347
- output_file=task_details.get('output_file') if task_details.get('output_file') is not None else "", # Saves the task output to a file
348
- callback=task_details.get('callback') if task_details.get('callback') is not None else None, # Python callable executed with the task's output
349
- 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
350
- 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
351
- )
352
-
353
- # Set tool callback if provided
354
- if self.task_callback:
355
- task.callback = self.task_callback
356
-
357
- tasks.append(task)
358
- 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()
359
394
 
360
- for role, details in config['roles'].items():
361
- for task_name, task_details in details.get('tasks', {}).items():
362
- task = tasks_dict[task_name]
363
- context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', []) if ctx in tasks_dict]
364
- task.context = context_tasks
365
-
366
- crew = Crew(
367
- agents=list(agents.values()),
368
- tasks=tasks,
369
- verbose=2
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'),
370
412
  )
371
413
 
372
- self.logger.debug("Final Crew Configuration:")
373
- self.logger.debug(f"Agents: {crew.agents}")
374
- self.logger.debug(f"Tasks: {crew.tasks}")
375
-
376
- response = crew.kickoff()
377
- result = f"### Task Output ###\n{response}"
378
- if agentops_exists:
379
- agentops.end_session("Success")
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
+
380
473
  return result
381
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"),