swarms 7.6.2__py3-none-any.whl → 7.6.5__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.
Files changed (34) hide show
  1. swarms/__init__.py +1 -0
  2. swarms/agents/__init__.py +0 -3
  3. swarms/agents/flexion_agent.py +2 -1
  4. swarms/client/__init__.py +15 -0
  5. swarms/prompts/multi_agent_collab_prompt.py +313 -0
  6. swarms/structs/__init__.py +5 -17
  7. swarms/structs/agent.py +219 -255
  8. swarms/structs/base_swarm.py +0 -7
  9. swarms/structs/concurrent_workflow.py +1 -1
  10. swarms/structs/conversation.py +16 -2
  11. swarms/structs/de_hallucination_swarm.py +8 -4
  12. swarms/structs/groupchat.py +80 -84
  13. swarms/structs/hybrid_hiearchical_peer_swarm.py +23 -40
  14. swarms/structs/multi_agent_exec.py +63 -139
  15. swarms/structs/rearrange.py +65 -204
  16. swarms/structs/sequential_workflow.py +34 -47
  17. swarms/structs/swarm_router.py +2 -1
  18. swarms/telemetry/bootup.py +19 -38
  19. swarms/telemetry/main.py +56 -20
  20. swarms/tools/mcp_integration.py +321 -483
  21. swarms/utils/auto_download_check_packages.py +2 -2
  22. swarms/utils/disable_logging.py +0 -17
  23. swarms/utils/history_output_formatter.py +8 -3
  24. swarms/utils/litellm_wrapper.py +117 -1
  25. swarms/utils/vllm_wrapper.py +146 -0
  26. {swarms-7.6.2.dist-info → swarms-7.6.5.dist-info}/METADATA +1 -5
  27. {swarms-7.6.2.dist-info → swarms-7.6.5.dist-info}/RECORD +31 -31
  28. swarms/structs/auto_swarm.py +0 -229
  29. swarms/utils/agent_ops_check.py +0 -26
  30. swarms/utils/pandas_utils.py +0 -92
  31. /swarms/{structs/swarms_api.py → client/main.py} +0 -0
  32. {swarms-7.6.2.dist-info → swarms-7.6.5.dist-info}/LICENSE +0 -0
  33. {swarms-7.6.2.dist-info → swarms-7.6.5.dist-info}/WHEEL +0 -0
  34. {swarms-7.6.2.dist-info → swarms-7.6.5.dist-info}/entry_points.txt +0 -0
swarms/structs/agent.py CHANGED
@@ -6,7 +6,6 @@ import random
6
6
  import threading
7
7
  import time
8
8
  import uuid
9
-
10
9
  from concurrent.futures import ThreadPoolExecutor
11
10
  from datetime import datetime
