swarms 7.7.0__py3-none-any.whl → 7.7.2__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/prompts/paper_idea_agent.py +31 -0
- swarms/structs/__init__.py +1 -4
- swarms/structs/agent.py +176 -119
- swarms/structs/aop.py +557 -0
- swarms/structs/conversation.py +38 -7
- swarms/structs/swarm_router.py +1 -1
- swarms/telemetry/main.py +48 -26
- swarms/tools/mcp_client.py +90 -0
- swarms/utils/formatter.py +15 -1
- swarms/utils/history_output_formatter.py +29 -5
- swarms/utils/litellm_wrapper.py +26 -10
- {swarms-7.7.0.dist-info → swarms-7.7.2.dist-info}/METADATA +1 -1
- {swarms-7.7.0.dist-info → swarms-7.7.2.dist-info}/RECORD +17 -19
- swarms/structs/async_workflow.py +0 -818
- swarms/structs/octotools.py +0 -844
- swarms/structs/pulsar_swarm.py +0 -469
- swarms/structs/swarm_load_balancer.py +0 -344
- swarms/structs/talk_hier.py +0 -729
- /swarms/structs/{multi_agent_orchestrator.py → multi_agent_router.py} +0 -0
- {swarms-7.7.0.dist-info → swarms-7.7.2.dist-info}/LICENSE +0 -0
- {swarms-7.7.0.dist-info → swarms-7.7.2.dist-info}/WHEEL +0 -0
- {swarms-7.7.0.dist-info → swarms-7.7.2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# System Role Definition
|
2
|
+
PAPER_IDEA_AGENT_SYSTEM_PROMPT = """
|
3
|
+
You are an experienced AI researcher tasked with proposing high-impact research ideas. Your ideas should:
|
4
|
+
|
5
|
+
- Be novel and creative
|
6
|
+
- Think outside conventional boundaries
|
7
|
+
- Start from simple, elegant questions or observations
|
8
|
+
- Be distinguishable from existing literature
|
9
|
+
- Be feasible within academic lab resources
|
10
|
+
- Be publishable at top ML conferences
|
11
|
+
- Be implementable using the provided codebase
|
12
|
+
|
13
|
+
Your responses must follow this strict format:
|
14
|
+
|
15
|
+
|
16
|
+
IDEA JSON Structure:
|
17
|
+
{
|
18
|
+
"Name": "Concise identifier",
|
19
|
+
"Title": "Academic paper title",
|
20
|
+
"Short Hypothesis": "Core hypothesis in 1-2 sentences",
|
21
|
+
"Related Work": "Key papers and how this differs",
|
22
|
+
"Abstract": "Complete paper abstract",
|
23
|
+
"Experiments": "Detailed experimental plan",
|
24
|
+
"Risk Factors and Limitations": "Known challenges and constraints"
|
25
|
+
}
|
26
|
+
|
27
|
+
Important Guidelines:
|
28
|
+
- Perform at least one literature search before finalizing any idea
|
29
|
+
- Ensure JSON formatting is valid for automated parsing
|
30
|
+
- Keep proposals clear and implementable
|
31
|
+
"""
|
swarms/structs/__init__.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from swarms.structs.agent import Agent
|
2
2
|
from swarms.structs.agent_builder import AgentsBuilder
|
3
3
|
from swarms.structs.agents_available import showcase_available_agents
|
4
|
-
from swarms.structs.async_workflow import AsyncWorkflow
|
5
4
|
from swarms.structs.base_structure import BaseStructure
|
6
5
|
from swarms.structs.base_swarm import BaseSwarm
|
7
6
|
from swarms.structs.base_workflow import BaseWorkflow
|
@@ -48,7 +47,7 @@ from swarms.structs.multi_agent_exec import (
|
|
48
47
|
get_agents_info,
|
49
48
|
get_swarms_info,
|
50
49
|
)
|
51
|
-
from swarms.structs.
|
50
|
+
from swarms.structs.multi_agent_router import MultiAgentRouter
|
52
51
|
from swarms.structs.queue_swarm import TaskQueueSwarm
|
53
52
|
from swarms.structs.rearrange import AgentRearrange, rearrange
|
54
53
|
from swarms.structs.round_robin import RoundRobinSwarm
|
@@ -83,7 +82,6 @@ from swarms.structs.swarming_architectures import (
|
|
83
82
|
|
84
83
|
__all__ = [
|
85
84
|
"Agent",
|
86
|
-
"AsyncWorkflow",
|
87
85
|
"BaseStructure",
|
88
86
|
"BaseSwarm",
|
89
87
|
"BaseWorkflow",
|
@@ -136,7 +134,6 @@ __all__ = [
|
|
136
134
|
"run_agent_with_timeout",
|
137
135
|
"run_agents_with_resource_monitoring",
|
138
136
|
"swarm_router",
|
139
|
-
"AsyncWorkflow",
|
140
137
|
"run_agents_with_tasks_concurrently",
|
141
138
|
"showcase_available_agents",
|
142
139
|
"GroupChat",
|
swarms/structs/agent.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import concurrent.futures
|
1
2
|
import asyncio
|
2
3
|
import json
|
3
4
|
import logging
|
@@ -13,7 +14,6 @@ from typing import (
|
|
13
14
|
Callable,
|
14
15
|
Dict,
|
15
16
|
List,
|
16
|
-
Literal,
|
17
17
|
Optional,
|
18
18
|
Tuple,
|
19
19
|
Union,
|
@@ -59,6 +59,7 @@ from swarms.utils.file_processing import create_file_in_folder
|
|
59
59
|
from swarms.utils.formatter import formatter
|
60
60
|
from swarms.utils.history_output_formatter import (
|
61
61
|
history_output_formatter,
|
62
|
+
HistoryOutputType,
|
62
63
|
)
|
63
64
|
from swarms.utils.litellm_tokenizer import count_tokens
|
64
65
|
from swarms.utils.litellm_wrapper import LiteLLM
|
@@ -89,18 +90,6 @@ def exists(val):
|
|
89
90
|
|
90
91
|
|
91
92
|
# Agent output types
|
92
|
-
# agent_output_type = Union[BaseModel, dict, str]
|
93
|
-
agent_output_type = Literal[
|
94
|
-
"string",
|
95
|
-
"str",
|
96
|
-
"list",
|
97
|
-
"json",
|
98
|
-
"dict",
|
99
|
-
"yaml",
|
100
|
-
"json_schema",
|
101
|
-
"memory-list",
|
102
|
-
"memory-dict",
|
103
|
-
]
|
104
93
|
ToolUsageType = Union[BaseModel, Dict[str, Any]]
|
105
94
|
|
106
95
|
|
@@ -346,7 +335,7 @@ class Agent:
|
|
346
335
|
# [Tools]
|
347
336
|
custom_tools_prompt: Optional[Callable] = None,
|
348
337
|
tool_schema: ToolUsageType = None,
|
349
|
-
output_type:
|
338
|
+
output_type: HistoryOutputType = "str",
|
350
339
|
function_calling_type: str = "json",
|
351
340
|
output_cleaner: Optional[Callable] = None,
|
352
341
|
function_calling_format_type: Optional[str] = "OpenAI",
|
@@ -524,6 +513,7 @@ class Agent:
|
|
524
513
|
self.no_print = no_print
|
525
514
|
self.tools_list_dictionary = tools_list_dictionary
|
526
515
|
# self.mcp_servers = mcp_servers
|
516
|
+
|
527
517
|
self._cached_llm = (
|
528
518
|
None # Add this line to cache the LLM instance
|
529
519
|
)
|
@@ -558,72 +548,76 @@ class Agent:
|
|
558
548
|
max_workers=executor_workers
|
559
549
|
)
|
560
550
|
|
561
|
-
|
562
|
-
if (
|
563
|
-
exists(tools)
|
564
|
-
or exists(list_base_models)
|
565
|
-
or exists(tool_schema)
|
566
|
-
):
|
567
|
-
|
568
|
-
self.tool_struct = BaseTool(
|
569
|
-
tools=tools,
|
570
|
-
base_models=list_base_models,
|
571
|
-
tool_system_prompt=tool_system_prompt,
|
572
|
-
)
|
573
|
-
|
574
|
-
# Some common configuration settings
|
575
|
-
threading.Thread(
|
576
|
-
target=self.setup_config, daemon=True
|
577
|
-
).start()
|
578
|
-
|
579
|
-
# If docs folder exists then get the docs from docs folder
|
580
|
-
if exists(self.docs_folder):
|
581
|
-
threading.Thread(
|
582
|
-
target=self.get_docs_from_doc_folders
|
583
|
-
).start()
|
584
|
-
|
585
|
-
if tools is not None:
|
586
|
-
logger.info(
|
587
|
-
"Tools provided make sure the functions have documentation ++ type hints, otherwise tool execution won't be reliable."
|
588
|
-
)
|
589
|
-
# Add the tool prompt to the memory
|
590
|
-
self.short_memory.add(
|
591
|
-
role="system", content=tool_system_prompt
|
592
|
-
)
|
593
|
-
|
594
|
-
# Log the tools
|
595
|
-
logger.info(
|
596
|
-
f"Tools provided: Accessing {len(tools)} tools"
|
597
|
-
)
|
598
|
-
|
599
|
-
# Transform the tools into an openai schema
|
600
|
-
# self.convert_tool_into_openai_schema()
|
601
|
-
|
602
|
-
# Transform the tools into an openai schema
|
603
|
-
tool_dict = (
|
604
|
-
self.tool_struct.convert_tool_into_openai_schema()
|
605
|
-
)
|
606
|
-
self.short_memory.add(role="system", content=tool_dict)
|
551
|
+
self.init_handling()
|
607
552
|
|
608
|
-
|
609
|
-
|
610
|
-
|
553
|
+
def init_handling(self):
|
554
|
+
# Define tasks as pairs of (function, condition)
|
555
|
+
# Each task will only run if its condition is True
|
556
|
+
tasks = [
|
557
|
+
(self.setup_config, True), # Always run setup_config
|
558
|
+
(
|
559
|
+
self.get_docs_from_doc_folders,
|
560
|
+
exists(self.docs_folder),
|
561
|
+
),
|
562
|
+
(self.handle_tool_init, True), # Always run tool init
|
563
|
+
(
|
564
|
+
self.handle_tool_schema_ops,
|
565
|
+
exists(self.tool_schema)
|
566
|
+
or exists(self.list_base_models),
|
567
|
+
),
|
568
|
+
(
|
569
|
+
self.handle_sop_ops,
|
570
|
+
exists(self.sop) or exists(self.sop_list),
|
571
|
+
),
|
572
|
+
]
|
573
|
+
|
574
|
+
# Filter out tasks whose conditions are False
|
575
|
+
filtered_tasks = [
|
576
|
+
task for task, condition in tasks if condition
|
577
|
+
]
|
578
|
+
|
579
|
+
# Execute all tasks concurrently
|
580
|
+
with concurrent.futures.ThreadPoolExecutor(
|
581
|
+
max_workers=os.cpu_count() * 4
|
582
|
+
) as executor:
|
583
|
+
# Map tasks to futures and collect results
|
584
|
+
results = {}
|
585
|
+
future_to_task = {
|
586
|
+
executor.submit(task): task.__name__
|
587
|
+
for task in filtered_tasks
|
611
588
|
}
|
612
589
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
590
|
+
# Wait for each future to complete and collect results/exceptions
|
591
|
+
for future in concurrent.futures.as_completed(
|
592
|
+
future_to_task
|
593
|
+
):
|
594
|
+
task_name = future_to_task[future]
|
595
|
+
try:
|
596
|
+
result = future.result()
|
597
|
+
results[task_name] = result
|
598
|
+
logging.info(
|
599
|
+
f"Task {task_name} completed successfully"
|
600
|
+
)
|
601
|
+
except Exception as e:
|
602
|
+
results[task_name] = None
|
603
|
+
logging.error(
|
604
|
+
f"Task {task_name} failed with error: {e}"
|
605
|
+
)
|
606
|
+
|
607
|
+
# Run sequential operations after all concurrent tasks are done
|
608
|
+
self.agent_output = self.agent_output_model()
|
609
|
+
log_agent_data(self.to_dict())
|
618
610
|
|
619
|
-
|
620
|
-
|
621
|
-
threading.Thread(target=self.handle_sop_ops()).start()
|
611
|
+
if self.llm is None:
|
612
|
+
self.llm = self.llm_handling()
|
622
613
|
|
614
|
+
def agent_output_model(self):
|
623
615
|
# Many steps
|
624
|
-
|
625
|
-
|
626
|
-
|
616
|
+
id = agent_id()
|
617
|
+
|
618
|
+
return ManySteps(
|
619
|
+
agent_id=id,
|
620
|
+
agent_name=self.agent_name,
|
627
621
|
# run_id=run_id,
|
628
622
|
task="",
|
629
623
|
max_loops=self.max_loops,
|
@@ -637,18 +631,6 @@ class Agent:
|
|
637
631
|
dynamic_temperature_enabled=self.dynamic_temperature_enabled,
|
638
632
|
)
|
639
633
|
|
640
|
-
# Telemetry Processor to log agent data
|
641
|
-
log_agent_data(self.to_dict())
|
642
|
-
|
643
|
-
if self.llm is None:
|
644
|
-
self.llm = self.llm_handling()
|
645
|
-
|
646
|
-
# if (
|
647
|
-
# self.tools_list_dictionary is None
|
648
|
-
# and self.mcp_servers is not None
|
649
|
-
# ):
|
650
|
-
# self.tools_list_dictionary = self.mcp_tool_handling()
|
651
|
-
|
652
634
|
def llm_handling(self):
|
653
635
|
# Use cached instance if available
|
654
636
|
if self._cached_llm is not None:
|
@@ -695,6 +677,48 @@ class Agent:
|
|
695
677
|
)
|
696
678
|
return None
|
697
679
|
|
680
|
+
def handle_tool_init(self):
|
681
|
+
# Initialize the tool struct
|
682
|
+
if (
|
683
|
+
exists(self.tools)
|
684
|
+
or exists(self.list_base_models)
|
685
|
+
or exists(self.tool_schema)
|
686
|
+
):
|
687
|
+
|
688
|
+
self.tool_struct = BaseTool(
|
689
|
+
tools=self.tools,
|
690
|
+
base_models=self.list_base_models,
|
691
|
+
tool_system_prompt=self.tool_system_prompt,
|
692
|
+
)
|
693
|
+
|
694
|
+
if self.tools is not None:
|
695
|
+
logger.info(
|
696
|
+
"Tools provided make sure the functions have documentation ++ type hints, otherwise tool execution won't be reliable."
|
697
|
+
)
|
698
|
+
# Add the tool prompt to the memory
|
699
|
+
self.short_memory.add(
|
700
|
+
role="system", content=self.tool_system_prompt
|
701
|
+
)
|
702
|
+
|
703
|
+
# Log the tools
|
704
|
+
logger.info(
|
705
|
+
f"Tools provided: Accessing {len(self.tools)} tools"
|
706
|
+
)
|
707
|
+
|
708
|
+
# Transform the tools into an openai schema
|
709
|
+
# self.convert_tool_into_openai_schema()
|
710
|
+
|
711
|
+
# Transform the tools into an openai schema
|
712
|
+
tool_dict = (
|
713
|
+
self.tool_struct.convert_tool_into_openai_schema()
|
714
|
+
)
|
715
|
+
self.short_memory.add(role="system", content=tool_dict)
|
716
|
+
|
717
|
+
# Now create a function calling map for every tools
|
718
|
+
self.function_map = {
|
719
|
+
tool.__name__: tool for tool in self.tools
|
720
|
+
}
|
721
|
+
|
698
722
|
# def mcp_execution_flow(self, response: any):
|
699
723
|
# """
|
700
724
|
# Executes the MCP (Model Context Protocol) flow based on the provided response.
|
@@ -955,14 +979,24 @@ class Agent:
|
|
955
979
|
agent(task="What is the capital of France?", img="path/to/image.jpg", is_last=True)
|
956
980
|
"""
|
957
981
|
try:
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
982
|
+
# 1. Batch process initial setup
|
983
|
+
setup_tasks = [
|
984
|
+
lambda: self.check_if_no_prompt_then_autogenerate(
|
985
|
+
task
|
986
|
+
),
|
987
|
+
lambda: self.short_memory.add(
|
988
|
+
role=self.user_name, content=task
|
989
|
+
),
|
990
|
+
lambda: (
|
991
|
+
self.plan(task) if self.plan_enabled else None
|
992
|
+
),
|
993
|
+
]
|
962
994
|
|
963
|
-
#
|
964
|
-
|
965
|
-
|
995
|
+
# Execute setup tasks concurrently
|
996
|
+
with ThreadPoolExecutor(
|
997
|
+
max_workers=len(setup_tasks)
|
998
|
+
) as executor:
|
999
|
+
executor.map(lambda f: f(), setup_tasks)
|
966
1000
|
|
967
1001
|
# Set the loop count
|
968
1002
|
loop_count = 0
|
@@ -1035,15 +1069,31 @@ class Agent:
|
|
1035
1069
|
# Convert to a str if the response is not a str
|
1036
1070
|
response = self.parse_llm_output(response)
|
1037
1071
|
|
1038
|
-
self.short_memory.add(
|
1039
|
-
|
1040
|
-
)
|
1072
|
+
# self.short_memory.add(
|
1073
|
+
# role=self.agent_name, content=response
|
1074
|
+
# )
|
1041
1075
|
|
1042
|
-
# Print
|
1043
|
-
self.pretty_print(response, loop_count)
|
1076
|
+
# # Print
|
1077
|
+
# self.pretty_print(response, loop_count)
|
1044
1078
|
|
1045
|
-
# Output Cleaner
|
1046
|
-
self.output_cleaner_op(response)
|
1079
|
+
# # Output Cleaner
|
1080
|
+
# self.output_cleaner_op(response)
|
1081
|
+
|
1082
|
+
# 9. Batch memory updates and prints
|
1083
|
+
update_tasks = [
|
1084
|
+
lambda: self.short_memory.add(
|
1085
|
+
role=self.agent_name, content=response
|
1086
|
+
),
|
1087
|
+
lambda: self.pretty_print(
|
1088
|
+
response, loop_count
|
1089
|
+
),
|
1090
|
+
lambda: self.output_cleaner_op(response),
|
1091
|
+
]
|
1092
|
+
|
1093
|
+
with ThreadPoolExecutor(
|
1094
|
+
max_workers=len(update_tasks)
|
1095
|
+
) as executor:
|
1096
|
+
executor.map(lambda f: f(), update_tasks)
|
1047
1097
|
|
1048
1098
|
# Check and execute tools
|
1049
1099
|
if self.tools is not None:
|
@@ -1120,7 +1170,7 @@ class Agent:
|
|
1120
1170
|
break
|
1121
1171
|
|
1122
1172
|
if self.interactive:
|
1123
|
-
logger.info("Interactive mode enabled.")
|
1173
|
+
# logger.info("Interactive mode enabled.")
|
1124
1174
|
user_input = input("You: ")
|
1125
1175
|
|
1126
1176
|
# User-defined exit command
|
@@ -1144,13 +1194,23 @@ class Agent:
|
|
1144
1194
|
if self.autosave is True:
|
1145
1195
|
log_agent_data(self.to_dict())
|
1146
1196
|
|
1147
|
-
|
1148
|
-
self.save()
|
1197
|
+
self.save()
|
1149
1198
|
|
1150
|
-
log_agent_data(self.to_dict())
|
1199
|
+
# log_agent_data(self.to_dict())
|
1151
1200
|
|
1152
|
-
if self.autosave is True:
|
1153
|
-
|
1201
|
+
# if self.autosave is True:
|
1202
|
+
# self.save()
|
1203
|
+
|
1204
|
+
# 14. Batch final operations
|
1205
|
+
final_tasks = [
|
1206
|
+
lambda: log_agent_data(self.to_dict()),
|
1207
|
+
lambda: self.save() if self.autosave else None,
|
1208
|
+
]
|
1209
|
+
|
1210
|
+
with ThreadPoolExecutor(
|
1211
|
+
max_workers=len(final_tasks)
|
1212
|
+
) as executor:
|
1213
|
+
executor.map(lambda f: f(), final_tasks)
|
1154
1214
|
|
1155
1215
|
return history_output_formatter(
|
1156
1216
|
self.short_memory, type=self.output_type
|
@@ -1162,7 +1222,7 @@ class Agent:
|
|
1162
1222
|
except KeyboardInterrupt as error:
|
1163
1223
|
self._handle_run_error(error)
|
1164
1224
|
|
1165
|
-
def
|
1225
|
+
def __handle_run_error(self, error: any):
|
1166
1226
|
log_agent_data(self.to_dict())
|
1167
1227
|
|
1168
1228
|
if self.autosave is True:
|
@@ -1173,6 +1233,14 @@ class Agent:
|
|
1173
1233
|
)
|
1174
1234
|
raise error
|
1175
1235
|
|
1236
|
+
def _handle_run_error(self, error: any):
|
1237
|
+
process_thread = threading.Thread(
|
1238
|
+
target=self.__handle_run_error,
|
1239
|
+
args=(error,),
|
1240
|
+
daemon=True,
|
1241
|
+
)
|
1242
|
+
process_thread.start()
|
1243
|
+
|
1176
1244
|
async def arun(
|
1177
1245
|
self,
|
1178
1246
|
task: Optional[str] = None,
|
@@ -1212,12 +1280,6 @@ class Agent:
|
|
1212
1280
|
self.run,
|
1213
1281
|
task=task,
|
1214
1282
|
img=img,
|
1215
|
-
is_last=is_last,
|
1216
|
-
device=device,
|
1217
|
-
device_id=device_id,
|
1218
|
-
all_cores=all_cores,
|
1219
|
-
do_not_use_cluster_ops=do_not_use_cluster_ops,
|
1220
|
-
all_gpus=all_gpus,
|
1221
1283
|
*args,
|
1222
1284
|
**kwargs,
|
1223
1285
|
)
|
@@ -1253,12 +1315,7 @@ class Agent:
|
|
1253
1315
|
return self.run(
|
1254
1316
|
task=task,
|
1255
1317
|
img=img,
|
1256
|
-
|
1257
|
-
device=device,
|
1258
|
-
device_id=device_id,
|
1259
|
-
all_cores=all_cores,
|
1260
|
-
do_not_use_cluster_ops=do_not_use_cluster_ops,
|
1261
|
-
all_gpus=all_gpus * args,
|
1318
|
+
*args,
|
1262
1319
|
**kwargs,
|
1263
1320
|
)
|
1264
1321
|
except Exception as error:
|