swarms 7.6.1__py3-none-any.whl → 7.6.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 (42) hide show
  1. swarms/__init__.py +1 -0
  2. swarms/agents/__init__.py +4 -5
  3. swarms/agents/flexion_agent.py +2 -1
  4. swarms/agents/reasoning_agents.py +10 -0
  5. swarms/client/__init__.py +15 -0
  6. swarms/prompts/multi_agent_collab_prompt.py +313 -0
  7. swarms/structs/__init__.py +10 -17
  8. swarms/structs/agent.py +178 -262
  9. swarms/structs/base_swarm.py +0 -7
  10. swarms/structs/concurrent_workflow.py +2 -2
  11. swarms/structs/conversation.py +16 -2
  12. swarms/structs/de_hallucination_swarm.py +8 -4
  13. swarms/structs/dynamic_conversational_swarm.py +226 -0
  14. swarms/structs/groupchat.py +80 -84
  15. swarms/structs/hiearchical_swarm.py +1 -1
  16. swarms/structs/hybrid_hiearchical_peer_swarm.py +256 -0
  17. swarms/structs/majority_voting.py +1 -1
  18. swarms/structs/mixture_of_agents.py +1 -1
  19. swarms/structs/multi_agent_exec.py +63 -139
  20. swarms/structs/multi_agent_orchestrator.py +1 -1
  21. swarms/structs/output_types.py +3 -0
  22. swarms/structs/rearrange.py +66 -205
  23. swarms/structs/sequential_workflow.py +34 -47
  24. swarms/structs/swarm_router.py +3 -2
  25. swarms/telemetry/bootup.py +19 -38
  26. swarms/telemetry/main.py +62 -22
  27. swarms/tools/tool_schema_base_model.py +57 -0
  28. swarms/utils/auto_download_check_packages.py +2 -2
  29. swarms/utils/disable_logging.py +0 -17
  30. swarms/utils/history_output_formatter.py +8 -3
  31. swarms/utils/litellm_wrapper.py +117 -1
  32. {swarms-7.6.1.dist-info → swarms-7.6.4.dist-info}/METADATA +1 -5
  33. {swarms-7.6.1.dist-info → swarms-7.6.4.dist-info}/RECORD +37 -37
  34. swarms/structs/agent_security.py +0 -318
  35. swarms/structs/airflow_swarm.py +0 -430
  36. swarms/structs/output_type.py +0 -18
  37. swarms/utils/agent_ops_check.py +0 -26
  38. swarms/utils/pandas_utils.py +0 -92
  39. /swarms/{structs/swarms_api.py → client/main.py} +0 -0
  40. {swarms-7.6.1.dist-info → swarms-7.6.4.dist-info}/LICENSE +0 -0
  41. {swarms-7.6.1.dist-info → swarms-7.6.4.dist-info}/WHEEL +0 -0
  42. {swarms-7.6.1.dist-info → swarms-7.6.4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,256 @@
1
+ import os
2
+ from typing import List
3
+ from swarms.structs.agent import Agent
4
+ from swarms.structs.conversation import Conversation
5
+ from swarms.structs.multi_agent_exec import get_swarms_info
6
+ from swarms.structs.swarm_router import SwarmRouter
7
+ from swarms.utils.history_output_formatter import (
8
+ history_output_formatter,
9
+ )
10
+ from concurrent.futures import ThreadPoolExecutor, as_completed
11
+ from typing import Union, Callable
12
+
13
+ tools = [
14
+ {
15
+ "type": "function",
16
+ "function": {
17
+ "name": "select_swarm",
18
+ "description": "Analyzes the input task and selects the most appropriate swarm configuration, outputting both the swarm name and the formatted task.",
19
+ "parameters": {
20
+ "type": "object",
21
+ "properties": {
22
+ "reasoning": {
23
+ "type": "string",
24
+ "description": "The reasoning behind the selection of the swarm and task description.",
25
+ },
26
+ "swarm_name": {
27
+ "type": "string",
28
+ "description": "The name of the selected swarm that is most appropriate for handling the given task.",
29
+ },
30
+ "task_description": {
31
+ "type": "string",
32
+ "description": "A clear and structured description of the task to be performed by the swarm.",
33
+ },
34
+ },
35
+ "required": [
36
+ "reasoning",
37
+ "swarm_name",
38
+ "task_description",
39
+ ],
40
+ },
41
+ },
42
+ },
43
+ ]
44
+
45
+ router_system_prompt = """
46
+ You are an intelligent Router Agent responsible for analyzing tasks and directing them to the most appropriate swarm in our system. Your role is critical in ensuring optimal task execution and resource utilization.
47
+
48
+ Key Responsibilities:
49
+ 1. Task Analysis:
50
+ - Carefully analyze the input task's requirements, complexity, and domain
51
+ - Identify key components and dependencies
52
+ - Determine the specialized skills needed for completion
53
+
54
+ 2. Swarm Selection Criteria:
55
+ - Match task requirements with swarm capabilities
56
+ - Consider swarm specializations and past performance
57
+ - Evaluate computational resources needed
58
+ - Account for task priority and time constraints
59
+
60
+ 3. Decision Making Framework:
61
+ - Use a systematic approach to evaluate all available swarms
62
+ - Consider load balancing across the system
63
+ - Factor in swarm availability and current workload
64
+ - Assess potential risks and failure points
65
+
66
+ 4. Output Requirements:
67
+ - Provide clear justification for swarm selection
68
+ - Structure the task description in a way that maximizes swarm efficiency
69
+ - Include any relevant context or constraints
70
+ - Ensure all critical information is preserved
71
+
72
+ Best Practices:
73
+ - Always prefer specialized swarms for domain-specific tasks
74
+ - Consider breaking complex tasks into subtasks when appropriate
75
+ - Maintain consistency in task formatting across different swarms
76
+ - Include error handling considerations in task descriptions
77
+
78
+ Your output must strictly follow the required format:
79
+ {
80
+ "swarm_name": "Name of the selected swarm",
81
+ "task_description": "Detailed and structured task description"
82
+ }
83
+
84
+ Remember: Your selection directly impacts the overall system performance and task completion success rate. Take all factors into account before making your final decision.
85
+ """
86
+
87
+
88
+ class HybridHierarchicalClusterSwarm:
89
+ """
90
+ A class representing a Hybrid Hierarchical-Cluster Swarm that routes tasks to appropriate swarms.
91
+
92
+ Attributes:
93
+ name (str): The name of the swarm.
94
+ description (str): A description of the swarm's functionality.
95
+ swarms (List[SwarmRouter]): A list of available swarm routers.
96
+ max_loops (int): The maximum number of loops for task processing.
97
+ output_type (str): The format of the output (e.g., list).
98
+ conversation (Conversation): An instance of the Conversation class to manage interactions.
99
+ router_agent (Agent): An instance of the Agent class responsible for routing tasks.
100
+ """
101
+
102
+ def __init__(
103
+ self,
104
+ name: str = "Hybrid Hierarchical-Cluster Swarm",
105
+ description: str = "A swarm that uses a hybrid hierarchical-peer model to solve complex tasks.",
106
+ swarms: List[Union[SwarmRouter, Callable]] = [],
107
+ max_loops: int = 1,
108
+ output_type: str = "list",
109
+ router_agent_model_name: str = "gpt-4o-mini",
110
+ *args,
111
+ **kwargs,
112
+ ):
113
+ self.name = name
114
+ self.description = description
115
+ self.swarms = swarms
116
+ self.max_loops = max_loops
117
+ self.output_type = output_type
118
+
119
+ self.conversation = Conversation()
120
+
121
+ self.router_agent = Agent(
122
+ agent_name="Router Agent",
123
+ agent_description="A router agent that routes tasks to the appropriate swarms.",
124
+ system_prompt=f"{router_system_prompt}\n\n{get_swarms_info()}",
125
+ tools_list_dictionary=tools,
126
+ model_name=router_agent_model_name,
127
+ max_loops=1,
128
+ output_type="final",
129
+ )
130
+
131
+ def convert_str_to_dict(self, response: str):
132
+ # Handle response whether it's a string or dictionary
133
+ if isinstance(response, str):
134
+ try:
135
+ import json
136
+
137
+ response = json.loads(response)
138
+ except json.JSONDecodeError:
139
+ raise ValueError(
140
+ "Invalid JSON response from router agent"
141
+ )
142
+
143
+ return response
144
+
145
+ def run(self, task: str, *args, **kwargs):
146
+ """
147
+ Runs the routing process for a given task.
148
+
149
+ Args:
150
+ task (str): The task to be processed by the swarm.
151
+
152
+ Returns:
153
+ str: The formatted history output of the conversation.
154
+
155
+ Raises:
156
+ ValueError: If the task is empty or invalid.
157
+ """
158
+ if not task:
159
+ raise ValueError("Task cannot be empty.")
160
+
161
+ self.conversation.add(role="User", content=task)
162
+
163
+ response = self.router_agent.run(task=task)
164
+
165
+ if isinstance(response, str):
166
+ response = self.convert_str_to_dict(response)
167
+ else:
168
+ pass
169
+
170
+ swarm_name = response.get("swarm_name")
171
+ task_description = response.get("task_description")
172
+
173
+ if not swarm_name or not task_description:
174
+ raise ValueError(
175
+ "Invalid response from router agent: both 'swarm_name' and 'task_description' must be present. "
176
+ f"Received: swarm_name={swarm_name}, task_description={task_description}. "
177
+ f"Please check the response format from the model: {self.router_agent.model_name}."
178
+ )
179
+
180
+ self.route_task(swarm_name, task_description)
181
+
182
+ return history_output_formatter(
183
+ self.conversation, self.output_type
184
+ )
185
+
186
+ def find_swarm_by_name(self, swarm_name: str):
187
+ """
188
+ Finds a swarm by its name.
189
+
190
+ Args:
191
+ swarm_name (str): The name of the swarm to find.
192
+
193
+ Returns:
194
+ SwarmRouter: The found swarm router, or None if not found.
195
+ """
196
+ for swarm in self.swarms:
197
+ if swarm.name == swarm_name:
198
+ return swarm
199
+ return None
200
+
201
+ def route_task(self, swarm_name: str, task_description: str):
202
+ """
203
+ Routes the task to the specified swarm.
204
+
205
+ Args:
206
+ swarm_name (str): The name of the swarm to route the task to.
207
+ task_description (str): The description of the task to be executed.
208
+
209
+ Raises:
210
+ ValueError: If the swarm is not found.
211
+ """
212
+ swarm = self.find_swarm_by_name(swarm_name)
213
+
214
+ if swarm:
215
+ output = swarm.run(task_description)
216
+ self.conversation.add(role=swarm.name, content=output)
217
+ else:
218
+ raise ValueError(f"Swarm '{swarm_name}' not found.")
219
+
220
+ def batched_run(self, tasks: List[str]):
221
+ """
222
+ Runs the routing process for a list of tasks in batches.
223
+
224
+ Args:
225
+ tasks (List[str]): A list of tasks to be processed by the swarm.
226
+
227
+ Returns:
228
+ List[str]: A list of formatted history outputs for each batch.
229
+
230
+ Raises:
231
+ ValueError: If the task list is empty or invalid.
232
+ """
233
+ if not tasks:
234
+ raise ValueError("Task list cannot be empty.")
235
+
236
+ max_workers = os.cpu_count() * 2
237
+
238
+ results = []
239
+
240
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
241
+ # Submit all tasks to the executor
242
+ future_to_task = {
243
+ executor.submit(self.run, task): task
244
+ for task in tasks
245
+ }
246
+
247
+ # Collect results as they complete
248
+ for future in as_completed(future_to_task):
249
+ try:
250
+ result = future.result()
251
+ results.append(result)
252
+ except Exception as e:
253
+ # Handle any errors that occurred during task execution
254
+ results.append(f"Error processing task: {str(e)}")
255
+
256
+ return results
@@ -9,7 +9,7 @@ from typing import Any, Callable, List, Optional
9
9
  from swarms.structs.agent import Agent
10
10
  from swarms.structs.conversation import Conversation
11
11
  from swarms.structs.multi_agent_exec import run_agents_concurrently
12
- from swarms.structs.output_type import OutputType
12
+ from swarms.structs.output_types import OutputType
13
13
  from swarms.utils.formatter import formatter
14
14
  from swarms.utils.loguru_logger import initialize_logger
15
15
 
@@ -11,7 +11,7 @@ from swarms.schemas.agent_step_schemas import ManySteps
11
11
  from swarms.prompts.ag_prompt import aggregator_system_prompt
12
12
  from swarms.utils.loguru_logger import initialize_logger
13
13
  import concurrent.futures
14
- from swarms.structs.output_type import OutputType
14
+ from swarms.structs.output_types import OutputType
15
15
  from swarms.structs.conversation import Conversation
16
16
 
17
17
  logger = initialize_logger(log_folder="mixture_of_agents")
@@ -5,7 +5,7 @@ from concurrent.futures import (
5
5
  ThreadPoolExecutor,
6
6
  )
7
7
  from dataclasses import dataclass
8
- from typing import Any, List
8
+ from typing import Any, Callable, List, Union
9
9
 
10
10
  import psutil
11
11
 
@@ -415,141 +415,65 @@ def run_agents_with_tasks_concurrently(
415
415
  )
416
416
 
417
417
 
418
- # from joblib import Parallel, delayed
419
-
420
-
421
- # def run_agents_joblib(
422
- # agents: List[Any],
423
- # tasks: List[str] = [],
424
- # img: List[str] = None,
425
- # max_workers: int = None,
426
- # max_loops: int = 1,
427
- # prefer: str = "threads",
428
- # ) -> List[Any]:
429
- # """
430
- # Executes a list of agents with their corresponding tasks concurrently using joblib.
431
-
432
- # Each agent is expected to have a .run() method that accepts at least:
433
- # - task: A string indicating the task to execute.
434
- # - img: (Optional) A string representing image input.
435
-
436
- # Args:
437
- # agents (List[Any]): A list of agent instances.
438
- # tasks (List[str], optional): A list of task strings. If provided, each agent gets a task.
439
- # If fewer tasks than agents, the first task is reused.
440
- # img (List[str], optional): A list of image strings. If provided, each agent gets an image.
441
- # If fewer images than agents, the first image is reused.
442
- # max_workers (int, optional): The maximum number of processes to use.
443
- # Defaults to all available CPU cores.
444
- # max_loops (int, optional): Number of times to execute the whole batch.
445
-
446
- # Returns:
447
- # List[Any]: The list of results returned by each agent’s run() method.
448
- # """
449
- # max_workers = max_workers or os.cpu_count()
450
- # results = []
451
-
452
- # for _ in range(max_loops):
453
- # results.extend(
454
- # Parallel(n_jobs=max_workers, prefer=prefer)(
455
- # delayed(lambda a, t, i: a.run(task=t, img=i))(
456
- # agent,
457
- # (
458
- # tasks[idx]
459
- # if tasks and idx < len(tasks)
460
- # else (tasks[0] if tasks else "")
461
- # ),
462
- # (
463
- # img[idx]
464
- # if img and idx < len(img)
465
- # else (img[0] if img else None)
466
- # ),
467
- # )
468
- # for idx, agent in enumerate(agents)
469
- # )
470
- # )
471
-
472
- # return results
473
-
474
-
475
- # # Example usage:
476
- # if __name__ == '__main__':
477
- # # Dummy Agent class for demonstration.
478
- # class Agent:
479
- # def __init__(self, agent_name, max_loops, model_name):
480
- # self.agent_name = agent_name
481
- # self.max_loops = max_loops
482
- # self.model_name = model_name
483
-
484
- # def run(self, task: str, img: str = None) -> str:
485
- # img_info = f" with image '{img}'" if img else ""
486
- # return (f"{self.agent_name} using model '{self.model_name}' processed task: '{task}'{img_info}")
487
-
488
- # # Create a few Agent instances.
489
- # agents = [
490
- # Agent(
491
- # agent_name=f"Financial-Analysis-Agent_parallel_swarm{i}",
492
- # max_loops=1,
493
- # model_name="gpt-4o-mini",
494
- # )
495
- # for i in range(3)
496
- # ]
497
-
498
- # task = "How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria"
499
- # outputs = run_agents_process_pool(agents, tasks=[task])
500
-
501
- # for i, output in enumerate(outputs):
502
- # print(f"Output from agent {i+1}:\n{output}")
503
-
504
- # # Example usage:
505
- # if __name__ == '__main__':
506
- # # A sample agent class with a run method.
507
- # class SampleAgent:
508
- # def __init__(self, name):
509
- # self.name = name
510
-
511
- # def run(self, task, device, device_id, no_clusterops):
512
- # # Simulate some processing.
513
- # return (f"Agent {self.name} processed task '{task}' on {device} "
514
- # f"(device_id={device_id}), no_clusterops={no_clusterops}")
515
-
516
- # # Create a list of sample agents.
517
- # agents = [SampleAgent(f"Agent_{i}") for i in range(5)]
518
- # # Define tasks; if fewer tasks than agents, the first task will be reused.
519
- # tasks = ["task1", "task2", "task3"]
520
-
521
- # outputs = run_agents_with_tasks_concurrently(
522
- # agents=agents,
523
- # tasks=tasks,
524
- # max_workers=4,
525
- # device="cpu",
526
- # device_id=1,
527
- # all_cores=True,
528
- # no_clusterops=False
529
- # )
530
-
531
- # for output in outputs:
532
- # print(output)
533
-
534
-
535
- # # Example usage:
536
- # if __name__ == "__main__":
537
- # # Initialize your agents (for example, 3 agents)
538
- # agents = [
539
- # Agent(
540
- # agent_name=f"Financial-Analysis-Agent_parallel_swarm{i}",
541
- # max_loops=1,
542
- # model_name="gpt-4o-mini",
543
- # )
544
- # for i in range(3)
545
- # ]
546
-
547
- # # Generate a list of tasks.
548
- # tasks = [
549
- # "How can I establish a ROTH IRA to buy stocks and get a tax break?",
550
- # "What are the criteria for establishing a ROTH IRA?",
551
- # "What are the tax benefits of a ROTH IRA?",
552
- # "How to buy stocks using a ROTH IRA?",
553
- # "What are the limitations of a ROTH IRA?",
554
- # ]
555
- # outputs = run_agents_joblib(agents, tasks)
418
+ def get_swarms_info(swarms: List[Callable]) -> str:
419
+ """
420
+ Fetches and formats information about all available swarms in the system.
421
+
422
+ Returns:
423
+ str: A formatted string containing names and descriptions of all swarms.
424
+ """
425
+ if not swarms:
426
+ return "No swarms currently available in the system."
427
+
428
+ swarm_info = [
429
+ "Available Swarms:",
430
+ "",
431
+ ] # Empty string for line spacing
432
+
433
+ for idx, swarm in enumerate(swarms, 1):
434
+ swarm_info.extend(
435
+ [
436
+ f"[Swarm {idx}]",
437
+ f"Name: {swarm.name}",
438
+ f"Description: {swarm.description}",
439
+ f"Length of Agents: {len(swarm.agents)}",
440
+ f"Swarm Type: {swarm.swarm_type}",
441
+ "", # Empty string for line spacing between swarms
442
+ ]
443
+ )
444
+
445
+ return "\n".join(swarm_info).strip()
446
+
447
+
448
+ def get_agents_info(
449
+ agents: List[Union[Agent, Callable]], team_name: str = None
450
+ ) -> str:
451
+ """
452
+ Fetches and formats information about all available agents in the system.
453
+
454
+ Returns:
455
+ str: A formatted string containing names and descriptions of all swarms.
456
+ """
457
+ if not agents:
458
+ return "No agents currently available in the system."
459
+
460
+ agent_info = [
461
+ f"Available Agents for Team: {team_name}",
462
+ "",
463
+ ] # Empty string for line spacing
464
+
465
+ for idx, agent in enumerate(agents, 1):
466
+ agent_info.extend(
467
+ [
468
+ "\n",
469
+ f"[Agent {idx}]",
470
+ f"Name: {agent.agent_name}",
471
+ f"Description: {agent.agent_description}",
472
+ f"Role: {agent.role}",
473
+ f"Model: {agent.model_name}",
474
+ f"Max Loops: {agent.max_loops}",
475
+ "\n",
476
+ ]
477
+ )
478
+
479
+ return "\n".join(agent_info).strip()
@@ -18,7 +18,7 @@ from pydantic import BaseModel, Field
18
18
  from swarms.utils.function_caller_model import OpenAIFunctionCaller
19
19
  from swarms.structs.agent import Agent
20
20
  from swarms.structs.conversation import Conversation
21
- from swarms.structs.output_type import OutputType
21
+ from swarms.structs.output_types import OutputType
22
22
  from swarms.utils.any_to_str import any_to_str
23
23
 
24
24
 
@@ -14,3 +14,6 @@ OutputType = Literal[
14
14
  "string",
15
15
  "str",
16
16
  ]
17
+
18
+ # Use the OutputType for type annotations
19
+ output_type: OutputType