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,65 +1,41 @@
1
1
  import math
2
- from typing import List, Union
2
+ from typing import List, Union, Dict, Any
3
3
 
4
- from pydantic import BaseModel
5
4
 
6
5
  from swarms.structs.agent import Agent
7
6
  from swarms.structs.omni_agent_types import AgentListType
8
7
  from swarms.utils.loguru_logger import initialize_logger
8
+ from swarms.structs.conversation import Conversation
9
+ from swarms.utils.history_output_formatter import (
10
+ history_output_formatter,
11
+ )
12
+ from swarms.structs.output_types import OutputType
9
13
 
10
14
  logger = initialize_logger(log_folder="swarming_architectures")
11
15
 
12
16
 
13
- # Define Pydantic schema for logging agent responses
14
- class AgentLog(BaseModel):
15
- agent_name: str
16
- task: str
17
- response: str
18
-
19
-
20
- class Conversation(BaseModel):
21
- logs: List[AgentLog] = []
22
-
23
- def add_log(
24
- self, agent_name: str, task: str, response: str
25
- ) -> None:
26
- log_entry = AgentLog(
27
- agent_name=agent_name, task=task, response=response
28
- )
29
- self.logs.append(log_entry)
30
- logger.info(
31
- f"Agent: {agent_name} | Task: {task} | Response: {response}"
32
- )
33
-
34
- def return_history(self) -> dict:
35
- return {
36
- "history": [
37
- {
38
- "agent_name": log.agent_name,
39
- "task": log.task,
40
- "response": log.response,
41
- }
42
- for log in self.logs
43
- ]
44
- }
45
-
46
-
47
17
  def circular_swarm(
48
18
  agents: AgentListType,
49
19
  tasks: List[str],
50
- return_full_history: bool = True,
51
- ) -> Union[dict, List[str]]:
20
+ output_type: OutputType = "dict",
21
+ ) -> Union[Dict[str, Any], List[str]]:
52
22
  """
53
23
  Implements a circular swarm where agents pass tasks in a circular manner.
54
24
 
55
25
  Args:
56
- - agents (AgentListType): A list of Agent objects to participate in the swarm.
57
- - tasks (List[str]): A list of tasks to be processed by the agents.
58
- - return_full_history (bool, optional): If True, returns the full conversation history. Defaults to True.
26
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
27
+ tasks (List[str]): A list of tasks to be processed by the agents.
28
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
59
29
 
60
30
  Returns:
61
- - Union[dict, List[str]]: If return_full_history is True, returns a dictionary containing the conversation history. Otherwise, returns a list of responses.
31
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
32
+ If output_type is "dict", returns a dictionary containing the conversation history.
33
+ If output_type is "list", returns a list of responses.
34
+
35
+ Raises:
36
+ ValueError: If agents or tasks lists are empty.
62
37
  """
38
+
63
39
  # Ensure agents is a flat list of Agent objects
