swarms 7.7.0__py3-none-any.whl → 7.7.1__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/agent.py +166 -116
- swarms/structs/aop.py +557 -0
- swarms/structs/conversation.py +21 -0
- swarms/telemetry/main.py +36 -24
- swarms/tools/mcp_client.py +90 -0
- swarms/utils/history_output_formatter.py +29 -5
- swarms/utils/litellm_wrapper.py +26 -10
- {swarms-7.7.0.dist-info → swarms-7.7.1.dist-info}/METADATA +1 -1
- {swarms-7.7.0.dist-info → swarms-7.7.1.dist-info}/RECORD +13 -10
- {swarms-7.7.0.dist-info → swarms-7.7.1.dist-info}/LICENSE +0 -0
- {swarms-7.7.0.dist-info → swarms-7.7.1.dist-info}/WHEEL +0 -0
- {swarms-7.7.0.dist-info → swarms-7.7.1.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/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
|
+
# )
|
1075
|
+
|
1076
|
+
# # Print
|
1077
|
+
# self.pretty_print(response, loop_count)
|
1078
|
+
|
1079
|
+
# # Output Cleaner
|
1080
|
+
# self.output_cleaner_op(response)
|
1041
1081
|
|
1042
|
-
#
|
1043
|
-
|
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
|
+
]
|
1044
1092
|
|
1045
|
-
|
1046
|
-
|
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
|
@@ -1147,10 +1197,21 @@ class Agent:
|
|
1147
1197
|
if self.autosave is True:
|
1148
1198
|
self.save()
|
1149
1199
|
|
1150
|
-
log_agent_data(self.to_dict())
|
1200
|
+
# log_agent_data(self.to_dict())
|
1151
1201
|
|
1152
|
-
if self.autosave is True:
|
1153
|
-
|
1202
|
+
# if self.autosave is True:
|
1203
|
+
# self.save()
|
1204
|
+
|
1205
|
+
# 14. Batch final operations
|
1206
|
+
final_tasks = [
|
1207
|
+
lambda: log_agent_data(self.to_dict()),
|
1208
|
+
lambda: self.save() if self.autosave else None,
|
1209
|
+
]
|
1210
|
+
|
1211
|
+
with ThreadPoolExecutor(
|
1212
|
+
max_workers=len(final_tasks)
|
1213
|
+
) as executor:
|
1214
|
+
executor.map(lambda f: f(), final_tasks)
|
1154
1215
|
|
1155
1216
|
return history_output_formatter(
|
1156
1217
|
self.short_memory, type=self.output_type
|
@@ -1212,12 +1273,6 @@ class Agent:
|
|
1212
1273
|
self.run,
|
1213
1274
|
task=task,
|
1214
1275
|
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
1276
|
*args,
|
1222
1277
|
**kwargs,
|
1223
1278
|
)
|
@@ -1253,12 +1308,7 @@ class Agent:
|
|
1253
1308
|
return self.run(
|
1254
1309
|
task=task,
|
1255
1310
|
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,
|
1311
|
+
*args,
|
1262
1312
|
**kwargs,
|
1263
1313
|
)
|
1264
1314
|
except Exception as error:
|