swarms 7.7.2__py3-none-any.whl → 7.7.3__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 (34) 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 +93 -122
  12. swarms/structs/ma_utils.py +96 -0
  13. swarms/structs/mixture_of_agents.py +20 -103
  14. swarms/structs/multi_agent_router.py +32 -95
  15. swarms/structs/output_types.py +3 -16
  16. swarms/structs/stopping_conditions.py +30 -0
  17. swarms/structs/swarm_router.py +56 -4
  18. swarms/structs/swarming_architectures.py +576 -185
  19. swarms/telemetry/main.py +1 -7
  20. swarms/tools/mcp_client.py +209 -53
  21. swarms/tools/mcp_integration.py +1 -53
  22. swarms/utils/generate_keys.py +64 -0
  23. swarms/utils/history_output_formatter.py +2 -0
  24. {swarms-7.7.2.dist-info → swarms-7.7.3.dist-info}/METADATA +98 -263
  25. {swarms-7.7.2.dist-info → swarms-7.7.3.dist-info}/RECORD +28 -32
  26. swarms/schemas/agent_input_schema.py +0 -149
  27. swarms/structs/agents_available.py +0 -87
  28. swarms/structs/graph_swarm.py +0 -612
  29. swarms/structs/queue_swarm.py +0 -193
  30. swarms/structs/swarm_builder.py +0 -395
  31. swarms/structs/swarm_output_type.py +0 -23
  32. {swarms-7.7.2.dist-info → swarms-7.7.3.dist-info}/LICENSE +0 -0
  33. {swarms-7.7.2.dist-info → swarms-7.7.3.dist-info}/WHEEL +0 -0
  34. {swarms-7.7.2.dist-info → swarms-7.7.3.dist-info}/entry_points.txt +0 -0