12
11
  from typing import (
@@ -39,10 +38,8 @@ from swarms.schemas.base_schemas import (
39
38
  ChatCompletionResponseChoice,
40
39
  ChatMessageResponse,
41
40
  )
42
- from swarms.structs.concat import concat_strings
41
+ from swarms.structs.agent_roles import agent_roles
43
42
  from swarms.structs.conversation import Conversation
44
-
45
- # from swarms.structs.multi_agent_exec import run_agents_concurrently
46
43
  from swarms.structs.safe_loading import (
47
44
  SafeLoaderUtils,
48
45
  SafeStateManager,
@@ -54,11 +51,19 @@ from swarms.utils.any_to_str import any_to_str
54
51
  from swarms.utils.data_to_text import data_to_text
55
52
  from swarms.utils.file_processing import create_file_in_folder
56
53
  from swarms.utils.formatter import formatter
54
+ from swarms.utils.history_output_formatter import (
55
+ history_output_formatter,
56
+ )
57
57
  from swarms.utils.litellm_tokenizer import count_tokens
58
58
  from swarms.utils.pdf_to_text import pdf_to_text
59
- from swarms.structs.agent_roles import agent_roles
60
59
  from swarms.utils.str_to_dict import str_to_dict
61
60
 
61
+ from swarms.tools.mcp_integration import (
62
+ batch_mcp_flow,
63
+ mcp_flow_get_tool_schema,
64
+ MCPServerSseParams,
65
+ )
66
+
62
67
 
63
68
  # Utils
64
69
  # Custom stopping condition
@@ -353,6 +358,7 @@ class Agent:
353
358
  role: agent_roles = "worker",
354
359
  no_print: bool = False,
355
360
  tools_list_dictionary: Optional[List[Dict[str, Any]]] = None,
361
+ mcp_servers: List[MCPServerSseParams] = [],
356
362
  *args,
357
363
  **kwargs,
358
364
  ):
@@ -472,13 +478,23 @@ class Agent:
472
478
  self.role = role
473
479
  self.no_print = no_print
474
480
  self.tools_list_dictionary = tools_list_dictionary
481
+ self.mcp_servers = mcp_servers
482
+
483
+ if (
484
+ self.agent_name is not None
485
+ or self.agent_description is not None
486
+ ):
487
+ prompt = f"Your Name: {self.agent_name} \n\n Your Description: {self.agent_description} \n\n {system_prompt}"
488
+ else:
489
+ prompt = system_prompt
475
490
 
476
491
  # Initialize the short term memory
477
492
  self.short_memory = Conversation(
478
- system_prompt=system_prompt,
493
+ system_prompt=prompt,
479
494
  time_enabled=False,
480
495
  user=user_name,
481
496
  rules=rules,
497
+ token_count=False,
482
498
  *args,
483
499
  **kwargs,
484
500
  )
@@ -504,24 +520,10 @@ class Agent:
504
520
  tool_system_prompt=tool_system_prompt,
505
521
  )
506
522
 
507
- # The max_loops will be set dynamically if the dynamic_loop
508
- if self.dynamic_loops is True:
509
- logger.info("Dynamic loops enabled")
510
- self.max_loops = "auto"
511
-
512
- # If multimodal = yes then set the sop to the multimodal sop
513
- if self.multi_modal is True:
514
- self.sop = MULTI_MODAL_AUTO_AGENT_SYSTEM_PROMPT_1
515
-
516
- # If the preset stopping token is enabled then set the stopping token to the preset stopping token
517
- if preset_stopping_token is not None:
518
- self.stopping_token = "<DONE>"
519
-
520
- # If the docs exist then ingest the docs
521
- # if exists(self.docs):
522
- # threading.Thread(
523
- # target=self.ingest_docs, args=(self.docs)
524
- # ).start()
523
+ # Some common configuration settings
524
+ threading.Thread(
525
+ target=self.setup_config, daemon=True
526
+ ).start()
525
527
 
526
528
  # If docs folder exists then get the docs from docs folder
527
529
  if exists(self.docs_folder):
@@ -567,10 +569,6 @@ class Agent:
567
569
  if exists(self.sop) or exists(self.sop_list):
568
570
  threading.Thread(target=self.handle_sop_ops()).start()
569
571
 
570
- # If agent_ops is on => activate agentops
571
- if agent_ops_on is True:
572
- threading.Thread(target=self.activate_agentops()).start()
573
-
574
572
  # Many steps
575
573
  self.agent_output = ManySteps(
576
574
  agent_id=agent_id,
@@ -594,6 +592,12 @@ class Agent:
594
592
  if self.llm is None:
595
593
  self.llm = self.llm_handling()
596
594
 
595
+ if (
596
+ self.tools_list_dictionary is None
597
+ and self.mcp_servers is not None
598
+ ):
599
+ self.tools_list_dictionary = self.mcp_tool_handling()
600
+
597
601
  def llm_handling(self):
598
602
  from swarms.utils.litellm_wrapper import LiteLLM
599
603
 
@@ -634,12 +638,90 @@ class Agent:
634
638
  temperature=self.temperature,
635
639
  max_tokens=self.max_tokens,
636
640
  system_prompt=self.system_prompt,
641
+ stream=self.streaming_on,
637
642
  )
638
643
  return llm
639
644
  except Exception as e:
