swarms 7.7.7__py3-none-any.whl → 7.7.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
swarms/structs/agent.py CHANGED
@@ -67,6 +67,7 @@ from swarms.utils.pdf_to_text import pdf_to_text
67
67
  from swarms.utils.str_to_dict import str_to_dict
68
68
  from swarms.prompts.react_base_prompt import REACT_SYS_PROMPT
69
69
  from swarms.prompts.max_loop_prompt import generate_reasoning_prompt
70
+ from swarms.prompts.safety_prompt import SAFETY_PROMPT
70
71
 
71
72
 
72
73
  # Utils
@@ -201,7 +202,7 @@ class Agent:
201
202
  limit_tokens_from_string (Callable): The function to limit tokens from a string
202
203
  custom_tools_prompt (Callable): The custom tools prompt
203
204
  tool_schema (ToolUsageType): The tool schema
204
- output_type (agent_output_type): The output type
205
+ output_type (agent_output_type): The output type. Supported: 'str', 'string', 'list', 'json', 'dict', 'yaml', 'xml'.
205
206
  function_calling_type (str): The function calling type
206
207
  output_cleaner (Callable): The output cleaner function
207
208
  function_calling_format_type (str): The function calling format type
@@ -279,7 +280,6 @@ class Agent:
279
280
 
280
281
  def __init__(
281
282
  self,
282
- agent_id: Optional[str] = agent_id(),
283
283
  id: Optional[str] = agent_id(),
284
284
  llm: Optional[Any] = None,
285
285
  template: Optional[str] = None,
@@ -399,11 +399,11 @@ class Agent:
399
399
  mcp_url: str = None,
400
400
  mcp_urls: List[str] = None,
401
401
  react_on: bool = False,
402
+ safety_prompt_on: bool = False,
402
403
  *args,
403
404
  **kwargs,
404
405
  ):
405
406
  # super().__init__(*args, **kwargs)
406
- self.agent_id = agent_id
407
407
  self.id = id
408
408
  self.llm = llm
409
409
  self.template = template
@@ -522,6 +522,7 @@ class Agent:
522
522
  self.mcp_url = mcp_url
523
523
  self.mcp_urls = mcp_urls
524
524
  self.react_on = react_on
525
+ self.safety_prompt_on = safety_prompt_on
525
526
 