64
40
  flat_agents = (
65
41
  [agent for sublist in agents for agent in sublist]
@@ -71,25 +47,50 @@ def circular_swarm(
71
47
  raise ValueError("Agents and tasks lists cannot be empty.")
72
48
 
73
49
  conversation = Conversation()
74
- responses = []
75
50
 
76
51
  for task in tasks:
77
52
  for agent in flat_agents:
78
- response = agent.run(task)
79
- conversation.add_log(
80
- agent_name=agent.agent_name,
81
- task=task,
82
- response=response,
53
+ conversation.add(
54
+ role="User",
55
+ message=task,
56
+ )
57
+ response = agent.run(conversation.get_str())
58
+ conversation.add(
59
+ role=agent.agent_name,
60
+ message=response,
83
61
  )
84
- responses.append(response)
85
62
 
86
- if return_full_history:
87
- return conversation.return_history()
88
- else:
89
- return responses
63
+ return history_output_formatter(conversation, output_type)
90
64
 
91
65
 
92
- def grid_swarm(agents: AgentListType, tasks: List[str]):
66
+ def grid_swarm(
67
+ agents: AgentListType,
68
+ tasks: List[str],
69
+ output_type: OutputType = "dict",
70
+ ) -> Union[Dict[str, Any], List[str]]:
71
+ """
72
+ Implements a grid swarm where agents are arranged in a square grid pattern.
73
+
74
+ Args:
75
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
76
+ tasks (List[str]): A list of tasks to be processed by the agents.
77
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
78
+
79
+ Returns:
80
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
81
+ If output_type is "dict", returns a dictionary containing the conversation history.
82
+ If output_type is "list", returns a list of responses.
83
+
84
+ Raises:
85
+ ValueError: If agents or tasks lists are empty.
86
+ """
87
+ conversation = Conversation()
88
+
89
+ conversation.add(
90
+ role="User",
91
+ message=tasks,
92
+ )
93
+
93
94
  grid_size = int(
94
95
  len(agents) ** 0.5
95
96
  ) # Assuming agents can form a perfect square grid
@@ -97,122 +98,180 @@ def grid_swarm(agents: AgentListType, tasks: List[str]):
97
98
  for j in range(grid_size):
98
99
  if tasks:
99
100
  task = tasks.pop(0)
100
- agents[i * grid_size + j].run(task)
101
+ response = agents[i * grid_size + j].run(task)
102
+ conversation.add(
103
+ role=agents[i * grid_size + j].agent_name,
104
+ message=response,
105
+ )
106
+
107
+ return history_output_formatter(conversation, output_type)
101
108
 
102
109
 
103
110
  # Linear Swarm: Agents process tasks in a sequential linear manner
104
111
  def linear_swarm(
105
112
  agents: AgentListType,
106
113
  tasks: List[str],
107
- return_full_history: bool = True,
108
- ) -> Union[str, List[str]]:
114
+ output_type: OutputType = "dict",
115
+ ) -> Union[Dict[str, Any], List[str]]:
116
+ """
117
+ Implements a linear swarm where agents process tasks in a sequential manner.
118
+
119
+ Args:
120
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
121
+ tasks (List[str]): A list of tasks to be processed by the agents.
122
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
123
+
124
+ Returns:
125
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
126
+ If output_type is "dict", returns a dictionary containing the conversation history.
127
+ If output_type is "list", returns a list of responses.
128
+
129
+ Raises:
130
+ ValueError: If agents or tasks lists are empty.
131
+ """
109
132
  if not agents or not tasks:
110
133
  raise ValueError("Agents and tasks lists cannot be empty.")
111
134
 
112
135
  conversation = Conversation()
113
- responses = []
114
136
 
115
137
  for agent in agents:
116
138
  if tasks:
117
139
  task = tasks.pop(0)
118
- response = agent.run(task)
119
- conversation.add_log(
120
- agent_name=agent.agent_name,
121
- task=task,
122
- response=response,
140
+ conversation.add(
141
+ role="User",
142
+ message=task,
143
+ )
144
+ response = agent.run(conversation.get_str())
145
+ conversation.add(
146
+ role=agent.agent_name,
147
+ message=response,
123
148
  )
124
- responses.append(response)
125
149
 
126
- return (
127
- conversation.return_history()
128
- if return_full_history
129
- else responses
130
- )
150
+ return history_output_formatter(conversation, output_type)
131
151
 
132
152
 
133
153
  # Star Swarm: A central agent first processes all tasks, followed by others
134
154
  def star_swarm(
135
155
  agents: AgentListType,
136
156
  tasks: List[str],
137
- return_full_history: bool = True,
138
- ) -> Union[str, List[str]]:
157
+ output_type: OutputType = "dict",
158
+ ) -> Union[Dict[str, Any], List[str]]:
159
+ """
160
+ Implements a star swarm where a central agent processes tasks first, followed by others.
161
+
162
+ Args:
163
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
164
+ tasks (List[str]): A list of tasks to be processed by the agents.
165
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
166
+
167
+ Returns:
168
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
169
+ If output_type is "dict", returns a dictionary containing the conversation history.
170
+ If output_type is "list", returns a list of responses.
171
+
172
+ Raises:
173
+ ValueError: If agents or tasks lists are empty.
174
+ """
139
175
  if not agents or not tasks:
140
176
  raise ValueError("Agents and tasks lists cannot be empty.")
141
177
 
142
178
  conversation = Conversation()
143
179
  center_agent = agents[0] # The central agent
144
- responses = []
145
180
 
146
181
  for task in tasks:
147
182
  # Central agent processes the task
148
- center_response = center_agent.run(task)
149
- conversation.add_log(
150
- agent_name=center_agent.agent_name,
151
- task=task,
152
- response=center_response,
183
+ conversation.add(
184
+ role="User",
185
+ message=task,
186
+ )
187
+ center_response = center_agent.run(conversation.get_str())
188
+ conversation.add(
189
+ role=center_agent.agent_name,
190
+ message=center_response,
153
191
  )
154
- responses.append(center_response)
155
192
 
156
193
  # Other agents process the same task
157
194
  for agent in agents[1:]:
158
195
  response = agent.run(task)
159
- conversation.add_log(
160
- agent_name=agent.agent_name,
161
- task=task,
162
- response=response,
196
+ conversation.add(
197
+ role=agent.agent_name,
198
+ message=response,
163
199
  )
164
- responses.append(response)
165
200
 
166
- return (
167
- conversation.return_history()
168
- if return_full_history
169
- else responses
170
- )
201
+ return history_output_formatter(conversation, output_type)
171
202
 
172
203
 
173
204
  # Mesh Swarm: Agents work on tasks randomly from a task queue until all tasks are processed
174
205
  def mesh_swarm(
175
206
  agents: AgentListType,
176
207
  tasks: List[str],
177
- return_full_history: bool = True,
178
- ) -> Union[str, List[str]]:
208
+ output_type: OutputType = "dict",
209
+ ) -> Union[Dict[str, Any], List[str]]:
210
+ """
211
+ Implements a mesh swarm where agents work on tasks randomly from a task queue.
212
+
213
+ Args:
214
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
215
+ tasks (List[str]): A list of tasks to be processed by the agents.
216
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
217
+
218
+ Returns:
219
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
220
+ If output_type is "dict", returns a dictionary containing the conversation history.
221
+ If output_type is "list", returns a list of responses.
222
+
223
+ Raises:
224
+ ValueError: If agents or tasks lists are empty.
225
+ """
179
226
  if not agents or not tasks:
180
227
  raise ValueError("Agents and tasks lists cannot be empty.")
181
228
 
182
229
  conversation = Conversation()
230
+ conversation.add(
231
+ role="User",
232
+ message=tasks,
233
+ )
183
234
  task_queue = tasks.copy()
184
- responses = []
185
235
 
186
236
  while task_queue:
187
237
  for agent in agents:
188
238
  if task_queue:
189
239
  task = task_queue.pop(0)
190
240
  response = agent.run(task)
191
- conversation.add_log(
192
- agent_name=agent.agent_name,
193
- task=task,
194
- response=response,
241
+ conversation.add(
242
+ role=agent.agent_name,
243
+ message=response,
195
244
  )
196
- responses.append(response)
197
245
 
198
- return (
199
- conversation.return_history()
200
- if return_full_history
201
- else responses
202
- )
246
+ return history_output_formatter(conversation, output_type)
203
247
 
204
248
 
205
249
  # Pyramid Swarm: Agents are arranged in a pyramid structure
206
250
  def pyramid_swarm(
207
251
  agents: AgentListType,
208
252
  tasks: List[str],
209
- return_full_history: bool = True,
210
- ) -> Union[str, List[str]]:
253
+ output_type: OutputType = "dict",
254
+ ) -> Union[Dict[str, Any], List[str]]:
255
+ """
256
+ Implements a pyramid swarm where agents are arranged in a pyramid structure.
257
+
258
+ Args:
259
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
260
+ tasks (List[str]): A list of tasks to be processed by the agents.
261
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
262
+
263
+ Returns:
264
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
265
+ If output_type is "dict", returns a dictionary containing the conversation history.
266
+ If output_type is "list", returns a list of responses.
267
+
268
+ Raises:
269
+ ValueError: If agents or tasks lists are empty.
270
+ """
211
271
  if not agents or not tasks:
212
272
  raise ValueError("Agents and tasks lists cannot be empty.")
213
273
 
214
274
  conversation = Conversation()
215
- responses = []
216
275
 
217
276
  levels = int(
218
277
  (-1 + (1 + 8 * len(agents)) ** 0.5) / 2
@@ -224,21 +283,37 @@ def pyramid_swarm(
224
283
  task = tasks.pop(0)
225
284
  agent_index = int(i * (i + 1) / 2 + j)
226
285
  response = agents[agent_index].run(task)
227
- conversation.add_log(
228
- agent_name=agents[agent_index].agent_name,
229
- task=task,
230
- response=response,
286
+ conversation.add(
287
+ role=agents[agent_index].agent_name,
288
+ message=response,
231
289
  )
232
- responses.append(response)
233
290
 
234
- return (
235
- conversation.return_history()
236
- if return_full_history
237
- else responses
238
- )
291
+ return history_output_formatter(conversation, output_type)
292
+
293
+
294
+ def fibonacci_swarm(
295
+ agents: AgentListType,
296
+ tasks: List[str],
297
+ output_type: OutputType = "dict",
298
+ ) -> Union[Dict[str, Any], List[str]]:
299
+ """
300
+ Implements a fibonacci swarm where agents are selected based on the fibonacci sequence.
239
301
 
302
+ Args:
303
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
304
+ tasks (List[str]): A list of tasks to be processed by the agents.
305
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
240
306
 
241
- def fibonacci_swarm(agents: AgentListType, tasks: List[str]):
307
+ Returns:
308
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
309
+ If output_type is "dict", returns a dictionary containing the conversation history.
310
+ If output_type is "list", returns a list of responses.
311
+ """
312
+ conversation = Conversation()
313
+ conversation.add(
314
+ role="User",
315
+ message=tasks,
316
+ )
242
317
  fib = [1, 1]
243
318
  while len(fib) < len(agents):
244
319
  fib.append(fib[-1] + fib[-2])
@@ -246,10 +321,38 @@ def fibonacci_swarm(agents: AgentListType, tasks: List[str]):
246
321
  for j in range(fib[i]):
247
322
  if tasks:
248
323
  task = tasks.pop(0)
249
- agents[int(sum(fib[:i]) + j)].run(task)
324
+ response = agents[int(sum(fib[:i]) + j)].run(task)
325
+ conversation.add(
326
+ role=agents[int(sum(fib[:i]) + j)].agent_name,
327
+ message=response,
328
+ )
329
+
330
+ return history_output_formatter(conversation, output_type)
331
+
332
+
333
+ def prime_swarm(
334
+ agents: AgentListType,
335
+ tasks: List[str],
336
+ output_type: OutputType = "dict",
337
+ ) -> Union[Dict[str, Any], List[str]]:
338
+ """
339
+ Implements a prime swarm where agents are selected based on prime numbers.
250
340
 
341
+ Args:
342
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
343
+ tasks (List[str]): A list of tasks to be processed by the agents.
344
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
251
345
 
252
- def prime_swarm(agents: AgentListType, tasks: List[str]):
346
+ Returns:
347
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
348
+ If output_type is "dict", returns a dictionary containing the conversation history.
349
+ If output_type is "list", returns a list of responses.
350
+ """
351
+ conversation = Conversation()
352
+ conversation.add(
353
+ role="User",
354
+ message=tasks,
355
+ )
253
356
  primes = [
254
357
  2,
255
358
  3,
@@ -280,114 +383,358 @@ def prime_swarm(agents: AgentListType, tasks: List[str]):
280
383
  for prime in primes:
281
384
  if prime < len(agents) and tasks:
282
385
  task = tasks.pop(0)
283
- agents[prime].run(task)
386
+ output = agents[prime].run(task)
387
+ conversation.add(
388
+ role=agents[prime].agent_name,
389
+ message=output,
390
+ )
391
+ return history_output_formatter(conversation, output_type)
284
392
 
285
393
 
286
- def power_swarm(agents: List[str], tasks: List[str]):
394
+ def power_swarm(
395
+ agents: AgentListType,
396
+ tasks: List[str],
397
+ output_type: OutputType = "dict",
398
+ ) -> Union[Dict[str, Any], List[str]]:
399
+ """
400
+ Implements a power swarm where agents are selected based on powers of 2.
401
+
402
+ Args:
403
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
404
+ tasks (List[str]): A list of tasks to be processed by the agents.
405
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
406
+
407
+ Returns:
408
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
409
+ If output_type is "dict", returns a dictionary containing the conversation history.
410
+ If output_type is "list", returns a list of responses.
411
+ """
412
+ conversation = Conversation()
413
+ conversation.add(
414
+ role="User",
415
+ message=tasks,
416
+ )
287
417
  powers = [2**i for i in range(int(len(agents) ** 0.5))]
288
418
  for power in powers:
289
419
  if power < len(agents) and tasks:
290
420
  task = tasks.pop(0)
291
- agents[power].run(task)
421
+ output = agents[power].run(task)
422
+ conversation.add(
423
+ role=agents[power].agent_name,
424
+ message=output,
425
+ )
426
+ return history_output_formatter(conversation, output_type)
427
+
428
+
429
+ def log_swarm(
430
+ agents: AgentListType,
431
+ tasks: List[str],
432
+ output_type: OutputType = "dict",
433
+ ) -> Union[Dict[str, Any], List[str]]:
434
+ """
435
+ Implements a logarithmic swarm where agents are selected based on logarithmic progression.
292
436
 
437
+ Args:
438
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
439
+ tasks (List[str]): A list of tasks to be processed by the agents.
440
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
293
441
 
294
- def log_swarm(agents: AgentListType, tasks: List[str]):
442
+ Returns:
443
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
444
+ If output_type is "dict", returns a dictionary containing the conversation history.
445
+ If output_type is "list", returns a list of responses.
446
+ """
447
+ conversation = Conversation()
448
+ conversation.add(
449
+ role="User",
450
+ message=tasks,
451
+ )
295
452
  for i in range(len(agents)):
296
453
  if 2**i < len(agents) and tasks:
297
454
  task = tasks.pop(0)
298
- agents[2**i].run(task)
455
+ output = agents[2**i].run(task)
456
+ conversation.add(
457
+ role=agents[2**i].agent_name,
458
+ message=output,
459
+ )
460
+ return history_output_formatter(conversation, output_type)
461
+
462
+
463
+ def exponential_swarm(
464
+ agents: AgentListType,
465
+ tasks: List[str],
466
+ output_type: OutputType = "dict",
467
+ ) -> Union[Dict[str, Any], List[str]]:
468
+ """
469
+ Implements an exponential swarm where agents are selected based on exponential progression.
299
470
 
471
+ Args:
472
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
473
+ tasks (List[str]): A list of tasks to be processed by the agents.
474
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
475
+
476
+ Returns:
477
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
478
+ If output_type is "dict", returns a dictionary containing the conversation history.
479
+ If output_type is "list", returns a list of responses.
480
+ """
481
+ conversation = Conversation()
482
+ conversation.add(
483
+ role="User",
484
+ message=tasks,
485
+ )
300
486
 
301
- def exponential_swarm(agents: AgentListType, tasks: List[str]):
302
487
  for i in range(len(agents)):
303
488
  index = min(int(2**i), len(agents) - 1)
304
489
  if tasks:
305
490
  task = tasks.pop(0)
306
- agents[index].run(task)
491
+ output = agents[index].run(task)
492
+
493
+ conversation.add(
494
+ role=agents[index].agent_name,
495
+ message=output,
496
+ )
497
+
498
+ return history_output_formatter(conversation, output_type)
307
499
 
308
500
 
309
- def geometric_swarm(agents, tasks):
501
+ def geometric_swarm(
502
+ agents: AgentListType,
503
+ tasks: List[str],
504
+ output_type: OutputType = "dict",
505
+ ) -> Union[Dict[str, Any], List[str]]:
506
+ """
507
+ Implements a geometric swarm where agents are selected based on geometric progression.
508
+ Each agent processes tasks in a pattern that follows a geometric sequence.
509
+
510
+ Args:
511
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
512
+ tasks (List[str]): A list of tasks to be processed by the agents.
513
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
514
+
515
+ Returns:
516
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
517
+ If output_type is "dict", returns a dictionary containing the conversation history.
518
+ If output_type is "list", returns a list of responses.
519
+ """
310
520
  ratio = 2
311
- for i in range(range(len(agents))):
521
+ conversation = Conversation()
522
+ conversation.add(
523
+ role="User",
524
+ message=tasks,
525
+ )
526
+
527
+ for i in range(len(agents)):
312
528
  index = min(int(ratio**2), len(agents) - 1)
313
529
  if tasks:
314
530
  task = tasks.pop(0)
315
- agents[index].run(task)
531
+ response = agents[index].run(task)
532
+ conversation.add(
533
+ role=agents[index].agent_name,
534
+ message=response,
535
+ )
536
+
537
+ return history_output_formatter(conversation, output_type)
316
538
 
317
539
 
318
- def harmonic_swarm(agents: AgentListType, tasks: List[str]):
540
+ def harmonic_swarm(
541
+ agents: AgentListType,
542
+ tasks: List[str],
543
+ output_type: OutputType = "dict",
544
+ ) -> Union[Dict[str, Any], List[str]]:
545
+ """
546
+ Implements a harmonic swarm where agents are selected based on harmonic progression.
547
+
548
+ Args:
549
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
550
+ tasks (List[str]): A list of tasks to be processed by the agents.
551
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
552
+
553
+ Returns:
554
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
555
+ If output_type is "dict", returns a dictionary containing the conversation history.
556
+ If output_type is "list", returns a list of responses.
557
+ """
558
+ conversation = Conversation()
559
+ conversation.add(
560
+ role="User",
561
+ message=tasks,
562
+ )
563
+
319
564
  for i in range(1, len(agents) + 1):
320
565
  index = min(int(len(agents) / i), len(agents) - 1)
321
566
  if tasks:
322
567
  task = tasks.pop(0)
323
- agents[index].run(task)
568
+ response = agents[index].run(task)
569
+ conversation.add(
570
+ role=agents[index].agent_name,
571
+ message=response,
572
+ )
573
+
574
+ return history_output_formatter(conversation, output_type)
575
+
324
576
 
577
+ def staircase_swarm(
578
+ agents: AgentListType,
579
+ tasks: List[str],
580
+ output_type: OutputType = "dict",
581
+ ) -> Union[Dict[str, Any], List[str]]:
582
+ """
583
+ Implements a staircase swarm where agents are selected in a step-like pattern.
584
+
585
+ Args:
586
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
587
+ tasks (List[str]): A list of tasks to be processed by the agents.
588
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
589
+
590
+ Returns:
591
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
592
+ If output_type is "dict", returns a dictionary containing the conversation history.
593
+ If output_type is "list", returns a list of responses.
594
+ """
595
+ conversation = Conversation()
596
+ conversation.add(
597
+ role="User",
598
+ message=tasks,
599
+ )
325
600
 
326
- def staircase_swarm(agents: AgentListType, task: str):
327
601
  step = len(agents) // 5
328
602
  for i in range(len(agents)):
329
603
  index = (i // step) * step
330
- agents[index].run(task)
604
+ if tasks:
605
+ task = tasks.pop(0)
606
+ response = agents[index].run(task)
607
+ conversation.add(
608
+ role=agents[index].agent_name,
609
+ message=response,
610
+ )
611
+
612
+ return history_output_formatter(conversation, output_type)
331
613
 
332
614
 
333
- def sigmoid_swarm(agents: AgentListType, task: str):
615
+ def sigmoid_swarm(
616
+ agents: AgentListType,
617
+ tasks: List[str],
618
+ output_type: OutputType = "dict",
619
+ ) -> Union[Dict[str, Any], List[str]]:
620
+ """
621
+ Implements a sigmoid swarm where agents are selected based on sigmoid function.
622
+
623
+ Args:
624
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
625
+ tasks (List[str]): A list of tasks to be processed by the agents.
626
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
627
+
628
+ Returns:
629
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
630
+ If output_type is "dict", returns a dictionary containing the conversation history.
631
+ If output_type is "list", returns a list of responses.
632
+ """
633
+ conversation = Conversation()
634
+ conversation.add(
635
+ role="User",
636
+ message=tasks,
637
+ )
638
+
334
639
  for i in range(len(agents)):
335
640
  index = int(len(agents) / (1 + math.exp(-i)))
336
- agents[index].run(task)
641
+ if tasks:
642
+ task = tasks.pop(0)
643
+ response = agents[index].run(task)
644
+ conversation.add(
645
+ role=agents[index].agent_name,
646
+ message=response,
647
+ )
337
648
 
649
+ return history_output_formatter(conversation, output_type)
650
+
651
+
652
+ def sinusoidal_swarm(
653
+ agents: AgentListType,
654
+ tasks: List[str],
655
+ output_type: OutputType = "dict",
656
+ ) -> Union[Dict[str, Any], List[str]]:
657
+ """
658
+ Implements a sinusoidal swarm where agents are selected based on sine function.
659
+
660
+ Args:
661
+ agents (AgentListType): A list of Agent objects to participate in the swarm.
662
+ tasks (List[str]): A list of tasks to be processed by the agents.
663
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
664
+
665
+ Returns:
666
+ Union[Dict[str, Any], List[str]]: The formatted output of the swarm's processing.
667
+ If output_type is "dict", returns a dictionary containing the conversation history.
668
+ If output_type is "list", returns a list of responses.
669
+ """
670
+ conversation = Conversation()
671
+ conversation.add(
672
+ role="User",
673
+ message=tasks,
674
+ )
338
675
 
339
- def sinusoidal_swarm(agents: AgentListType, task: str):
340
676
  for i in range(len(agents)):
341
677
  index = int((math.sin(i) + 1) / 2 * len(agents))
342
- agents[index].run(task)
343
-
678
+ if tasks:
679
+ task = tasks.pop(0)
680
+ response = agents[index].run(task)
681
+ conversation.add(
682
+ role=agents[index].agent_name,
683
+ message=response,
684
+ )
344
685
 
345
- """
346
- This module contains functions for facilitating communication between agents in a swarm. It includes methods for one-to-one communication, broadcasting, and other swarm architectures.
347
- """
686
+ return history_output_formatter(conversation, output_type)
348
687
 
349
688
 
350
689
  # One-to-One Communication between two agents
351
690
  def one_to_one(
352
- sender: Agent, receiver: Agent, task: str, max_loops: int = 1
353
- ) -> str:
691
+ sender: Agent,
692
+ receiver: Agent,
693
+ task: str,
694
+ max_loops: int = 1,
695
+ output_type: OutputType = "dict",
696
+ ) -> Union[Dict[str, Any], List[str]]:
354
697
  """
355
- Facilitates one-to-one communication between two agents. The sender and receiver agents exchange messages for a specified number of loops.
698
+ Implements one-to-one communication between two agents.
356
699
 
357
700
  Args:
358
701
  sender (Agent): The agent sending the message.
359
702
  receiver (Agent): The agent receiving the message.
360
- task (str): The message to be sent.
361
- max_loops (int, optional): The number of times the sender and receiver exchange messages. Defaults to 1.
703
+ task (str): The task to be processed.
704
+ max_loops (int, optional): Maximum number of communication loops. Defaults to 1.
705
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
362
706
 
363
707
  Returns:
364
- str: The conversation history between the sender and receiver.
708
+ Union[Dict[str, Any], List[str]]: The formatted output of the communication.
709
+ If output_type is "dict", returns a dictionary containing the conversation history.
710
+ If output_type is "list", returns a list of responses.
365
711
 
366
712
  Raises:
367
- Exception: If there is an error during the communication process.
713
+ ValueError: If sender, receiver, or task is empty.
368
714
  """
369
715
  conversation = Conversation()
370
- responses = []
716
+ conversation.add(
717
+ role="User",
718
+ message=task,
719
+ )
371
720
 
372
721
  try:
373
722
  for _ in range(max_loops):
374
723
  # Sender processes the task
375
724
  sender_response = sender.run(task)
376
- conversation.add_log(
377
- agent_name=sender.agent_name,
378
- task=task,
379
- response=sender_response,
725
+ conversation.add(
726
+ role=sender.agent_name,
727
+ message=sender_response,
380
728
  )
381
- responses.append(sender_response)
382
729
 
383
730
  # Receiver processes the result of the sender
384
731
  receiver_response = receiver.run(sender_response)
385
- conversation.add_log(
386
- agent_name=receiver.agent_name,
387
- task=task,
388
- response=receiver_response,
732
+ conversation.add(
733
+ role=receiver.agent_name,
734
+ message=receiver_response,
389
735
  )
390
- responses.append(receiver_response)
736
+
737
+ return history_output_formatter(conversation, output_type)
391
738
 
392
739
  except Exception as error:
393
740
  logger.error(
@@ -395,36 +742,57 @@ def one_to_one(
395
742
  )
396
743
  raise error
397
744
 
398
- return conversation.return_history()
399
-
400
745
 
401
746
  async def broadcast(
402
- sender: Agent, agents: AgentListType, task: str
403
- ) -> None:
747
+ sender: Agent,
748
+ agents: AgentListType,
749
+ task: str,
750
+ output_type: OutputType = "dict",
751
+ ) -> Union[Dict[str, Any], List[str]]:
752
+ """
753
+ Implements a broadcast communication pattern where one agent sends to many.
754
+
755
+ Args:
756
+ sender (Agent): The agent broadcasting the message.
757
+ agents (AgentListType): List of agents receiving the broadcast.
758
+ task (str): The task to be broadcast.
759
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
760
+
761
+ Returns:
762
+ Union[Dict[str, Any], List[str]]: The formatted output of the broadcast.
763
+ If output_type is "dict", returns a dictionary containing the conversation history.
764
+ If output_type is "list", returns a list of responses.
765
+
766
+ Raises:
767
+ ValueError: If sender, agents, or task is empty.
768
+ """
404
769
  conversation = Conversation()
770
+ conversation.add(
771
+ role="User",
772
+ message=task,
773
+ )
405
774
 
406
775
  if not sender or not agents or not task:
407
776
  raise ValueError("Sender, agents, and task cannot be empty.")
408
777
 
409
778
  try:
410
779
  # First get the sender's broadcast message
411
- broadcast_message = sender.run(task)
412
- conversation.add_log(
413
- agent_name=sender.agent_name,
414
- task=task,
415
- response=broadcast_message,
780
+ broadcast_message = sender.run(conversation.get_str())
781
+
782
+ conversation.add(
783
+ role=sender.agent_name,
784
+ message=broadcast_message,
416
785
  )
417
786
 
418
787
  # Then have all agents process it
419
788
  for agent in agents:
420
- response = agent.run(broadcast_message)
421
- conversation.add_log(
422
- agent_name=agent.agent_name,
423
- task=broadcast_message,
424
- response=response,
789
+ response = agent.run(conversation.get_str())
790
+ conversation.add(
791
+ role=agent.agent_name,
792
+ message=response,
425
793
  )
426
794
 
427
- return conversation.return_history()
795
+ return history_output_formatter(conversation, output_type)
428
796
 
429
797
  except Exception as error:
430
798
  logger.error(f"Error during broadcast: {error}")
@@ -432,8 +800,28 @@ async def broadcast(
432
800
 
433
801
 
434
802
  async def one_to_three(
435
- sender: Agent, agents: AgentListType, task: str
436
- ):
803
+ sender: Agent,
804
+ agents: AgentListType,
805
+ task: str,
806
+ output_type: OutputType = "dict",
807
+ ) -> Union[Dict[str, Any], List[str]]:
808
+ """
809
+ Implements one-to-three communication pattern where one agent sends to three others.
810
+
811
+ Args:
812
+ sender (Agent): The agent sending the message.
813
+ agents (AgentListType): List of three agents receiving the message.
814
+ task (str): The task to be processed.
815
+ output_type (OutputType, optional): The format of the output. Defaults to "dict".
816
+
817
+ Returns:
818
+ Union[Dict[str, Any], List[str]]: The formatted output of the communication.
819
+ If output_type is "dict", returns a dictionary containing the conversation history.
820
+ If output_type is "list", returns a list of responses.
821
+
822
+ Raises:
823
+ ValueError: If sender, agents, or task is empty, or if agents list doesn't contain exactly 3 agents.
824
+ """
437
825
  if len(agents) != 3:
438
826
  raise ValueError("The number of agents must be exactly 3.")
439
827
 
@@ -442,25 +830,28 @@ async def one_to_three(
442
830
 
443
831
  conversation = Conversation()
444
832
 
833
+ conversation.add(
834
+ role="User",
835
+ message=task,
836
+ )
837
+
445
838
  try:
446
839
  # Get sender's message
447
- sender_message = sender.run(task)
448
- conversation.add_log(
449
- agent_name=sender.agent_name,
450
- task=task,
451
- response=sender_message,
840
+ sender_message = sender.run(conversation.get_str())
841
+ conversation.add(
842
+ role=sender.agent_name,
843
+ message=sender_message,
452
844
  )
453
845
 
454
846
  # Have each receiver process the message
455
847
  for agent in agents:
456
- response = agent.run(sender_message)
457
- conversation.add_log(
458
- agent_name=agent.agent_name,
459
- task=sender_message,
460
- response=response,
848
+ response = agent.run(conversation.get_str())
849
+ conversation.add(
850
+ role=agent.agent_name,
851
+ message=response,
461
852
  )
462
853
 
463
- return conversation.return_history()
854
+ return history_output_formatter(conversation, output_type)
464
855
 
465
856
  except Exception as error:
466
857
  logger.error(f"Error in one_to_three: {error}")