640
645
  logger.error(f"Error in llm_handling: {e}")
641
646
  return None
642
647
 
648
+ def mcp_execution_flow(self, response: any):
649
+ """
650
+ Executes the MCP (Model Context Protocol) flow based on the provided response.
651
+
652
+ This method takes a response, converts it from a string to a dictionary format,
653
+ and checks for the presence of a tool name or a name in the response. If either
654
+ is found, it retrieves the tool name and proceeds to call the batch_mcp_flow
655
+ function to execute the corresponding tool actions.
656
+
657
+ Args:
658
+ response (any): The response to be processed, which can be in string format
659
+ that represents a dictionary.
660
+
661
+ Returns:
662
+ The output from the batch_mcp_flow function, which contains the results of
663
+ the tool execution. If an error occurs during processing, it logs the error
664
+ and returns None.
665
+
666
+ Raises:
667
+ Exception: Logs any exceptions that occur during the execution flow.
668
+ """
669
+ try:
670
+ response = str_to_dict(response)
671
+
672
+ tool_output = batch_mcp_flow(
673
+ self.mcp_servers,
674
+ function_call=response,
675
+ )
676
+
677
+ return tool_output
678
+ except Exception as e:
679
+ logger.error(f"Error in mcp_execution_flow: {e}")
680
+ return None
681
+
682
+ def mcp_tool_handling(self):
683
+ """
684
+ Handles the retrieval of tool schemas from the MCP servers.
685
+
686
+ This method iterates over the list of MCP servers, retrieves the tool schema
687
+ for each server using the mcp_flow_get_tool_schema function, and compiles
688
+ these schemas into a list. The resulting list is stored in the
689
+ tools_list_dictionary attribute.
690
+
691
+ Returns:
692
+ list: A list of tool schemas retrieved from the MCP servers. If an error
693
+ occurs during the retrieval process, it logs the error and returns None.
694
+
695
+ Raises:
696
+ Exception: Logs any exceptions that occur during the tool handling process.
697
+ """
698
+ try:
699
+ self.tools_list_dictionary = []
700
+
701
+ for mcp_server in self.mcp_servers:
702
+ tool_schema = mcp_flow_get_tool_schema(mcp_server)
703
+ self.tools_list_dictionary.append(tool_schema)
704
+
705
+ print(self.tools_list_dictionary)
706
+ return self.tools_list_dictionary
707
+ except Exception as e:
708
+ logger.error(f"Error in mcp_tool_handling: {e}")
709
+ return None
710
+
711
+ def setup_config(self):
712
+ # The max_loops will be set dynamically if the dynamic_loop
713
+ if self.dynamic_loops is True:
714
+ logger.info("Dynamic loops enabled")
715
+ self.max_loops = "auto"
716
+
717
+ # If multimodal = yes then set the sop to the multimodal sop
718
+ if self.multi_modal is True:
719
+ self.sop = MULTI_MODAL_AUTO_AGENT_SYSTEM_PROMPT_1
720
+
721
+ # If the preset stopping token is enabled then set the stopping token to the preset stopping token
722
+ if self.preset_stopping_token is not None:
723
+ self.stopping_token = "<DONE>"
724
+
643
725
  def prepare_tools_list_dictionary(self):
644
726
  import json
645
727
 