526
527
  self._cached_llm = (
527
528
  None # Add this line to cache the LLM instance
@@ -562,7 +563,7 @@ class Agent:
562
563
  if self.react_on is True:
563
564
  self.system_prompt += REACT_SYS_PROMPT
564
565
 
565
- if self.max_loops > 1:
566
+ if self.max_loops >= 2:
566
567
  self.system_prompt += generate_reasoning_prompt(
567
568
  self.max_loops
568
569
  )
@@ -578,6 +579,9 @@ class Agent:
578
579
  else:
579
580
  prompt = self.system_prompt
580
581
 
582
+ if self.safety_prompt_on is True:
583
+ prompt += SAFETY_PROMPT
584
+
581
585
  # Initialize the short term memory
582
586
  self.short_memory = Conversation(
583
587
  system_prompt=prompt,
@@ -1000,7 +1004,7 @@ class Agent:
1000
1004
 
1001
1005
  Returns:
1002
1006
  Any: The output of the agent.
1003
- (string, list, json, dict, yaml)
1007
+ (string, list, json, dict, yaml, xml)
1004
1008
 
1005
1009
  Examples:
1006
1010
  agent(task="What is the capital of France?")
@@ -1044,14 +1048,14 @@ class Agent:
1044
1048
  ):
1045
1049
  loop_count += 1
1046
1050
 
1047
- if self.max_loops > 1:
1051
+ if self.max_loops >= 2:
1048
1052
  self.short_memory.add(
1049
1053
  role=self.agent_name,
1050
1054
  content=f"Current Internal Reasoning Loop: {loop_count}/{self.max_loops}",
1051
1055
  )
1052
1056
 
1053
1057
  # If it is the final loop, then add the final loop message
1054
- if loop_count == self.max_loops:
1058
+ if loop_count >= 2 and loop_count == self.max_loops:
1055
1059
  self.short_memory.add(
1056
1060
  role=self.agent_name,
1057
1061
  content=f"🎉 Final Internal Reasoning Loop: {loop_count}/{self.max_loops} Prepare your comprehensive response.",
@@ -1222,6 +1226,7 @@ class Agent:
1222
1226
  if self.autosave:
1223
1227
  self.save()
1224
1228
 
1229
+ # Output formatting based on output_type
1225
1230
  return history_output_formatter(
1226
1231
  self.short_memory, type=self.output_type
1227
1232
  )
@@ -2270,7 +2275,7 @@ class Agent:
2270
2275
  time=time.time(),
2271
2276
  tokens=total_tokens,
2272
2277
  response=AgentChatCompletionResponse(
2273
- id=self.agent_id,
2278
+ id=self.id,
2274
2279
  agent_name=self.agent_name,
2275
2280
  object="chat.completion",
2276
2281
  choices=ChatCompletionResponseChoice(
@@ -4,8 +4,6 @@ from concurrent.futures import ThreadPoolExecutor
4
4
  from functools import lru_cache
5
5
  from typing import Any, Callable, Dict, List, Optional, Union
6
6
 
7
- from tqdm import tqdm
8
-
9
7
  from swarms.structs.agent import Agent
10
8
  from swarms.structs.base_swarm import BaseSwarm
11
9
  from swarms.structs.conversation import Conversation
@@ -22,9 +20,7 @@ class ConcurrentWorkflow(BaseSwarm):
22
20
  """
23
21
  Represents a concurrent workflow that executes multiple agents concurrently in a production-grade manner.
24
22
  Features include:
25
- - Interactive model support
26
23
  - Caching for repeated prompts
27
- - Optional progress tracking
28
24
  - Enhanced error handling and retries
29
25
  - Input validation
30
26
 
@@ -39,11 +35,9 @@ class ConcurrentWorkflow(BaseSwarm):
39
35
  return_str_on (bool): Flag indicating whether to return the output as a string. Defaults to False.
40
36
  auto_generate_prompts (bool): Flag indicating whether to auto-generate prompts for agents. Defaults to False.
41
37
  return_entire_history (bool): Flag indicating whether to return the entire conversation history. Defaults to False.
42
- interactive (bool): Flag indicating whether to enable interactive mode. Defaults to False.
43
38
  cache_size (int): The size of the cache. Defaults to 100.
44
39
  max_retries (int): The maximum number of retry attempts. Defaults to 3.
45
40
  retry_delay (float): The delay between retry attempts in seconds. Defaults to 1.0.
46
- show_progress (bool): Flag indicating whether to show progress. Defaults to False.
47
41
 
48
42
  Raises:
49
43
  ValueError: If the list of agents is empty or if the description is empty.
@@ -59,13 +53,10 @@ class ConcurrentWorkflow(BaseSwarm):
59
53
  return_str_on (bool): Flag indicating whether to return the output as a string.
60
54
  auto_generate_prompts (bool): Flag indicating whether to auto-generate prompts for agents.
61
55
  return_entire_history (bool): Flag indicating whether to return the entire conversation history.
62
- interactive (bool): Flag indicating whether to enable interactive mode.
63
56
  cache_size (int): The size of the cache.
64
57
  max_retries (int): The maximum number of retry attempts.
65
58
  retry_delay (float): The delay between retry attempts in seconds.
66
- show_progress (bool): Flag indicating whether to show progress.
67
59
  _cache (dict): The cache for storing agent outputs.
68
- _progress_bar (tqdm): The progress bar for tracking execution.
69
60
  """
70
61
 
71
62
  def __init__(
@@ -80,11 +71,9 @@ class ConcurrentWorkflow(BaseSwarm):
80
71
  return_str_on: bool = False,
81
72
  auto_generate_prompts: bool = False,
82
73
  return_entire_history: bool = False,
83
- interactive: bool = False,
84
74
  cache_size: int = 100,
85
75
  max_retries: int = 3,
86
76
  retry_delay: float = 1.0,
87
- show_progress: bool = False,
88
77
  *args,
89
78
  **kwargs,
90
79
  ):
@@ -107,21 +96,14 @@ class ConcurrentWorkflow(BaseSwarm):
107
96
  self.output_type = output_type
108
97
  self.return_entire_history = return_entire_history
109
98
  self.tasks = [] # Initialize tasks list
110
- self.interactive = interactive
111
99
  self.cache_size = cache_size
112
100
  self.max_retries = max_retries
113
101
  self.retry_delay = retry_delay
114
- self.show_progress = show_progress
115
102
  self._cache = {}
116
- self._progress_bar = None
117
103
 
118
104
  self.reliability_check()
119
105
  self.conversation = Conversation()
120
106
 
121
- def disable_agent_prints(self):
122
- for agent in self.agents:
123
- agent.no_print = False
124
-
125
107
  def reliability_check(self):
126
108
  try:
127
109
  formatter.print_panel(
@@ -186,44 +168,6 @@ class ConcurrentWorkflow(BaseSwarm):
186
168
  """Cached version of agent execution to avoid redundant computations"""
187
169
  return self.agents[agent_id].run(task=task)
188
170
 
189
- def enable_progress_bar(self):
190
- """Enable progress bar display"""
191
- self.show_progress = True
192
-
193
- def disable_progress_bar(self):
194
- """Disable progress bar display"""
195
- if self._progress_bar:
196
- self._progress_bar.close()
197
- self._progress_bar = None
198
- self.show_progress = False
199
-
200
- def _create_progress_bar(self, total: int):
201
- """Create a progress bar for tracking execution"""
202
- if self.show_progress:
203
- try:
204
- self._progress_bar = tqdm(
205
- total=total,
206
- desc="Processing tasks",
207
- unit="task",
208
- disable=not self.show_progress,
209
- ncols=100,
210
- bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}]",
211
- )
212
- except Exception as e:
213
- logger.warning(f"Failed to create progress bar: {e}")
214
- self.show_progress = False
215
- self._progress_bar = None
216
- return self._progress_bar
217
-
218
- def _update_progress(self, increment: int = 1):
219
- """Update the progress bar"""
220
- if self._progress_bar and self.show_progress:
221
- try:
222
- self._progress_bar.update(increment)
223
- except Exception as e:
224
- logger.warning(f"Failed to update progress bar: {e}")
225
- self.disable_progress_bar()
226
-
227
171
  def _validate_input(self, task: str) -> bool:
228
172
  """Validate input task"""
229
173
  if not isinstance(task, str):
@@ -232,38 +176,6 @@ class ConcurrentWorkflow(BaseSwarm):
232
176
  raise ValueError("Task cannot be empty")
233
177
  return True
234
178
 
235
- def _handle_interactive(self, task: str) -> str:
236
- """Handle interactive mode for task input"""
237
- if self.interactive:
238
- from swarms.utils.formatter import formatter
239
-
240
- # Display current task in a panel
241
- formatter.print_panel(
242
- content=f"Current task: {task}",
243
- title="Task Status",
244
- style="bold blue",
245
- )
246
-
247
- # Get user input with formatted prompt
248
- formatter.print_panel(
249
- content="Do you want to modify this task? (y/n/q to quit): ",
250
- title="User Input",
251
- style="bold green",
252
- )
253
- response = input().lower()
254
-
255
- if response == "q":
256
- return None
257
- elif response == "y":
258
- formatter.print_panel(
259
- content="Enter new task: ",
260
- title="New Task Input",
261
- style="bold yellow",
262
- )
263
- new_task = input()
264
- return new_task
265
- return task
266
-
267
179
  def _run_with_retry(
268
180
  self, agent: Agent, task: str, img: str = None
269
181
  ) -> Any:
@@ -286,68 +198,69 @@ class ConcurrentWorkflow(BaseSwarm):
286
198
  self.retry_delay * (attempt + 1)
287
199
  ) # Exponential backoff
288
200
 
201
+ def _process_agent(
202
+ self, agent: Agent, task: str, img: str = None
203
+ ) -> Any:
204
+ """
205
+ Process a single agent with caching and error handling.
206
+
207
+ Args:
208
+ agent: The agent to process
209
+ task: Task to execute
210
+ img: Optional image input
211
+
212
+ Returns:
213
+ The agent's output
214
+ """
215
+ try:
216
+ # Fast path - check cache first
217
+ cache_key = f"{task}_{agent.agent_name}"
218
+ if cache_key in self._cache:
219
+ output = self._cache[cache_key]
220
+ else:
221
+ # Slow path - run agent and update cache
222
+ output = self._run_with_retry(agent, task, img)
223
+
224
+ if len(self._cache) >= self.cache_size:
225
+ self._cache.pop(next(iter(self._cache)))
226
+
227
+ self._cache[cache_key] = output
228
+
229
+ return output
230
+ except Exception as e:
231
+ logger.error(
232
+ f"Error running agent {agent.agent_name}: {e}"
233
+ )
234
+ raise
235
+
289
236
  def _run(
290
237
  self, task: str, img: str = None, *args, **kwargs
291
238
  ) -> Union[Dict[str, Any], str]:
292
239
  """
293
- Enhanced run method with caching, progress tracking, and better error handling
240
+ Enhanced run method with parallel execution.
294
241
  """
295
-
296
- # Validate and potentially modify task
242
+ # Fast validation
297
243
  self._validate_input(task)
298
- task = self._handle_interactive(task)
299
-
300
- # Add task to conversation
301
244
  self.conversation.add("User", task)
302
245
 
303
- # Create progress bar if enabled
304
- if self.show_progress:
305
- self._create_progress_bar(len(self.agents))
306
-
307
- def run_agent(
308
- agent: Agent, task: str, img: str = None
309
- ) -> Any:
310
- try:
311
- # Check cache first
312
- cache_key = f"{task}_{agent.agent_name}"
313
- if cache_key in self._cache:
314
- output = self._cache[cache_key]
315
- else:
316
- output = self._run_with_retry(agent, task, img)
317
- # Update cache
318
- if len(self._cache) >= self.cache_size:
319
- self._cache.pop(next(iter(self._cache)))
320
- self._cache[cache_key] = output
321
-
322
- self._update_progress()
323
- return output
324
- except Exception as e:
325
- logger.error(
326
- f"Error running agent {agent.agent_name}: {e}"
327
- )
328
- self._update_progress()
329
- raise
330
-
331
246
  try:
247
+ # Parallel execution with optimized thread pool
332
248
  with ThreadPoolExecutor(
333
249
  max_workers=self.max_workers
334
250
  ) as executor:
335
- list(
336
- executor.map(
337
- lambda agent: run_agent(agent, task),
338
- self.agents,
251
+ futures = [
252
+ executor.submit(
253
+ self._process_agent, agent, task, img
339
254
  )
340
- )
341
- finally:
342
- if self._progress_bar and self.show_progress:
343
- try:
344
- self._progress_bar.close()
345
- except Exception as e:
346
- logger.warning(
347
- f"Failed to close progress bar: {e}"
348
- )
349
- finally:
350
- self._progress_bar = None
255
+ for agent in self.agents
256
+ ]
257
+ # Wait for all futures to complete
258
+ for future in futures:
259
+ future.result()
260
+
261
+ except Exception as e:
262
+ logger.error(f"An error occurred during execution: {e}")
263
+ raise e
351
264
 
352
265
  return history_output_formatter(
353
266
  self.conversation,
@@ -362,20 +275,11 @@ class ConcurrentWorkflow(BaseSwarm):
362
275
  **kwargs,
363
276
  ) -> Any:
364
277
  """
365
- Executes the agent's run method on a specified device with optional interactive mode.
366
-
367
- This method attempts to execute the agent's run method on a specified device, either CPU or GPU.
368
- It supports both standard execution and interactive mode where users can modify tasks and continue
369
- the workflow interactively.
278
+ Executes the agent's run method with parallel execution.
370
279
 
371
280
  Args:
372
281
  task (Optional[str], optional): The task to be executed. Defaults to None.
373
282
  img (Optional[str], optional): The image to be processed. Defaults to None.
374
- is_last (bool, optional): Indicates if this is the last task. Defaults to False.
375
- device (str, optional): The device to use for execution. Defaults to "cpu".
376
- device_id (int, optional): The ID of the GPU to use if device is set to "gpu". Defaults to 0.
377
- all_cores (bool, optional): If True, uses all available CPU cores. Defaults to True.
378
- all_gpus (bool, optional): If True, uses all available GPUS. Defaults to True.
379
283
  *args: Additional positional arguments to be passed to the execution method.
380
284
  **kwargs: Additional keyword arguments to be passed to the execution method.
381
285
 
@@ -383,117 +287,27 @@ class ConcurrentWorkflow(BaseSwarm):
383
287
  Any: The result of the execution.
384
288
 
385
289
  Raises:
386
- ValueError: If an invalid device is specified.
290
+ ValueError: If task validation fails.
387
291
  Exception: If any other error occurs during execution.
388
292
  """
389
293
  if task is not None:
390
294
  self.tasks.append(task)
391
295
 
392
296
  try:
393
- # Handle interactive mode
394
- if self.interactive:
395
- current_task = task
396
- loop_count = 0
397
-
398
- while loop_count < self.max_loops:
399
- if (
400
- self.max_loops is not None
401
- and loop_count >= self.max_loops
402
- ):
403
- formatter.print_panel(
404
- content=f"Maximum number of loops ({self.max_loops}) reached.",
405
- title="Session Complete",
406
- style="bold red",
407
- )
408
- break
409
-
410
- if current_task is None:
411
- formatter.print_panel(
412
- content="Enter your task (or 'q' to quit): ",
413
- title="Task Input",
414
- style="bold blue",
415
- )
416
- current_task = input()
417
- if current_task.lower() == "q":
418
- break
419
-
420
- # Run the workflow with the current task
421
- try:
422
- outputs = self._run(
423
- current_task, img, *args, **kwargs
424
- )
425
- formatter.print_panel(
426
- content=str(outputs),
427
- title="Workflow Result",
428
- style="bold green",
429
- )
430
- except Exception as e:
431
- formatter.print_panel(
432
- content=f"Error: {str(e)}",
433
- title="Error",
434
- style="bold red",
435
- )
436
-
437
- # Ask if user wants to continue
438
- formatter.print_panel(
439
- content="Do you want to continue with a new task? (y/n): ",
440
- title="Continue Session",
441
- style="bold yellow",
442
- )
443
- if input().lower() != "y":
444
- break
445
-
446
- current_task = None
447
- loop_count += 1
448
-
449
- formatter.print_panel(
450
- content="Interactive session ended.",
451
- title="Session Complete",
452
- style="bold blue",
453
- )
454
- return outputs
455
- else:
456
- # Standard non-interactive execution
457
- outputs = self._run(task, img, *args, **kwargs)
458
- return outputs
459
-
460
- except ValueError as e:
461
- logger.error(f"Invalid device specified: {e}")
462
- raise e
297
+ outputs = self._run(task, img, *args, **kwargs)
298
+ return outputs
463
299
  except Exception as e:
464
300
  logger.error(f"An error occurred during execution: {e}")
465
301
  raise e
466
302
 
467
303
  def run_batched(self, tasks: List[str]) -> Any:
468
304
  """
469
- Enhanced batched execution with progress tracking
305
+ Enhanced batched execution
470
306
  """
471
307
  if not tasks:
472
308
  raise ValueError("Tasks list cannot be empty")
473
309
 
474
- results = []
475
-
476
- # Create progress bar if enabled
477
- if self.show_progress:
478
- self._create_progress_bar(len(tasks))
479
-
480
- try:
481
- for task in tasks:
482
- result = self.run(task)
483
- results.append(result)
484
- self._update_progress()
485
- finally:
486
- if self._progress_bar and self.show_progress:
487
- try:
488
- self._progress_bar.close()
489
- except Exception as e:
490
- logger.warning(
491
- f"Failed to close progress bar: {e}"
492
- )
493
- finally:
494
- self._progress_bar = None
495
-
496
- return results
310
+ return [self.run(task) for task in tasks]
497
311
 
498
312
  def clear_cache(self):
499
313
  """Clear the task cache"""