swarms 7.7.2__py3-none-any.whl → 7.7.4__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/ag_prompt.py +51 -19
- swarms/prompts/agent_system_prompts.py +13 -4
- swarms/prompts/multi_agent_collab_prompt.py +18 -0
- swarms/prompts/prompt.py +6 -10
- swarms/schemas/__init__.py +0 -3
- swarms/structs/__init__.py +2 -4
- swarms/structs/agent.py +201 -160
- swarms/structs/aop.py +8 -1
- swarms/structs/auto_swarm_builder.py +271 -210
- swarms/structs/conversation.py +22 -65
- swarms/structs/hiearchical_swarm.py +94 -123
- swarms/structs/hybrid_hiearchical_peer_swarm.py +1 -1
- swarms/structs/ma_utils.py +96 -0
- swarms/structs/mixture_of_agents.py +20 -103
- swarms/structs/multi_agent_router.py +32 -95
- swarms/structs/multi_model_gpu_manager.py +1447 -0
- swarms/structs/output_types.py +3 -16
- swarms/structs/stopping_conditions.py +30 -0
- swarms/structs/swarm_arange.py +18 -15
- swarms/structs/swarm_router.py +56 -4
- swarms/structs/swarming_architectures.py +576 -185
- swarms/telemetry/main.py +1 -7
- swarms/tools/mcp_client.py +209 -53
- swarms/tools/mcp_integration.py +1 -53
- swarms/utils/generate_keys.py +64 -0
- swarms/utils/history_output_formatter.py +2 -0
- {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/METADATA +98 -263
- {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/RECORD +31 -34
- swarms/schemas/agent_input_schema.py +0 -149
- swarms/structs/agents_available.py +0 -87
- swarms/structs/graph_swarm.py +0 -612
- swarms/structs/queue_swarm.py +0 -193
- swarms/structs/swarm_builder.py +0 -395
- swarms/structs/swarm_output_type.py +0 -23
- {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/LICENSE +0 -0
- {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/WHEEL +0 -0
- {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/entry_points.txt +0 -0
@@ -1,59 +1,20 @@
|
|
1
1
|
import asyncio
|
2
2
|
import os
|
3
|
-
import
|
4
|
-
from typing import Any, Dict, List, Optional
|
3
|
+
from typing import List, Optional
|
5
4
|
|
6
|
-
from pydantic import BaseModel, Field
|
7
5
|
|
8
6
|
from swarms.structs.agent import Agent
|
9
|
-
from swarms.
|
10
|
-
from swarms.schemas.agent_step_schemas import ManySteps
|
11
|
-
from swarms.prompts.ag_prompt import aggregator_system_prompt
|
7
|
+
from swarms.prompts.ag_prompt import aggregator_system_prompt_main
|
12
8
|
from swarms.utils.loguru_logger import initialize_logger
|
13
9
|
import concurrent.futures
|
14
10
|
from swarms.structs.output_types import OutputType
|
15
11
|
from swarms.structs.conversation import Conversation
|
12
|
+
from swarms.utils.history_output_formatter import (
|
13
|
+
history_output_formatter,
|
14
|
+
)
|
16
15
|
|
17
16
|
logger = initialize_logger(log_folder="mixture_of_agents")
|
18
17
|
|
19
|
-
time_stamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
20
|
-
|
21
|
-
|
22
|
-
class MixtureOfAgentsInput(BaseModel):
|
23
|
-
name: str = "MixtureOfAgents"
|
24
|
-
description: str = (
|
25
|
-
"A class to run a mixture of agents and aggregate their responses."
|
26
|
-
)
|
27
|
-
agents: List[Dict[str, Any]]
|
28
|
-
aggregator_agent: Any = Field(
|
29
|
-
...,
|
30
|
-
description="An aggregator agent to be used in the mixture.",
|
31
|
-
)
|
32
|
-
aggregator_system_prompt: str = Field(
|
33
|
-
default=aggregator_system_prompt.get_prompt(),
|
34
|
-
description=aggregator_system_prompt.description,
|
35
|
-
)
|
36
|
-
layers: int = 3
|
37
|
-
time_created: str = Field(
|
38
|
-
time_stamp,
|
39
|
-
description="The time the mixture of agents was created.",
|
40
|
-
)
|
41
|
-
|
42
|
-
|
43
|
-
class MixtureOfAgentsOutput(BaseModel):
|
44
|
-
id: str = Field(
|
45
|
-
..., description="The ID of the mixture of agents."
|
46
|
-
)
|
47
|
-
task: str = Field(..., description="None")
|
48
|
-
InputConfig: MixtureOfAgentsInput
|
49
|
-
# output: List[ManySteps]
|
50
|
-
normal_agent_outputs: List[ManySteps]
|
51
|
-
aggregator_agent_summary: str
|
52
|
-
time_completed: str = Field(
|
53
|
-
time_stamp,
|
54
|
-
description="The time the mixture of agents was completed.",
|
55
|
-
)
|
56
|
-
|
57
18
|
|
58
19
|
class MixtureOfAgents:
|
59
20
|
"""
|
@@ -66,7 +27,7 @@ class MixtureOfAgents:
|
|
66
27
|
description: str = "A class to run a mixture of agents and aggregate their responses.",
|
67
28
|
agents: List[Agent] = [],
|
68
29
|
aggregator_agent: Agent = None,
|
69
|
-
aggregator_system_prompt: str =
|
30
|
+
aggregator_system_prompt: str = aggregator_system_prompt_main,
|
70
31
|
layers: int = 3,
|
71
32
|
max_loops: int = 1,
|
72
33
|
return_str_on: bool = False,
|
@@ -85,31 +46,13 @@ class MixtureOfAgents:
|
|
85
46
|
"""
|
86
47
|
self.name = name
|
87
48
|
self.description = description
|
88
|
-
self.agents
|
89
|
-
self.aggregator_agent
|
90
|
-
self.aggregator_system_prompt
|
91
|
-
self.layers
|
92
|
-
self.max_loops
|
93
|
-
self.return_str_on
|
94
|
-
self.output_type
|
95
|
-
|
96
|
-
self.input_schema = MixtureOfAgentsInput(
|
97
|
-
name=name,
|
98
|
-
description=description,
|
99
|
-
agents=[agent.to_dict() for agent in self.agents],
|
100
|
-
aggregator_agent=aggregator_agent.to_dict(),
|
101
|
-
aggregator_system_prompt=self.aggregator_system_prompt,
|
102
|
-
layers=self.layers,
|
103
|
-
time_created=time_stamp,
|
104
|
-
)
|
105
|
-
|
106
|
-
self.output_schema = MixtureOfAgentsOutput(
|
107
|
-
id="MixtureOfAgents",
|
108
|
-
InputConfig=self.input_schema.model_dump(),
|
109
|
-
normal_agent_outputs=[],
|
110
|
-
aggregator_agent_summary="",
|
111
|
-
task="",
|
112
|
-
)
|
49
|
+
self.agents = agents
|
50
|
+
self.aggregator_agent = aggregator_agent
|
51
|
+
self.aggregator_system_prompt = aggregator_system_prompt_main
|
52
|
+
self.layers = layers
|
53
|
+
self.max_loops = max_loops
|
54
|
+
self.return_str_on = return_str_on
|
55
|
+
self.output_type = output_type
|
113
56
|
|
114
57
|
self.reliability_check()
|
115
58
|
|
@@ -182,9 +125,6 @@ class MixtureOfAgents:
|
|
182
125
|
Returns:
|
183
126
|
str: The response from the agent.
|
184
127
|
"""
|
185
|
-
# Update the task in the output schema
|
186
|
-
self.output_schema.task = task
|
187
|
-
|
188
128
|
# If there are previous responses, update the agent's system prompt
|
189
129
|
if prev_responses:
|
190
130
|
system_prompt_with_responses = (
|
@@ -197,9 +137,7 @@ class MixtureOfAgents:
|
|
197
137
|
# Run the agent asynchronously
|
198
138
|
response = await asyncio.to_thread(agent.run, task)
|
199
139
|
|
200
|
-
self.
|
201
|
-
agent.agent_output
|
202
|
-
)
|
140
|
+
self.conversation.add(agent.agent_name, response)
|
203
141
|
|
204
142
|
# Log the agent's response
|
205
143
|
print(f"Agent {agent.agent_name} response: {response}")
|
@@ -235,7 +173,6 @@ class MixtureOfAgents:
|
|
235
173
|
final_result = await self._run_agent_async(
|
236
174
|
self.aggregator_agent, task, prev_responses=results
|
237
175
|
)
|
238
|
-
self.output_schema.aggregator_agent_summary = final_result
|
239
176
|
|
240
177
|
print(f"Final Aggregated Response: {final_result}")
|
241
178
|
|
@@ -248,38 +185,18 @@ class MixtureOfAgents:
|
|
248
185
|
"""
|
249
186
|
try:
|
250
187
|
self.conversation.add("user", task)
|
251
|
-
prev_context = None
|
252
188
|
|
253
189
|
for _ in range(self.max_loops):
|
254
190
|
# Add previous context to task if available
|
255
|
-
|
256
|
-
f"{task}\n\nPrevious context:\n{prev_context}"
|
257
|
-
if prev_context
|
258
|
-
else task
|
259
|
-
)
|
191
|
+
prompt = f"History: {self.conversation.get_str()}\n\nTask: {task}"
|
260
192
|
|
261
193
|
# Run async process
|
262
|
-
asyncio.run(self._run_async(
|
194
|
+
asyncio.run(self._run_async(prompt))
|
263
195
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
self.output_schema.task = task
|
270
|
-
|
271
|
-
log_agent_data(self.output_schema.model_dump())
|
272
|
-
|
273
|
-
if self.return_str_on or self.output_type == "str":
|
274
|
-
return self.conversation.get_str()
|
275
|
-
elif self.output_type == "dict":
|
276
|
-
return (
|
277
|
-
self.conversation.return_messages_as_dictionary()
|
278
|
-
)
|
279
|
-
elif self.output_type == "list":
|
280
|
-
return self.conversation.return_messages_as_list()
|
281
|
-
else:
|
282
|
-
return self.output_schema.model_dump_json(indent=4)
|
196
|
+
return history_output_formatter(
|
197
|
+
conversation=self.conversation,
|
198
|
+
type=self.output_type,
|
199
|
+
)
|
283
200
|
|
284
201
|
except Exception as e:
|
285
202
|
logger.error(f"Error running mixture of agents: {str(e)}")
|
@@ -9,8 +9,6 @@ Todo:
|
|
9
9
|
"""
|
10
10
|
|
11
11
|
import os
|
12
|
-
import uuid
|
13
|
-
from datetime import datetime
|
14
12
|
from typing import List, Optional
|
15
13
|
|
16
14
|
from loguru import logger
|
@@ -20,6 +18,10 @@ from swarms.structs.agent import Agent
|
|
20
18
|
from swarms.structs.conversation import Conversation
|
21
19
|
from swarms.structs.output_types import OutputType
|
22
20
|
from swarms.utils.any_to_str import any_to_str
|
21
|
+
from swarms.utils.history_output_formatter import (
|
22
|
+
history_output_formatter,
|
23
|
+
)
|
24
|
+
from swarms.utils.formatter import formatter
|
23
25
|
|
24
26
|
|
25
27
|
class AgentResponse(BaseModel):
|
@@ -62,7 +64,7 @@ class MultiAgentRouter:
|
|
62
64
|
temperature: float = 0.1,
|
63
65
|
shared_memory_system: callable = None,
|
64
66
|
output_type: OutputType = "dict",
|
65
|
-
|
67
|
+
if_print: bool = True,
|
66
68
|
):
|
67
69
|
"""
|
68
70
|
Initializes the MultiAgentRouter with a list of agents and configuration options.
|
@@ -80,15 +82,15 @@ class MultiAgentRouter:
|
|
80
82
|
self.description = description
|
81
83
|
self.shared_memory_system = shared_memory_system
|
82
84
|
self.output_type = output_type
|
83
|
-
self.execute_task = execute_task
|
84
85
|
self.model = model
|
85
86
|
self.temperature = temperature
|
86
|
-
|
87
|
+
self.if_print = if_print
|
87
88
|
# Initialize Agents
|
88
89
|
self.agents = {agent.name: agent for agent in agents}
|
89
90
|
self.conversation = Conversation()
|
90
91
|
|
91
92
|
self.api_key = os.getenv("OPENAI_API_KEY")
|
93
|
+
|
92
94
|
if not self.api_key:
|
93
95
|
raise ValueError("OpenAI API key must be provided")
|
94
96
|
|
@@ -99,6 +101,7 @@ class MultiAgentRouter:
|
|
99
101
|
system_prompt=self.boss_system_prompt,
|
100
102
|
api_key=self.api_key,
|
101
103
|
temperature=temperature,
|
104
|
+
base_model=AgentResponse,
|
102
105
|
)
|
103
106
|
|
104
107
|
def __repr__(self):
|
@@ -140,21 +143,6 @@ class MultiAgentRouter:
|
|
140
143
|
Always select exactly one agent that best matches the task requirements.
|
141
144
|
"""
|
142
145
|
|
143
|
-
def find_agent_in_list(self, agent_name: str) -> Optional[Agent]:
|
144
|
-
"""
|
145
|
-
Find an agent by name in a list of agents.
|
146
|
-
|
147
|
-
Args:
|
148
|
-
agent_name (str): The name of the agent to find.
|
149
|
-
|
150
|
-
Returns:
|
151
|
-
Optional[Agent]: The agent object if found, otherwise None.
|
152
|
-
"""
|
153
|
-
for agent in self.agent_list:
|
154
|
-
if agent.name == agent_name:
|
155
|
-
return agent
|
156
|
-
return None
|
157
|
-
|
158
146
|
def route_task(self, task: str) -> dict:
|
159
147
|
"""
|
160
148
|
Routes a task to the appropriate agent and returns their response.
|
@@ -167,15 +155,21 @@ class MultiAgentRouter:
|
|
167
155
|
"""
|
168
156
|
try:
|
169
157
|
self.conversation.add(role="user", content=task)
|
170
|
-
start_time = datetime.now()
|
171
158
|
|
172
159
|
# Get boss decision using function calling
|
173
|
-
boss_response = self.function_caller.
|
174
|
-
|
160
|
+
boss_response = self.function_caller.run(task)
|
175
161
|
boss_response_str = any_to_str(boss_response)
|
176
162
|
|
163
|
+
if self.if_print:
|
164
|
+
formatter.print_panel(
|
165
|
+
boss_response_str,
|
166
|
+
title="Multi-Agent Router Decision",
|
167
|
+
)
|
168
|
+
else:
|
169
|
+
pass
|
170
|
+
|
177
171
|
self.conversation.add(
|
178
|
-
role="
|
172
|
+
role="Agent Router", content=boss_response_str
|
179
173
|
)
|
180
174
|
|
181
175
|
# Validate that the selected agent exists
|
@@ -190,60 +184,16 @@ class MultiAgentRouter:
|
|
190
184
|
# Use the modified task if provided, otherwise use original task
|
191
185
|
final_task = boss_response.modified_task or task
|
192
186
|
|
193
|
-
#
|
194
|
-
|
195
|
-
agent_response = None
|
196
|
-
execution_time = 0
|
187
|
+
# Use the agent's run method directly
|
188
|
+
agent_response = selected_agent.run(final_task)
|
197
189
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
self.conversation.add(
|
202
|
-
role=selected_agent.name, content=agent_response
|
203
|
-
)
|
204
|
-
execution_time = (
|
205
|
-
datetime.now() - execution_start
|
206
|
-
).total_seconds()
|
207
|
-
else:
|
208
|
-
logger.info(
|
209
|
-
"Task execution skipped (execute_task=False)"
|
210
|
-
)
|
190
|
+
self.conversation.add(
|
191
|
+
role=selected_agent.name, content=agent_response
|
192
|
+
)
|
211
193
|
|
212
|
-
|
213
|
-
|
214
|
-
result = {
|
215
|
-
"id": str(uuid.uuid4()),
|
216
|
-
"timestamp": datetime.now().isoformat(),
|
217
|
-
"task": {
|
218
|
-
"original": task,
|
219
|
-
"modified": (
|
220
|
-
final_task
|
221
|
-
if boss_response.modified_task
|
222
|
-
else None
|
223
|
-
),
|
224
|
-
},
|
225
|
-
"boss_decision": {
|
226
|
-
"selected_agent": boss_response.selected_agent,
|
227
|
-
"reasoning": boss_response.reasoning,
|
228
|
-
},
|
229
|
-
"execution": {
|
230
|
-
"agent_name": selected_agent.name,
|
231
|
-
"agent_id": selected_agent.id,
|
232
|
-
"was_executed": self.execute_task,
|
233
|
-
"response": (
|
234
|
-
agent_response if self.execute_task else None
|
235
|
-
),
|
236
|
-
"execution_time": (
|
237
|
-
execution_time if self.execute_task else None
|
238
|
-
),
|
239
|
-
},
|
240
|
-
"total_time": total_time,
|
241
|
-
}
|
242
|
-
|
243
|
-
logger.info(
|
244
|
-
f"Successfully routed task to {selected_agent.name}"
|
194
|
+
return history_output_formatter(
|
195
|
+
conversation=self.conversation, type=self.output_type
|
245
196
|
)
|
246
|
-
return result
|
247
197
|
|
248
198
|
except Exception as e:
|
249
199
|
logger.error(f"Error routing task: {str(e)}")
|
@@ -312,31 +262,18 @@ class MultiAgentRouter:
|
|
312
262
|
# ),
|
313
263
|
# ]
|
314
264
|
|
315
|
-
# # Initialize
|
316
|
-
#
|
317
|
-
# # router_no_execute = MultiAgentRouter(agents=agents, execute_task=False)
|
265
|
+
# # Initialize router
|
266
|
+
# router = MultiAgentRouter(agents=agents)
|
318
267
|
|
319
268
|
# # Example task
|
320
269
|
# task = "Write a Python function to calculate fibonacci numbers"
|
321
270
|
|
322
271
|
# try:
|
323
|
-
# # Process the task
|
324
|
-
#
|
325
|
-
#
|
326
|
-
# print(
|
327
|
-
#
|
328
|
-
# )
|
329
|
-
# print(
|
330
|
-
# f"Reasoning: {result_execute['boss_decision']['reasoning']}"
|
331
|
-
# )
|
332
|
-
# if result_execute["execution"]["response"]:
|
333
|
-
# print(
|
334
|
-
# f"Response Preview: {result_execute['execution']['response'][:200]}..."
|
335
|
-
# )
|
336
|
-
# print(
|
337
|
-
# f"Execution Time: {result_execute['execution']['execution_time']:.2f}s"
|
338
|
-
# )
|
339
|
-
# print(f"Total Time: {result_execute['total_time']:.2f}s")
|
272
|
+
# # Process the task
|
273
|
+
# result = router.route_task(task)
|
274
|
+
# print(f"Selected Agent: {result['boss_decision']['selected_agent']}")
|
275
|
+
# print(f"Reasoning: {result['boss_decision']['reasoning']}")
|
276
|
+
# print(f"Total Time: {result['total_time']:.2f}s")
|
340
277
|
|
341
278
|
# except Exception as e:
|
342
279
|
# print(f"Error occurred: {str(e)}")
|