@@ -1,193 +0,0 @@
1
- import queue
2
- import threading
3
- from typing import List
4
- from swarms.structs.agent import Agent
5
- from pydantic import BaseModel
6
- import os
7
- from swarms.utils.loguru_logger import logger
8
- from swarms.structs.base_swarm import BaseSwarm
9
- import time
10
-
11
-
12
- class AgentOutput(BaseModel):
13
- agent_name: str
14
- task: str
15
- result: str
16
- timestamp: str
17
-
18
-
19
- class SwarmRunMetadata(BaseModel):
20
- run_id: str
21
- name: str
22
- description: str
23
- agents: List[str]
24
- start_time: str
25
- end_time: str
26
- tasks_completed: int
27
- outputs: List[AgentOutput]
28
-
29
-
30
- class TaskQueueSwarm(BaseSwarm):
31
- """
32
- A swarm that processes tasks from a queue using multiple agents on different threads.
33
-
34
- Args:
35
- agents (List[Agent]): A list of agents of class Agent.
36
- name (str, optional): The name of the swarm. Defaults to "Task-Queue-Swarm".
37
- description (str, optional): The description of the swarm. Defaults to "A swarm that processes tasks from a queue using multiple agents on different threads.".
38
- autosave_on (bool, optional): Whether to automatically save the swarm metadata. Defaults to True.
39
- save_file_path (str, optional): The file path to save the swarm metadata. Defaults to "swarm_run_metadata.json".
40
- workspace_dir (str, optional): The directory path of the workspace. Defaults to os.getenv("WORKSPACE_DIR").
41
- return_metadata_on (bool, optional): Whether to return the swarm metadata after running. Defaults to False.
42
- max_loops (int, optional): The maximum number of loops to run the swarm. Defaults to 1.
43
-
44
- Attributes:
45
- agents (List[Agent]): A list of agents of class Agent.
46
- task_queue (queue.Queue): A queue to store the tasks.
47
- lock (threading.Lock): A lock for thread synchronization.
48
- autosave_on (bool): Whether to automatically save the swarm metadata.
49
- save_file_path (str): The file path to save the swarm metadata.
50
- workspace_dir (str): The directory path of the workspace.
51
- return_metadata_on (bool): Whether to return the swarm metadata after running.
52
- max_loops (int): The maximum number of loops to run the swarm.
53
- metadata (SwarmRunMetadata): The metadata of the swarm run.
54
- """
55
-
56
- def __init__(
57
- self,
58
- agents: List[Agent],
59
- name: str = "Task-Queue-Swarm",
60
- description: str = "A swarm that processes tasks from a queue using multiple agents on different threads.",
61
- autosave_on: bool = True,
62
- save_file_path: str = "swarm_run_metadata.json",
63
- workspace_dir: str = os.getenv("WORKSPACE_DIR"),
64
- return_metadata_on: bool = False,
65
- max_loops: int = 1,
66
- *args,
67
- **kwargs,
68
- ):
69
- super().__init__(
70
- name=name,
71
- description=description,
72
- agents=agents,
73
- *args,
74
- **kwargs,
75
- )
76
- self.agents = agents
77
- self.task_queue = queue.Queue()
78
- self.lock = threading.Lock()
79
- self.autosave_on = autosave_on
80
- self.save_file_path = save_file_path
81
- self.workspace_dir = workspace_dir or os.getenv(
82
- "WORKSPACE_DIR", "agent_workspace"
83
- )
84
- self.return_metadata_on = return_metadata_on
85
- self.max_loops = max_loops
86
-
87
- current_time = time.strftime("%Y%m%d%H%M%S")
88
- self.metadata = SwarmRunMetadata(
89
- run_id=f"swarm_run_{current_time}",
90
- name=name,
91
- description=description,
92
- agents=[agent.agent_name for agent in agents],
93
- start_time=current_time,
94
- end_time="",
95
- tasks_completed=0,
96
- outputs=[],
97
- )
98
-
99
- def reliability_checks(self):
100
- logger.info("Initializing reliability checks.")
101
-
102
- if not self.agents:
103
- raise ValueError(
104
- "You must provide a non-empty list of Agent instances."
105
- )
106
-
107
- if self.max_loops <= 0:
108
- raise ValueError("max_loops must be greater than zero.")
109
-
110
- logger.info(
111
- "Reliability checks successful. Swarm is ready for usage."
112
- )
113
-
114
- def add_task(self, task: str):
115
- """Adds a task to the queue."""
116
- self.task_queue.put(task)
117
-
118
- def _process_task(self, agent: Agent):
119
- """Processes tasks from the queue using the provided agent."""
120
- while True:
121
- try:
122
- task = self.task_queue.get_nowait()
123
- except queue.Empty:
124
- break
125
- try:
126
- logger.info(
127
- f"Agent {agent.agent_name} is running task: {task}"
128
- )
129
- result = agent.run(task)
130
- with self.lock:
131
- self.metadata.tasks_completed += 1
132
- self.metadata.outputs.append(
133
- AgentOutput(
134
- agent_name=agent.agent_name,
135
- task=task,
136
- result=result,
137
- timestamp=time.strftime(
138
- "%Y-%m-%d %H:%M:%S"
139
- ),
140
- )
141
- )
142
- logger.info(
143
- f"Agent {agent.agent_name} completed task: {task}"
144
- )
145
- logger.debug(f"Result: {result}")
146
- except Exception as e:
147
- logger.error(
148
- f"Agent {agent.agent_name} failed to complete task: {task}"
149
- )
150
- logger.exception(e)
151
- finally:
152
- self.task_queue.task_done()
153
-
154
- def run(self):
155
- """Runs the swarm by having agents pick up tasks from the queue."""
156
- logger.info(f"Starting swarm run: {self.metadata.run_id}")
157
-
158
- threads = [
159
- threading.Thread(
160
- target=self._process_task, args=(agent,), daemon=True
161
- )
162
- for agent in self.agents
163
- ]
164
-
165
- for thread in threads:
166
- thread.start()
167
-
168
- self.task_queue.join()
169
-
170
- for thread in threads:
171
- thread.join()
172
-
173
- self.metadata.end_time = time.strftime("%Y%m%d%H%M%S")
174
-
175
- if self.autosave_on:
176
- self.save_json_to_file()
177
-
178
- # if self.return_metadata_on:
179
- # return self.metadata.model_dump_json(indent=4)
180
- return self.export_metadata()
181
-
182
- def save_json_to_file(self):
183
- json_string = self.export_metadata()
184
- file_path = os.path.join(
185
- self.workspace_dir, self.save_file_path
186
- )
187
- os.makedirs(os.path.dirname(file_path), exist_ok=True)
188
- with open(file_path, "w") as f:
189
- f.write(json_string)
190
- logger.info(f"Metadata saved to {file_path}")
191
-
192
- def export_metadata(self):
193
- return self.metadata.model_dump_json(indent=4)
@@ -1,395 +0,0 @@
1
- import os
2
- from typing import List, Optional
3
-
4
- from loguru import logger
5
- from pydantic import BaseModel, Field
6
- from pydantic.v1 import validator
7
- from tenacity import (
8
- retry,
9
- stop_after_attempt,
10
- wait_exponential,
11
- )
12
-
13
- from swarms.structs.agent import Agent
14
- from swarms.structs.swarm_router import SwarmRouter, SwarmType
15
- from swarms.utils.function_caller_model import OpenAIFunctionCaller
16
-
17
-
18
- BOSS_SYSTEM_PROMPT = """
19
- Manage a swarm of worker agents to efficiently serve the user by deciding whether to create new agents or delegate tasks. Ensure operations are efficient and effective.
20
-
21
- ### Instructions:
22
-
23
- 1. **Task Assignment**:
24
- - Analyze available worker agents when a task is presented.
25
- - Delegate tasks to existing agents with clear, direct, and actionable instructions if an appropriate agent is available.
26
- - If no suitable agent exists, create a new agent with a fitting system prompt to handle the task.
27
-
28
- 2. **Agent Creation**:
29
- - Name agents according to the task they are intended to perform (e.g., "Twitter Marketing Agent").
30
- - Provide each new agent with a concise and clear system prompt that includes its role, objectives, and any tools it can utilize.
31
-
32
- 3. **Efficiency**:
33
- - Minimize redundancy and maximize task completion speed.
34
- - Avoid unnecessary agent creation if an existing agent can fulfill the task.
35
-
36
- 4. **Communication**:
37
- - Be explicit in task delegation instructions to avoid ambiguity and ensure effective task execution.
38
- - Require agents to report back on task completion or encountered issues.
39
-
40
- 5. **Reasoning and Decisions**:
41
- - Offer brief reasoning when selecting or creating agents to maintain transparency.
42
- - Avoid using an agent if unnecessary, with a clear explanation if no agents are suitable for a task.
43
-
44
- # Output Format
45
-
46
- Present your plan in clear, bullet-point format or short concise paragraphs, outlining task assignment, agent creation, efficiency strategies, and communication protocols.
47
-
48
- # Notes
49
-
50
- - Preserve transparency by always providing reasoning for task-agent assignments and creation.
51
- - Ensure instructions to agents are unambiguous to minimize error.
52
-
53
- """
54
-
55
-
56
- class AgentConfig(BaseModel):
57
- """Configuration for an individual agent in a swarm"""
58
-
59
- name: str = Field(
60
- description="The name of the agent",
61
- )
62
- description: str = Field(
63
- description="A description of the agent's purpose and capabilities",
64
- )
65
- system_prompt: str = Field(
66
- description="The system prompt that defines the agent's behavior",
67
- )
68
-
69
-
70
- class SwarmConfig(BaseModel):
71
- """Configuration for a swarm of cooperative agents"""
72
-
73
- name: str = Field(
74
- description="The name of the swarm",
75
- example="Research-Writing-Swarm",
76
- )
77
- description: str = Field(
78
- description="The description of the swarm's purpose and capabilities",
79
- example="A swarm of agents that work together to research topics and write articles",
80
- )
81
- agents: List[AgentConfig] = Field(
82
- description="The list of agents that make up the swarm",
83
- )
84
- max_loops: int = Field(
85
- description="The maximum number of loops for the swarm to iterate on",
86
- )
87
-
88
- @validator("agents")
89
- def validate_agents(cls, v):
90
- if not v:
91
- raise ValueError("Swarm must have at least one agent")
92
- return v
93
-
94
-
95
- class AutoSwarmBuilderOutput(BaseModel):
96
- """A class that automatically builds and manages swarms of AI agents with enhanced error handling."""
97
-
98
- name: Optional[str] = Field(
99
- description="The name of the swarm",
100
- example="DefaultSwarm",
101
- default=None,
102
- )
103
- description: Optional[str] = Field(
104
- description="The description of the swarm's purpose and capabilities",
105
- example="Generic AI Agent Swarm",
106
- default=None,
107
- )
108
- verbose: Optional[bool] = Field(
109
- description="Whether to display verbose output",
110
- default=None,
111
- )
112
- model_name: Optional[str] = Field(
113
- description="The name of the OpenAI model to use",
114
- default=None,
115
- )
116
- boss_output_schema: Optional[list] = Field(
117
- description="The schema for the output of the BOSS system prompt",
118
- default=None,
119
- )
120
- director_agents_created: Optional[SwarmConfig] = Field(
121
- description="The agents created by the director",
122
- default=None,
123
- )
124
- swarm_router_outputs: Optional[list] = Field(
125
- description="The outputs from the swarm router",
126
- default=None,
127
- )
128
- max_loops: Optional[int] = Field(
129
- description="The maximum number of loops for the swarm to iterate on",
130
- default=None,
131
- )
132
- swarm_type: Optional[SwarmType] = Field(
133
- description="The type of swarm to build",
134
- default=None,
135
- )
136
-
137
-
138
- class AutoSwarmBuilder:
139
- """A class that automatically builds and manages swarms of AI agents with enhanced error handling."""
140
-
141
- def __init__(
142
- self,
143
- name: Optional[str] = "autonomous-swarm-builder",
144
- description: Optional[
145
- str
146
- ] = "Given a task, this swarm will automatically create specialized agents and route it to the appropriate agents.",
147
- verbose: bool = True,
148
- model_name: str = "gpt-4o",
149
- boss_output_schema: list = None,
150
- swarm_router_outputs: AutoSwarmBuilderOutput = None,
151
- max_loops: int = 1,
152
- swarm_type: str = "SequentialWorkflow",
153
- auto_generate_prompts_for_agents: bool = False,
154
- shared_memory_system: callable = None,
155
- ):
156
- self.name = name or "DefaultSwarm"
157
- self.description = description or "Generic AI Agent Swarm"
158
- self.verbose = verbose
159
- self.agents_pool = []
160
- self.api_key = os.getenv("OPENAI_API_KEY")
161
- self.model_name = model_name
162
- self.boss_output_schema = boss_output_schema
163
- self.max_loops = max_loops
164
- self.swarm_type = swarm_type
165
- self.auto_generate_prompts_for_agents = (
166
- auto_generate_prompts_for_agents
167
- )
168
- self.shared_memory_system = shared_memory_system
169
- self.auto_swarm_builder_output = AutoSwarmBuilderOutput(
170
- name=name,
171
- description=description,
172
- verbose=verbose,
173
- model_name=model_name,
174
- boss_output_schema=boss_output_schema or [],
175
- swarm_router_outputs=swarm_router_outputs or [],
176
- max_loops=max_loops,
177
- swarm_type=swarm_type,
178
- )
179
-
180
- logger.info(
181
- "Initialized AutoSwarmBuilder",
182
- extra={
183
- "swarm_name": self.name,
184
- "description": self.description,
185
- "model": self.model_name,
186
- },
187
- )
188
-
189
- def run(
190
- self,
191
- task: str,
192
- image_url: Optional[str] = None,
193
- *args,
194
- **kwargs,
195
- ):
196
- """Run the swarm on a given task with error handling and retries."""
197
- if not task or not task.strip():
198
- raise ValueError("Task cannot be empty")
199
-
200
- logger.info("Starting swarm execution", extra={"task": task})
201
-
202
- try:
203
- # Create agents for the task
204
- agents = self._create_agents(task)
205
- if not agents:
206
- raise ValueError(
207
- "No agents were created for the task"
208
- )
209
-
210
- # Execute the task through the swarm router
211
- logger.info(
212
- "Routing task through swarm",
213
- extra={"num_agents": len(agents)},
214
- )
215
- output = self.swarm_router(
216
- agents=agents,
217
- task=task,
218
- image_url=image_url,
219
- *args,
220
- **kwargs,
221
- )
222
- self.auto_swarm_builder_output.swarm_router_outputs.append(
223
- output
224
- )
225
- print(output)
226
-
227
- logger.info("Swarm execution completed successfully")
228
- # return output
229
- return self.auto_swarm_builder_output.model_dump_json(
230
- indent=4
231
- )
232
-
233
- except Exception as e:
234
- logger.error(
235
- f"Error during swarm execution: {str(e)}",
236
- )
237
- raise e
238
-
239
- def _create_agents(
240
- self,
241
- task: str,
242
- ) -> List[Agent]:
243
- """Create the necessary agents for a task with enhanced error handling."""
244
- logger.info("Creating agents for task", extra={"task": task})
245
-
246
- try:
247
- model = OpenAIFunctionCaller(
248
- system_prompt=BOSS_SYSTEM_PROMPT,
249
- api_key=self.api_key,
250
- temperature=0.1,
251
- base_model=SwarmConfig,
252
- )
253
-
254
- agents_config = model.run(task)
255
- logger.info(
256
- f"Director has successfully created agents: {agents_config}"
257
- )
258
- self.auto_swarm_builder_output.director_agents_created = (
259
- agents_config
260
- )
261
-
262
- if isinstance(agents_config, dict):
263
- agents_config = SwarmConfig(**agents_config)
264
-
265
- # Update swarm configuration
266
- self.name = agents_config.name
267
- self.description = agents_config.description
268
-
269
- # Create agents from configuration
270
- agents = []
271
- for agent_config in agents_config.agents:
272
- if isinstance(agent_config, dict):
273
- agent_config = AgentConfig(**agent_config)
274
-
275
- agent = self.build_agent(
276
- agent_name=agent_config.name,
277
- agent_description=agent_config.description,
278
- agent_system_prompt=agent_config.system_prompt,
279
- )
280
- agents.append(agent)
281
-
282
- print(
283
- f"Agent created: {agent_config.name}: Description: {agent_config.description}"
284
- )
285
-
286
- # # Add available agents showcase to system prompts
287
- # agents_available = showcase_available_agents(
288
- # name=self.name,
289
- # description=self.description,
290
- # agents=agents,
291
- # )
292
-
293
- # for agent in agents:
294
- # agent.system_prompt += "\n" + agents_available
295
-
296
- logger.info(
297
- "Successfully created agents",
298
- extra={"num_agents": len(agents)},
299
- )
300
- return agents
301
-
302
- except Exception as e:
303
- logger.error(
304
- f"Error creating agents: {str(e)}", exc_info=True
305
- )
306
- raise
307
-
308
- def build_agent(
309
- self,
310
- agent_name: str,
311
- agent_description: str,
312
- agent_system_prompt: str,
313
- *args,
314
- **kwargs,
315
- ) -> Agent:
316
- """Build a single agent with enhanced error handling."""
317
- logger.info(
318
- "Building agent", extra={"agent_name": agent_name}
319
- )
320
-
321
- try:
322
- agent = Agent(
323
- agent_name=agent_name,
324
- description=agent_description,
325
- system_prompt=agent_system_prompt,
326
- model_name="gpt-4o",
327
- verbose=self.verbose,
328
- dynamic_temperature_enabled=False,
329
- return_step_meta=False,
330
- output_type="str",
331
- streaming_on=True,
332
- )
333
- return agent
334
-
335
- except Exception as e:
336
- logger.error(
337
- f"Error building agent: {str(e)}", exc_info=True
338
- )
339
- raise
340
-
341
- @retry(
342
- stop=stop_after_attempt(3),
343
- wait=wait_exponential(multiplier=1, min=4, max=10),
344
- )
345
- def swarm_router(
346
- self,
347
- agents: List[Agent],
348
- task: str,
349
- img: Optional[str] = None,
350
- *args,
351
- **kwargs,
352
- ) -> str:
353
- """Route tasks between agents in the swarm with error handling and retries."""
354
- logger.info(
355
- "Initializing swarm router",
356
- extra={"num_agents": len(agents)},
357
- )
358
-
359
- try:
360
- swarm_router_instance = SwarmRouter(
361
- name=self.name,
362
- description=self.description,
363
- agents=agents,
364
- swarm_type=self.swarm_type,
365
- auto_generate_prompts=self.auto_generate_prompts_for_agents,
366
- )
367
-
368
- # formatted_task = f"{self.name} {self.description} {task}"
369
- result = swarm_router_instance.run(
370
- task=task, *args, **kwargs
371
- )
372
-
373
- logger.info("Successfully completed swarm routing")
374
- return result
375
-
376
- except Exception as e:
377
- logger.error(
378
- f"Error in swarm router: {str(e)}", exc_info=True
379
- )
380
- raise
381
-
382
-
383
- # swarm = AutoSwarmBuilder(
384
- # name="ChipDesign-Swarm",
385
- # description="A swarm of specialized AI agents for chip design",
386
- # swarm_type="ConcurrentWorkflow",
387
- # )
388
-
389
- # try:
390
- # result = swarm.run(
391
- # "Design a new AI accelerator chip optimized for transformer model inference..."
392
- # )
393
- # print(result)
394
- # except Exception as e:
395
- # print(f"An error occurred: {e}")
@@ -1,23 +0,0 @@
1
- import time
2
- from typing import List
3
- import uuid
4
- from pydantic import BaseModel, Field
5
-
6
-
7
- class AgentRespond(BaseModel):
8
- id: str = Field(default=uuid.uuid4().hex)
9
- timestamp: str = Field(default=time.time())
10
- agent_position: int = Field(description="Agent in swarm position")
11
- agent_name: str
12
- agent_response: str = Field(description="Agent response")
13
-
14
-
15
- class SwarmOutput(BaseModel):
16
- id: str = Field(default=uuid.uuid4().hex)
17
- timestamp: str = Field(default=time.time())
18
- name: str = Field(description="Swarm name")
19
- description: str = Field(description="Swarm description")
20
- swarm_type: str = Field(description="Swarm type")
21
- agent_outputs: List[AgentRespond] = Field(
22
- description="List of agent responses"
23
- )
File without changes