@@ -775,18 +857,6 @@ class Agent:
775
857
  """,
776
858
  )
777
859
 
778
- def loop_count_print(
779
- self, loop_count: int, max_loops: int
780
- ) -> None:
781
- """loop_count_print summary
782
-
783
- Args:
784
- loop_count (_type_): _description_
785
- max_loops (_type_): _description_
786
- """
787
- logger.info(f"\nLoop {loop_count} of {max_loops}")
788
- print("\n")
789
-
790
860
  # Check parameters
791
861
  def check_parameters(self):
792
862
  if self.llm is None:
@@ -837,8 +907,6 @@ class Agent:
837
907
  try:
838
908
  self.check_if_no_prompt_then_autogenerate(task)
839
909
 
840
- self.agent_output.task = task
841
-
842
910
  # Add task to memory
843
911
  self.short_memory.add(role=self.user_name, content=task)
844
912
 
@@ -848,17 +916,17 @@ class Agent:
848
916
 
849
917
  # Set the loop count
850
918
  loop_count = 0
919
+
851
920
  # Clear the short memory
852
921
  response = None
853
- all_responses = []
854
922
 
855
923
  # Query the long term memory first for the context
856
924
  if self.long_term_memory is not None:
857
925
  self.memory_query(task)
858
926
 
859
- # Print the user's request
860
-
927
+ # Autosave
861
928
  if self.autosave:
929
+ log_agent_data(self.to_dict())
862
930
  self.save()
863
931
 
864
932
  # Print the request
@@ -873,8 +941,11 @@ class Agent:
873
941
  or loop_count < self.max_loops
874
942
  ):
875
943
  loop_count += 1
876
- self.loop_count_print(loop_count, self.max_loops)
877
- print("\n")
944
+
945
+ # self.short_memory.add(
946
+ # role=f"{self.agent_name}",
947
+ # content=f"Internal Reasoning Loop: {loop_count} of {self.max_loops}",
948
+ # )
878
949
 
879
950
  # Dynamic temperature
880
951
  if self.dynamic_temperature_enabled is True:
@@ -905,48 +976,24 @@ class Agent:
905
976
  if img is None
906
977
  else (task_prompt, img, *args)
907
978
  )
979
+
980
+ # Call the LLM
908
981
  response = self.call_llm(
909
982
  *response_args, **kwargs
910
983
  )
911
984
 
912
985
  # Convert to a str if the response is not a str
913
- response = self.llm_output_parser(response)
986
+ response = self.parse_llm_output(response)
914
987
 
915
- # if correct_answer is not None:
916
- # if correct_answer not in response:
917
- # logger.info("Correct answer found in response")
918
- # # break
988
+ self.short_memory.add(
989
+ role=self.agent_name, content=response
990
+ )
919
991
 
920
992
  # Print
921
- if self.no_print is False:
922
- if self.streaming_on is True:
923
- # self.stream_response(response)
924
- formatter.print_panel_token_by_token(
925
- f"{self.agent_name}: {response}",
926
- title=f"Agent Name: {self.agent_name} [Max Loops: {loop_count}]",
927
- )
928
- else:
929
- # logger.info(f"Response: {response}")
930
- formatter.print_panel(
931
- f"{self.agent_name}: {response}",
932
- f"Agent Name {self.agent_name} [Max Loops: {loop_count} ]",
933
- )
934
-
935
- # Check if response is a dictionary and has 'choices' key
936
- if (
937
- isinstance(response, dict)
938
- and "choices" in response
939
- ):
940
- response = response["choices"][0][
941
- "message"
942
- ]["content"]
943
- elif isinstance(response, str):
944
- # If response is already a string, use it as is
945
- pass
946
- else:
947
- raise ValueError(
948
- f"Unexpected response format: {type(response)}"
949
- )
993
+ self.pretty_print(response, loop_count)
994
+
995
+ # Output Cleaner
996
+ self.output_cleaner_op(response)
950
997
 
951
998
  # Check and execute tools
952
999
  if self.tools is not None:
@@ -978,34 +1025,7 @@ class Agent:
978
1025
  role=self.agent_name, content=out
979
1026
  )
980
1027
 
981
- # Add the response to the memory
982
- self.short_memory.add(
983
- role=self.agent_name, content=response
984
- )
985
-
986
- # Add to all responses
987
- all_responses.append(response)
988
-
989
- # # TODO: Implement reliability check
990
-
991
- if self.evaluator:
992
- logger.info("Evaluating response...")
993
- evaluated_response = self.evaluator(
994
- response
995
- )
996
- print(
997
- "Evaluated Response:"
998
- f" {evaluated_response}"
999
- )
1000
- self.short_memory.add(
1001
- role="Evaluator",
1002
- content=evaluated_response,
1003
- )
1004
-
1005
- # Sentiment analysis
1006
- if self.sentiment_analyzer:
1007
- logger.info("Analyzing sentiment...")
1008
- self.sentiment_analysis_handler(response)
1028
+ self.sentiment_and_evaluator(response)
1009
1029
 
1010
1030
  success = True # Mark as successful to exit the retry loop
1011
1031
 
@@ -1062,7 +1082,7 @@ class Agent:
1062
1082
  break
1063
1083
 
1064
1084
  self.short_memory.add(
1065
- role=self.user_name, content=user_input
1085
+ role="User", content=user_input
1066
1086
  )
1067
1087
 
1068
1088
  if self.loop_interval:
@@ -1077,91 +1097,14 @@ class Agent:
1077
1097
  if self.autosave is True:
1078
1098
  self.save()
1079
1099
 
1080
- # Apply the cleaner function to the response
1081
- if self.output_cleaner is not None:
1082
- logger.info("Applying output cleaner to response.")
1083
- response = self.output_cleaner(response)
1084
- logger.info(
1085
- f"Response after output cleaner: {response}"
1086
- )
1087
- self.short_memory.add(
1088
- role="Output Cleaner",
1089
- content=response,
1090
- )
1091
-
1092
- if self.agent_ops_on is True and is_last is True:
1093
- self.check_end_session_agentops()
1094
-
1095
- # Merge all responses
1096
- all_responses = [
1097
- response
1098
- for response in all_responses
1099
- if response is not None
1100
- ]
1101
-
1102
- self.agent_output.steps = self.short_memory.to_dict()
1103
- self.agent_output.full_history = (
1104
- self.short_memory.get_str()
1105
- )
1106
- self.agent_output.total_tokens = count_tokens(
1107
- self.short_memory.get_str()
1108
- )
1109
-
1110
- # # Handle artifacts
1111
- # if self.artifacts_on is True:
1112
- # self.handle_artifacts(
1113
- # concat_strings(all_responses),
1114
- # self.artifacts_output_path,
1115
- # self.artifacts_file_extension,
1116
- # )
1117
-
1118
1100
  log_agent_data(self.to_dict())
1119
1101
 
1120
1102
  if self.autosave is True:
1121
1103
  self.save()
1122
1104
 
1123
- # More flexible output types
1124
- if (
1125
- self.output_type == "string"
1126
- or self.output_type == "str"
1127
- ):
1128
- return concat_strings(all_responses)
1129
- elif self.output_type == "list":
1130
- return all_responses
1131
- elif (
1132
- self.output_type == "json"
1133
- or self.return_step_meta is True
1134
- ):
1135
- return self.agent_output.model_dump_json(indent=4)
1136
- elif self.output_type == "csv":
1137
- return self.dict_to_csv(
1138
- self.agent_output.model_dump()
1139
- )
1140
- elif self.output_type == "dict":
1141
- return self.agent_output.model_dump()
1142
- elif self.output_type == "yaml":
1143
- return yaml.safe_dump(
1144
- self.agent_output.model_dump(), sort_keys=False
1145
- )
1146
-
1147
- elif self.output_type == "memory-list":
1148
- return self.short_memory.return_messages_as_list()
1149
-
1150
- elif self.output_type == "memory-dict":
1151
- return (
1152
- self.short_memory.return_messages_as_dictionary()
1153
- )
1154
- elif self.return_history is True:
1155
- history = self.short_memory.get_str()
1156
-
1157
- formatter.print_panel(
1158
- history, title=f"{self.agent_name} History"
1159
- )
1160
- return history
1161
- else:
1162
- raise ValueError(
1163
- f"Invalid output type: {self.output_type}"
1164
- )
1105
+ return history_output_formatter(
1106
+ self.short_memory, type=self.output_type
1107
+ )
1165
1108
 
1166
1109
  except Exception as error:
1167
1110
  self._handle_run_error(error)
@@ -1937,7 +1880,7 @@ class Agent:
1937
1880
  """Send a message to the agent"""
1938
1881
  try:
1939
1882
  logger.info(f"Sending agent message: {message}")
1940
- message = f"{agent_name}: {message}"
1883
+ message = f"To: {agent_name}: {message}"
1941
1884
  return self.run(message, *args, **kwargs)
1942
1885
  except Exception as error:
1943
1886
  logger.info(f"Error sending agent message: {error}")
@@ -2014,20 +1957,6 @@ class Agent:
2014
1957
  )
2015
1958
  raise error
2016
1959
 
2017
- def check_end_session_agentops(self):
2018
- if self.agent_ops_on is True:
2019
- try:
2020
- from swarms.utils.agent_ops_check import (
2021
- end_session_agentops,
2022
- )
2023
-
2024
- # Try ending the session
2025
- return end_session_agentops()
2026
- except ImportError:
2027
- logger.error(
2028
- "Could not import agentops, try installing agentops: $ pip3 install agentops"
2029
- )
2030
-
2031
1960
  def memory_query(self, task: str = None, *args, **kwargs) -> None:
2032
1961
  try:
2033
1962
  # Query the long term memory
@@ -2154,50 +2083,6 @@ class Agent:
2154
2083
 
2155
2084
  return out
2156
2085
 
2157
- def activate_agentops(self):
2158
- if self.agent_ops_on is True:
2159
- try:
2160
- from swarms.utils.agent_ops_check import (
2161
- try_import_agentops,
2162
- )
2163
-
2164
- # Try importing agent ops
2165
- logger.info(
2166
- "Agent Ops Initializing, ensure that you have the agentops API key and the pip package installed."
2167
- )
2168
- try_import_agentops()
2169
- self.agent_ops_agent_name = self.agent_name
2170
-
2171
- logger.info("Agentops successfully activated!")
2172
- except ImportError:
2173
- logger.error(
2174
- "Could not import agentops, try installing agentops: $ pip3 install agentops"
2175
- )
2176
-
2177
- def llm_output_parser(self, response: Any) -> str:
2178
- """Parse the output from the LLM"""
2179
- try:
2180
- if isinstance(response, dict):
2181
- if "choices" in response:
2182
- return response["choices"][0]["message"][
2183
- "content"
2184
- ]
2185
- else:
2186
- return json.dumps(
2187
- response
2188
- ) # Convert dict to string
2189
- elif isinstance(response, str):
2190
- return response
2191
- else:
2192
- return str(
2193
- response
2194
- ) # Convert any other type to string
2195
- except Exception as e:
2196
- logger.error(f"Error parsing LLM output: {e}")
2197
- return str(
2198
- response
2199
- ) # Return string representation as fallback
2200
-
2201
2086
  def log_step_metadata(
2202
2087
  self, loop: int, task: str, response: str
2203
2088
  ) -> Step:
@@ -2693,9 +2578,88 @@ class Agent:
2693
2578
  """
