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.
Files changed (37) hide show
  1. swarms/prompts/ag_prompt.py +51 -19
  2. swarms/prompts/agent_system_prompts.py +13 -4
  3. swarms/prompts/multi_agent_collab_prompt.py +18 -0
  4. swarms/prompts/prompt.py +6 -10
  5. swarms/schemas/__init__.py +0 -3
  6. swarms/structs/__init__.py +2 -4
  7. swarms/structs/agent.py +201 -160
  8. swarms/structs/aop.py +8 -1
  9. swarms/structs/auto_swarm_builder.py +271 -210
  10. swarms/structs/conversation.py +22 -65
  11. swarms/structs/hiearchical_swarm.py +94 -123
  12. swarms/structs/hybrid_hiearchical_peer_swarm.py +1 -1
  13. swarms/structs/ma_utils.py +96 -0
  14. swarms/structs/mixture_of_agents.py +20 -103
  15. swarms/structs/multi_agent_router.py +32 -95
  16. swarms/structs/multi_model_gpu_manager.py +1447 -0
  17. swarms/structs/output_types.py +3 -16
  18. swarms/structs/stopping_conditions.py +30 -0
  19. swarms/structs/swarm_arange.py +18 -15
  20. swarms/structs/swarm_router.py +56 -4
  21. swarms/structs/swarming_architectures.py +576 -185
  22. swarms/telemetry/main.py +1 -7
  23. swarms/tools/mcp_client.py +209 -53
  24. swarms/tools/mcp_integration.py +1 -53
  25. swarms/utils/generate_keys.py +64 -0
  26. swarms/utils/history_output_formatter.py +2 -0
  27. {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/METADATA +98 -263
  28. {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/RECORD +31 -34
  29. swarms/schemas/agent_input_schema.py +0 -149
  30. swarms/structs/agents_available.py +0 -87
  31. swarms/structs/graph_swarm.py +0 -612
  32. swarms/structs/queue_swarm.py +0 -193
  33. swarms/structs/swarm_builder.py +0 -395
  34. swarms/structs/swarm_output_type.py +0 -23
  35. {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/LICENSE +0 -0
  36. {swarms-7.7.2.dist-info → swarms-7.7.4.dist-info}/WHEEL +0 -0
  37. {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 time
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.telemetry.main import log_agent_data
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: List[Agent] = agents
89
- self.aggregator_agent: Agent = aggregator_agent
90
- self.aggregator_system_prompt: str = aggregator_system_prompt
91
- self.layers: int = layers
92
- self.max_loops: int = max_loops
93
- self.return_str_on: bool = return_str_on
94
- self.output_type: OutputType = 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.output_schema.normal_agent_outputs.append(
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
- current_task = (
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(current_task))
194
+ asyncio.run(self._run_async(prompt))
263
195
 
264
- # Store current results as context for next loop
265
- prev_context = (
266
- self.output_schema.aggregator_agent_summary
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
- execute_task: bool = True,
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.get_completion(task)
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="assistant", content=boss_response_str
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
- # Execute the task with the selected agent if enabled
194
- execution_start = datetime.now()
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
- if self.execute_task:
199
- # Use the agent's run method directly
200
- agent_response = selected_agent.run(final_task)
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
- total_time = (datetime.now() - start_time).total_seconds()
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 routers with different configurations
316
- # router_execute = MultiAgentRouter(agents=agents, execute_task=True)
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 with execution
324
- # print("\nWith task execution:")
325
- # result_execute = router_execute.route_task(task)
326
- # print(
327
- # f"Selected Agent: {result_execute['boss_decision']['selected_agent']}"
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)}")