2694
2579
  return self.role
2695
2580
 
2696
- # def __getstate__(self):
2697
- # state = self.__dict__.copy()
2698
- # # Remove or replace unpicklable attributes.
2699
- # if '_queue' in state:
2700
- # del state['_queue']
2701
- # return state
2581
+ def pretty_print(self, response: str, loop_count: int):
2582
+ if self.no_print is False:
2583
+ if self.streaming_on is True:
2584
+ # self.stream_response(response)
2585
+ formatter.print_panel_token_by_token(
2586
+ f"{self.agent_name}: {response}",
2587
+ title=f"Agent Name: {self.agent_name} [Max Loops: {loop_count}]",
2588
+ )
2589
+ else:
2590
+ # logger.info(f"Response: {response}")
2591
+ formatter.print_panel(
2592
+ f"{self.agent_name}: {response}",
2593
+ f"Agent Name {self.agent_name} [Max Loops: {loop_count} ]",
2594
+ )
2595
+
2596
+ def parse_llm_output(self, response: Any) -> str:
2597
+ """Parse and standardize the output from the LLM.
2598
+
2599
+ Args:
2600
+ response (Any): The response from the LLM in any format
2601
+
2602
+ Returns:
2603
+ str: Standardized string output
2604
+
2605
+ Raises:
2606
+ ValueError: If the response format is unexpected and can't be handled
2607
+ """
2608
+ try:
2609
+ # Handle dictionary responses
2610
+ if isinstance(response, dict):
2611
+ if "choices" in response:
2612
+ return response["choices"][0]["message"][
2613
+ "content"
2614
+ ]
2615
+ return json.dumps(
2616
+ response
2617
+ ) # Convert other dicts to string
2618
+
2619
+ # Handle string responses
2620
+ elif isinstance(response, str):
2621
+ return response
2622
+
2623
+ # Handle list responses (from check_llm_outputs)
2624
+ elif isinstance(response, list):
2625
+ return "\n".join(response)
2626
+
2627
+ # Handle any other type by converting to string
2628
+ else:
2629
+ return str(response)
2630
+
2631
+ except Exception as e:
2632
+ logger.error(f"Error parsing LLM output: {e}")
2633
+ raise ValueError(
2634
+ f"Failed to parse LLM output: {type(response)}"
2635
+ )
2636
+
2637
+ def sentiment_and_evaluator(self, response: str):
2638
+ if self.evaluator:
2639
+ logger.info("Evaluating response...")
2640
+
2641
+ evaluated_response = self.evaluator(response)
2642
+ print("Evaluated Response:" f" {evaluated_response}")
2643
+ self.short_memory.add(
2644
+ role="Evaluator",
2645
+ content=evaluated_response,
2646
+ )
2647
+
2648
+ # Sentiment analysis
2649
+ if self.sentiment_analyzer:
2650
+ logger.info("Analyzing sentiment...")
2651
+ self.sentiment_analysis_handler(response)
2652
+
2653
+ def output_cleaner_op(self, response: str):
2654
+ # Apply the cleaner function to the response
2655
+ if self.output_cleaner is not None:
2656
+ logger.info("Applying output cleaner to response.")
2657
+
2658
+ response = self.output_cleaner(response)
2659
+
2660
+ logger.info(f"Response after output cleaner: {response}")
2661
+
2662
+ self.short_memory.add(
2663
+ role="Output Cleaner",
2664
+ content=response,
2665
+ )
@@ -89,7 +89,6 @@ class BaseSwarm(ABC):
89
89
  stopping_function: Optional[Callable] = None,
90
90
  stopping_condition: Optional[str] = "stop",
91
91
  stopping_condition_args: Optional[Dict] = None,
92
- agentops_on: Optional[bool] = False,
93
92
  speaker_selection_func: Optional[Callable] = None,
94
93
  rules: Optional[str] = None,
95
94
  collective_memory_system: Optional[Any] = False,
@@ -112,7 +111,6 @@ class BaseSwarm(ABC):
112
111
  self.stopping_function = stopping_function
113
112
  self.stopping_condition = stopping_condition
114
113
  self.stopping_condition_args = stopping_condition_args
115
- self.agentops_on = agentops_on
116
114
  self.speaker_selection_func = speaker_selection_func
117
115
  self.rules = rules
118
116
  self.collective_memory_system = collective_memory_system
@@ -167,11 +165,6 @@ class BaseSwarm(ABC):
167
165
  self.stopping_condition_args = stopping_condition_args
168
166
  self.stopping_condition = stopping_condition
169
167
 
170
- # If agentops is enabled, try to import agentops
171
- if agentops_on is True:
172
- for agent in self.agents:
173
- agent.agent_ops_on = True
174
-
175
168
  # Handle speaker selection function
176
169
  if speaker_selection_func is not None:
177
170
  if not callable(speaker_selection_func):
@@ -262,7 +262,7 @@ class ConcurrentWorkflow(BaseSwarm):
262
262
  ) -> AgentOutputSchema:
263
263
  start_time = datetime.now()
264
264
  try:
265
- output = agent.run(task=task, img=img)
265
+ output = agent.run(task=task)
266
266
 
267
267
  self.conversation.add(
268
268
  agent.agent_name,