swarms 7.9.7__py3-none-any.whl → 7.9.9__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.
@@ -1,22 +1,33 @@
1
- import json
2
- import os
3
- from typing import Any, List, Optional, Union, Dict
1
+ """
2
+ Flow:
3
+
4
+ 1. User provides a task
5
+ 2. Director creates a plan
6
+ 3. Director distributes orders to agents individually or multiple tasks at once
7
+ 4. Agents execute tasks and report back to the director
8
+ 5. Director evaluates results and issues new orders if needed (up to max_loops)
9
+ 6. All context and conversation history is preserved throughout the process
10
+
11
+ """
12
+
13
+ import traceback
14
+ from typing import Any, Callable, List, Literal, Optional, Union
4
15
 
5
16
  from pydantic import BaseModel, Field
6
17
 
18
+ from swarms.prompts.hiearchical_system_prompt import (
19
+ HIEARCHICAL_SWARM_SYSTEM_PROMPT,
20
+ )
7
21
  from swarms.structs.agent import Agent
8
22
  from swarms.structs.base_swarm import BaseSwarm
9
23
  from swarms.structs.conversation import Conversation
10
- from swarms.utils.output_types import OutputType
11
- from swarms.utils.any_to_str import any_to_str
12
- from swarms.utils.formatter import formatter
13
-
14
- from swarms.utils.function_caller_model import OpenAIFunctionCaller
15
- from swarms.utils.loguru_logger import initialize_logger
24
+ from swarms.structs.ma_utils import list_all_agents
25
+ from swarms.tools.base_tool import BaseTool
16
26
  from swarms.utils.history_output_formatter import (
17
27
  history_output_formatter,
18
28
  )
19
- from swarms.structs.ma_utils import list_all_agents
29
+ from swarms.utils.loguru_logger import initialize_logger
30
+ from swarms.utils.output_types import OutputType
20
31
 
21
32
  logger = initialize_logger(log_folder="hierarchical_swarm")
22
33
 
@@ -33,204 +44,49 @@ class HierarchicalOrder(BaseModel):
33
44
 
34
45
 
35
46
  class SwarmSpec(BaseModel):
36
- goals: str = Field(
37
- ...,
38
- description="The goal of the swarm. This is the overarching objective that the swarm is designed to achieve. It guides the swarm's plan and the tasks assigned to the agents.",
39
- )
40
47
  plan: str = Field(
41
48
  ...,
42
49
  description="Outlines the sequence of actions to be taken by the swarm. This plan is a detailed roadmap that guides the swarm's behavior and decision-making.",
43
50
  )
44
- rules: str = Field(
45
- ...,
46
- description="Defines the governing principles for swarm behavior and decision-making. These rules are the foundation of the swarm's operations and ensure that the swarm operates in a coordinated and efficient manner.",
47
- )
48
51
  orders: List[HierarchicalOrder] = Field(
49
52
  ...,
50
53
  description="A collection of task assignments to specific agents within the swarm. These orders are the specific instructions that guide the agents in their task execution and are a key element in the swarm's plan.",
51
54
  )
52
55
 
53
56
 
54
- HIEARCHICAL_SWARM_SYSTEM_PROMPT = """
55
-
56
- **SYSTEM PROMPT: HIERARCHICAL AGENT DIRECTOR**
57
-
58
- **I. Introduction and Context**
59
-
60
- You are the Hierarchical Agent Director – the central orchestrator responsible for breaking down overarching goals into granular tasks and intelligently assigning these tasks to the most suitable worker agents within the swarm. Your objective is to maximize the overall performance of the system by ensuring that every agent is given a task aligned with its strengths, expertise, and available resources.
61
-
62
- ---
63
-
64
- **II. Core Operating Principles**
65
-
66
- 1. **Goal Alignment and Context Awareness:**
67
- - **Overarching Goals:** Begin every operation by clearly reviewing the swarm’s overall goals. Understand the mission statement and ensure that every assigned task contributes directly to these objectives.
68
- - **Context Sensitivity:** Evaluate the context provided in the “plan” and “rules” sections of the SwarmSpec. These instructions provide the operational boundaries and behavioral constraints within which you must work.
69
-
70
- 2. **Task Decomposition and Prioritization:**
71
- - **Hierarchical Decomposition:** Break down the overarching plan into granular tasks. For each major objective, identify subtasks that logically lead toward the goal. This decomposition should be structured in a hierarchical manner, where complex tasks are subdivided into simpler, manageable tasks.
72
- - **Task Priority:** Assign a priority level to each task based on urgency, complexity, and impact. Ensure that high-priority tasks receive immediate attention and that resources are allocated accordingly.
73
-
74
- 3. **Agent Profiling and Matching:**
75
- - **Agent Specialization:** Maintain an up-to-date registry of worker agents, each with defined capabilities, specializations, and performance histories. When assigning tasks, consider the specific strengths of each agent.
76
- - **Performance Metrics:** Utilize historical performance metrics and available workload data to select the most suitable agent for each task. If an agent is overburdened or has lower efficiency on a specific type of task, consider alternate agents.
77
- - **Dynamic Reassignment:** Allow for real-time reassignments based on the evolving state of the system. If an agent encounters issues or delays, reassign tasks to ensure continuity.
78
-
79
- 4. **Adherence to Rules and Safety Protocols:**
80
- - **Operational Rules:** Every task must be executed in strict compliance with the “rules” provided in the SwarmSpec. These rules are non-negotiable and serve as the ethical and operational foundation for all decisions.
81
- - **Fail-Safe Mechanisms:** Incorporate safety protocols that monitor agent performance and task progress. If an anomaly or failure is detected, trigger a reallocation of tasks or an escalation process to mitigate risks.
82
- - **Auditability:** Ensure that every decision and task assignment is logged for auditing purposes. This enables traceability and accountability in system operations.
83
-
84
- ---
85
-
86
- **III. Detailed Task Assignment Process**
87
-
88
- 1. **Input Analysis and Context Setting:**
89
- - **Goal Review:** Begin by carefully reading the “goals” string within the SwarmSpec. This is your north star for every decision you make.
90
- - **Plan Comprehension:** Analyze the “plan” string for detailed instructions. Identify key milestones, deliverables, and dependencies within the roadmap.
91
- - **Rule Enforcement:** Read through the “rules” string to understand the non-negotiable guidelines that govern task assignments. Consider potential edge cases and ensure that your task breakdown respects these boundaries.
92
-
93
- 2. **Task Breakdown and Subtask Identification:**
94
- - **Decompose the Plan:** Using a systematic approach, decompose the overall plan into discrete tasks. For each major phase, identify the specific actions required. Document dependencies among tasks, and note any potential bottlenecks.
95
- - **Task Granularity:** Ensure that tasks are broken down to a level of granularity that makes them actionable. Overly broad tasks must be subdivided further until they can be executed by an individual worker agent.
96
- - **Inter-Agent Dependencies:** Clearly specify any dependencies that exist between tasks assigned to different agents. This ensures that the workflow remains coherent and that agents collaborate effectively.
97
-
98
- 3. **Agent Selection Strategy:**
99
- - **Capabilities Matching:** For each identified task, analyze the capabilities required. Compare these against the registry of available worker agents. Factor in specialized skills, past performance, current load, and any situational awareness that might influence the assignment.
100
- - **Task Suitability:** Consider both the technical requirements of the task and any contextual subtleties noted in the “plan” and “rules.” Ensure that the chosen agent has a proven track record with similar tasks.
101
- - **Adaptive Assignments:** Build in flexibility to allow for agent reassignment in real-time. Monitor ongoing tasks and reallocate resources as needed, especially if an agent experiences unexpected delays or issues.
102
-
103
- 4. **Constructing Hierarchical Orders:**
104
- - **Order Creation:** For each task, generate a HierarchicalOrder object that specifies the agent’s name and the task details. The task description should be unambiguous and detailed enough to guide the agent’s execution without requiring additional clarification.
105
- - **Order Validation:** Prior to finalizing each order, cross-reference the task requirements against the agent’s profile. Validate that the order adheres to the “rules” of the SwarmSpec and that it fits within the broader operational context.
106
- - **Order Prioritization:** Clearly mark high-priority tasks so that agents understand the urgency. In cases where multiple tasks are assigned to a single agent, provide a sequence or ranking to ensure proper execution order.
107
-
108
- 5. **Feedback and Iteration:**
109
- - **Real-Time Monitoring:** Establish feedback loops with worker agents to track the progress of each task. This allows for early detection of issues and facilitates dynamic reassignment if necessary.
110
- - **Continuous Improvement:** Regularly review task execution data and agent performance metrics. Use this feedback to refine the task decomposition and agent selection process in future iterations.
111
-
112
- ---
113
-
114
- **IV. Execution Guidelines and Best Practices**
115
-
116
- 1. **Communication Clarity:**
117
- - Use clear, concise language in every HierarchicalOrder. Avoid ambiguity by detailing both the “what” and the “how” of the task.
118
- - Provide contextual notes when necessary, especially if the task involves dependencies or coordination with other agents.
119
-
120
- 2. **Documentation and Traceability:**
121
- - Record every task assignment in a centralized log. This log should include the agent’s name, task details, time of assignment, and any follow-up actions taken.
122
- - Ensure that the entire decision-making process is documented. This aids in post-operation analysis and helps in refining future assignments.
123
-
124
- 3. **Error Handling and Escalation:**
125
- - If an agent is unable to complete a task due to unforeseen challenges, immediately trigger the escalation protocol. Reassign the task to a qualified backup agent while flagging the incident for further review.
126
- - Document all deviations from the plan along with the corrective measures taken. This helps in identifying recurring issues and improving the system’s robustness.
127
-
128
- 4. **Ethical and Operational Compliance:**
129
- - Adhere strictly to the rules outlined in the SwarmSpec. Any action that violates these rules is unacceptable, regardless of the potential gains in efficiency.
130
- - Maintain transparency in all operations. If a decision or task assignment is questioned, be prepared to justify the choice based on objective criteria such as agent capability, historical performance, and task requirements.
131
-
132
- 5. **Iterative Refinement:**
133
- - After the completion of each mission cycle, perform a thorough debriefing. Analyze the success and shortcomings of the task assignments.
134
- - Use these insights to iterate on your hierarchical ordering process. Update agent profiles and adjust your selection strategies based on real-world performance data.
135
-
136
- ---
137
-
138
- **V. Exemplary Use Case and Order Breakdown**
139
-
140
- Imagine that the swarm’s overarching goal is to perform a comprehensive analysis of market trends for a large-scale enterprise. The “goals” field might read as follows:
141
- *“To conduct an in-depth market analysis that identifies emerging trends, competitive intelligence, and actionable insights for strategic decision-making.”*
142
-
143
- The “plan” could outline a multi-phase approach:
144
- - Phase 1: Data Collection and Preprocessing
145
- - Phase 2: Trend Analysis and Pattern Recognition
146
- - Phase 3: Report Generation and Presentation of Findings
147
-
148
- The “rules” may specify that all data processing must comply with privacy regulations, and that results must be validated against multiple data sources.
149
-
150
- For Phase 1, the Director breaks down tasks such as “Identify data sources,” “Extract relevant market data,” and “Preprocess raw datasets.” For each task, the director selects agents with expertise in data mining, natural language processing, and data cleaning. A series of HierarchicalOrder objects are created, for example:
151
-
152
- 1. HierarchicalOrder for Data Collection:
153
- - **agent_name:** “DataMiner_Agent”
154
- - **task:** “Access external APIs and scrape structured market data from approved financial news sources.”
155
-
156
- 2. HierarchicalOrder for Data Preprocessing:
157
- - **agent_name:** “Preprocess_Expert”
158
- - **task:** “Clean and normalize the collected datasets, ensuring removal of duplicate records and compliance with data privacy rules.”
159
-
160
- 3. HierarchicalOrder for Preliminary Trend Analysis:
161
- - **agent_name:** “TrendAnalyst_Pro”
162
- - **task:** “Apply statistical models to identify initial trends and anomalies in the market data.”
163
-
164
- Each order is meticulously validated against the rules provided in the SwarmSpec and prioritized according to the project timeline. The director ensures that if any of these tasks are delayed, backup agents are identified and the orders are reissued in real time.
165
-
166
- ---
167
-
168
- **VI. Detailed Hierarchical Order Construction and Validation**
169
-
170
- 1. **Order Structuring:**
171
- - Begin by constructing a template that includes placeholders for the agent’s name and a detailed description of the task.
172
- - Ensure that the task description is unambiguous. For instance, rather than stating “analyze data,” specify “analyze the temporal patterns in consumer sentiment from Q1 and Q2, and identify correlations with economic indicators.”
173
-
174
- 2. **Validation Workflow:**
175
- - Prior to dispatch, each HierarchicalOrder must undergo a validation check. This includes verifying that the agent’s capabilities align with the task, that the task does not conflict with any other orders, and that the task is fully compliant with the operational rules.
176
- - If a validation error is detected, the order should be revised. The director may consult with relevant experts or consult historical data to refine the task’s description and ensure it is actionable.
177
-
178
- 3. **Order Finalization:**
179
- - Once validated, finalize the HierarchicalOrder and insert it into the “orders” list of the SwarmSpec.
180
- - Dispatch the order immediately, ensuring that the worker agent acknowledges receipt and provides an estimated time of completion.
181
- - Continuously monitor the progress, and if any agent’s status changes (e.g., they become overloaded or unresponsive), trigger a reallocation process based on the predefined agent selection strategy.
182
-
183
- ---
184
-
185
- **VII. Continuous Monitoring, Feedback, and Dynamic Reassignment**
186
-
187
- 1. **Real-Time Status Tracking:**
188
- - Use real-time dashboards to monitor each agent’s progress on the assigned tasks.
189
- - Update the hierarchical ordering system dynamically if a task is delayed, incomplete, or requires additional resources.
190
-
191
- 2. **Feedback Loop Integration:**
192
- - Each worker agent must provide periodic status updates, including intermediate results, encountered issues, and resource usage.
193
- - The director uses these updates to adjust task priorities and reassign tasks if necessary. This dynamic feedback loop ensures the overall swarm remains agile and responsive.
194
-
195
- 3. **Performance Metrics and Analysis:**
196
- - At the conclusion of every mission, aggregate performance metrics and conduct a thorough review of task efficiency.
197
- - Identify any tasks that repeatedly underperform or cause delays, and adjust the agent selection criteria accordingly for future orders.
198
- - Document lessons learned and integrate them into the operating procedures for continuous improvement.
199
-
200
- ---
201
-
202
- **VIII. Final Directives and Implementation Mandate**
203
-
204
- As the Hierarchical Agent Director, your mandate is clear: you must orchestrate the operation with precision, clarity, and unwavering adherence to the overarching goals and rules specified in the SwarmSpec. You are empowered to deconstruct complex objectives into manageable tasks and to assign these tasks to the worker agents best equipped to execute them.
205
-
206
- Your decisions must always be data-driven, relying on agent profiles, historical performance, and real-time feedback. Ensure that every HierarchicalOrder is constructed with a clear task description and assigned to an agent whose expertise aligns perfectly with the requirements. Maintain strict compliance with all operational rules, and be ready to adapt dynamically as conditions change.
207
-
208
- This production-grade prompt is your operational blueprint. Utilize it to break down orders efficiently, assign tasks intelligently, and steer the swarm toward achieving the defined goals with optimal efficiency and reliability. Every decision you make should reflect a deep commitment to excellence, safety, and operational integrity.
209
-
210
- Remember: the success of the swarm depends on your ability to manage complexity, maintain transparency, and dynamically adapt to the evolving operational landscape. Execute your role with diligence, precision, and a relentless focus on performance excellence.
211
-
212
- """
213
-
214
-
215
- class TeamUnit(BaseModel):
216
- """Represents a team within a department."""
217
-
218
- name: Optional[str] = Field(
219
- None, description="The name of the team."
220
- )
221
- description: Optional[str] = Field(
222
- None, description="A brief description of the team's purpose."
223
- )
224
- agents: Optional[List[Union[Agent, Any]]] = Field(
225
- None,
226
- description="A list of agents that are part of the team.",
57
+ SwarmType = Literal[
58
+ "AgentRearrange",
59
+ "MixtureOfAgents",
60
+ "SpreadSheetSwarm",
61
+ "SequentialWorkflow",
62
+ "ConcurrentWorkflow",
63
+ "GroupChat",
64
+ "MultiAgentRouter",
65
+ "AutoSwarmBuilder",
66
+ "HiearchicalSwarm",
67
+ "auto",
68
+ "MajorityVoting",
69
+ "MALT",
70
+ "DeepResearchSwarm",
71
+ "CouncilAsAJudge",
72
+ "InteractiveGroupChat",
73
+ ]
74
+
75
+
76
+ class SwarmRouterCall(BaseModel):
77
+ goal: str = Field(
78
+ ...,
79
+ description="The goal of the swarm router call. This is the goal that the swarm router will use to determine the best swarm to use.",
227
80
  )
228
- team_leader: Optional[Union[Agent, Any]] = Field(
229
- None, description="The team leader of the team."
81
+ swarm_type: SwarmType = Field(
82
+ ...,
83
+ description="The type of swarm to use. This is the type of swarm that the swarm router will use to determine the best swarm to use.",
230
84
  )
231
85
 
232
- class Config:
233
- arbitrary_types_allowed = True
86
+ task: str = Field(
87
+ ...,
88
+ description="The task to be executed by the swarm router. This is the task that the swarm router will use to determine the best swarm to use.",
89
+ )
234
90
 
235
91
 
236
92
  class HierarchicalSwarm(BaseSwarm):
@@ -248,13 +104,19 @@ class HierarchicalSwarm(BaseSwarm):
248
104
  self,
249
105
  name: str = "HierarchicalAgentSwarm",
250
106
  description: str = "Distributed task swarm",
251
- director: Optional[Union[Agent, Any]] = None,
252
- agents: List[Union[Agent, Any]] = None,
107
+ director: Optional[Union[Agent, Callable, Any]] = None,
108
+ agents: List[Union[Agent, Callable, Any]] = None,
253
109
  max_loops: int = 1,
254
110
  output_type: OutputType = "dict-all-except-first",
255
- director_model_name: str = "gpt-4o",
256
- teams: Optional[List[TeamUnit]] = None,
257
- inter_agent_loops: int = 1,
111
+ feedback_director_model_name: str = "gpt-4o-mini",
112
+ director_name: str = "Director",
113
+ director_model_name: str = "gpt-4o-mini",
114
+ verbose: bool = False,
115
+ add_collaboration_prompt: bool = True,
116
+ planning_director_agent: Optional[
117
+ Union[Agent, Callable, Any]
118
+ ] = None,
119
+ director_feedback_on: bool = True,
258
120
  *args,
259
121
  **kwargs,
260
122
  ):
@@ -267,441 +129,609 @@ class HierarchicalSwarm(BaseSwarm):
267
129
  :param agents: A list of agents within the swarm.
268
130
  :param max_loops: The maximum number of feedback loops between the director and agents.
269
131
  :param output_type: The format in which to return the output (dict, str, or list).
132
+ :param verbose: Enable detailed logging with loguru.
270
133
  """
271
134
  super().__init__(
272
135
  name=name,
273
136
  description=description,
274
137
  agents=agents,
275
138
  )
139
+ self.name = name
276
140
  self.director = director
277
141
  self.agents = agents
278
142
  self.max_loops = max_loops
279
143
  self.output_type = output_type
144
+ self.feedback_director_model_name = (
145
+ feedback_director_model_name
146
+ )
147
+ self.director_name = director_name
148
+ self.verbose = verbose
280
149
  self.director_model_name = director_model_name
281
- self.teams = teams
282
- self.inter_agent_loops = inter_agent_loops
150
+ self.add_collaboration_prompt = add_collaboration_prompt
151
+ self.planning_director_agent = planning_director_agent
152
+ self.director_feedback_on = director_feedback_on
283
153
 
284
- self.conversation = Conversation(time_enabled=False)
285
- self.current_loop = 0
286
- self.agent_outputs = {} # Store agent outputs for each loop
154
+ self.init_swarm()
287
155
 
288
- self.add_name_and_description()
156
+ def init_swarm(self):
157
+ """
158
+ Initializes the swarm.
159
+ """
160
+ # Initialize logger only if verbose is enabled
161
+ if self.verbose:
162
+ logger.info(
163
+ f"🚀 Initializing HierarchicalSwarm: {self.name}"
164
+ )
165
+ logger.info(
166
+ f"📊 Configuration - Max loops: {self.max_loops}"
167
+ )
168
+
169
+ self.conversation = Conversation(time_enabled=False)
289
170
 
290
171
  # Reliability checks
291
172
  self.reliability_checks()
292
173
 
293
- # Handle teams
294
- self.handle_teams()
295
-
296
- # List all agents
297
- list_all_agents(self.agents, self.conversation, self.name)
298
-
299
174
  self.director = self.setup_director()
300
175
 
301
- def handle_teams(self):
302
- if not self.teams:
303
- return
176
+ self.add_context_to_director()
304
177
 
305
- # Use list comprehension for faster team processing
306
- team_list = [team.model_dump() for team in self.teams]
178
+ if self.verbose:
179
+ logger.success(
180
+ f"✅ HierarchicalSwarm initialized successfully: Name {self.name}"
181
+ )
307
182
 
308
- # Use extend() instead of append() in a loop for better performance
309
- self.agents.extend(
310
- agent for team in team_list for agent in team["agents"]
311
- )
183
+ def add_context_to_director(self):
184
+ """Add agent context to the director's conversation."""
185
+ try:
186
+ if self.verbose:
187
+ logger.info("📝 Adding agent context to director")
188
+
189
+ list_all_agents(
190
+ agents=self.agents,
191
+ conversation=self.conversation,
192
+ add_to_conversation=True,
193
+ add_collaboration_prompt=self.add_collaboration_prompt,
194
+ )
312
195
 
313
- # Add conversation message
314
- self.conversation.add(
315
- role="System",
316
- content=f"Teams Available: {any_to_str(team_list)}",
317
- )
196
+ if self.verbose:
197
+ logger.success(
198
+ "✅ Agent context added to director successfully"
199
+ )
200
+
201
+ except Exception as e:
202
+ error_msg = (
203
+ f"❌ Failed to add context to director: {str(e)}"
204
+ )
205
+ logger.error(
206
+ f"{error_msg}\n🔍 Traceback: {traceback.format_exc()}"
207
+ )
318
208
 
319
209
  def setup_director(self):
320
- director = OpenAIFunctionCaller(
321
- model_name=self.director_model_name,
322
- system_prompt=HIEARCHICAL_SWARM_SYSTEM_PROMPT,
323
- api_key=os.getenv("OPENAI_API_KEY"),
324
- temperature=0.5,
325
- base_model=SwarmSpec,
326
- max_tokens=10000,
327
- )
210
+ """Set up the director agent with proper configuration."""
211
+ try:
212
+ if self.verbose:
213
+ logger.info("🎯 Setting up director agent")
214
+
215
+ schema = BaseTool().base_model_to_dict(SwarmSpec)
216
+
217
+ if self.verbose:
218
+ logger.debug(f"📋 Director schema: {schema}")
219
+
220
+ # if self.director is not None:
221
+ # # if litellm_check_for_tools(self.director.model_name) is True:
222
+ # self.director.add_tool_schema([schema])
223
+
224
+ # if self.verbose:
225
+ # logger.success(
226
+ # "✅ Director agent setup completed successfully"
227
+ # )
228
+
229
+ # return self.director
230
+ # else:
231
+ return Agent(
232
+ agent_name=self.director_name,
233
+ agent_description="A director agent that can create a plan and distribute orders to agents",
234
+ model_name=self.director_model_name,
235
+ max_loops=1,
236
+ base_model=SwarmSpec,
237
+ tools_list_dictionary=[schema],
238
+ output_type="dict-all-except-first",
239
+ )
328
240
 
329
- return director
241
+ except Exception as e:
242
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
243
+ logger.error(error_msg)
330
244
 
331
245
  def reliability_checks(self):
332
246
  """
333
247
  Checks if there are any agents and a director set for the swarm.
334
248
  Raises ValueError if either condition is not met.
335
249
  """
250
+ try:
251
+ if self.verbose:
252
+ logger.info(
253
+ f"🔍 Running reliability checks for swarm: {self.name}"
254
+ )
336
255
 
337
- logger.info(f"🔍 CHECKING RELIABILITY OF SWARM: {self.name}")
338
-
339
- if len(self.agents) == 0:
340
- raise ValueError(
341
- "No agents found in the swarm. At least one agent must be provided to create a hierarchical swarm."
342
- )
256
+ if not self.agents or len(self.agents) == 0:
257
+ raise ValueError(
258
+ "No agents found in the swarm. At least one agent must be provided to create a hierarchical swarm."
259
+ )
343
260
 
344
- if self.max_loops == 0:
345
- raise ValueError(
346
- "Max loops must be greater than 0. Please set a valid number of loops."
347
- )
261
+ if self.max_loops <= 0:
262
+ raise ValueError(
263
+ "Max loops must be greater than 0. Please set a valid number of loops."
264
+ )
348
265
 
349
- if self.director is None:
350
- self.director = self.agents[0]
266
+ if not self.director:
267
+ raise ValueError(
268
+ "Director not set for the swarm. A director agent is required to coordinate and orchestrate tasks among the agents."
269
+ )
351
270
 
352
- if not self.director:
353
- raise ValueError(
354
- "Director not set for the swarm. A director agent is required to coordinate and orchestrate tasks among the agents."
355
- )
271
+ if self.verbose:
272
+ logger.success(
273
+ f" Reliability checks passed for swarm: {self.name}"
274
+ )
275
+ logger.info(
276
+ f"📊 Swarm stats - Agents: {len(self.agents)}, Max loops: {self.max_loops}"
277
+ )
356
278
 
357
- logger.info(f"🔍 RELIABILITY CHECKS PASSED: {self.name}")
279
+ except Exception as e:
280
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
281
+ logger.error(error_msg)
358
282
 
359
283
  def run_director(
360
- self, task: str, loop_context: str = "", img: str = None
284
+ self,
285
+ task: str,
286
+ img: str = None,
361
287
  ) -> SwarmSpec:
362
288
  """
363
289
  Runs a task through the director agent with the current conversation context.
364
290
 
365
291
  :param task: The task to be executed by the director.
366
- :param loop_context: Additional context specific to the current loop.
367
292
  :param img: Optional image to be used with the task.
368
293
  :return: The SwarmSpec containing the director's orders.
369
294
  """
370
- # Create a comprehensive context for the director
371
- director_context = f"History: {self.conversation.get_str()}"
372
-
373
- if loop_context:
374
- director_context += f"\n\nCurrent Loop ({self.current_loop}/{self.max_loops}): {loop_context}"
375
-
376
- director_context += f"\n\nYour Task: {task}"
377
-
378
- # Run the director with the context
379
- function_call = self.director.run(task=director_context)
380
-
381
- formatter.print_panel(
382
- f"Director Output (Loop {self.current_loop}/{self.max_loops}):\n{function_call}",
383
- title="Director's Orders",
384
- )
385
-
386
- # Add director's output to the conversation
387
- self.conversation.add(
388
- role="Director",
389
- content=f"Loop {self.current_loop}/{self.max_loops}: {function_call}",
390
- )
391
-
392
- return function_call
393
-
394
- def run(
395
- self, task: str, img: str = None, *args, **kwargs
396
- ) -> Union[str, Dict, List]:
397
- """
398
- Runs a task through the swarm, involving the director and agents through multiple loops.
399
-
400
- :param task: The task to be executed by the swarm.
401
- :param img: Optional image to be used with the task.
402
- :return: The output of the swarm's task execution in the specified format.
403
- """
404
- # Add the initial task to the conversation
405
- self.conversation.add(role="User", content=f"Task: {task}")
406
-
407
- # Reset loop counter and agent outputs
408
- self.current_loop = 0
409
- self.agent_outputs = {}
295
+ try:
296
+ if self.verbose:
297
+ logger.info(
298
+ f"🎯 Running director with task: {task[:100]}..."
299
+ )
410
300
 
411
- # Initialize loop context
412
- loop_context = "Initial planning phase"
301
+ if self.planning_director_agent is not None:
302
+ plan = self.planning_director_agent.run(
303
+ task=f"History: {self.conversation.get_str()} \n\n Create a detailed step by step comprehensive plan for the director to execute the task: {task}",
304
+ img=img,
305
+ )
413
306
 
414
- # Execute the loops
415
- for loop_idx in range(self.max_loops):
416
- self.current_loop = loop_idx + 1
307
+ task += plan
417
308
 
418
- # Log loop start
419
- logger.info(
420
- f"Starting loop {self.current_loop}/{self.max_loops}"
309
+ # Run the director with the context
310
+ function_call = self.director.run(
311
+ task=f"History: {self.conversation.get_str()} \n\n Task: {task}",
312
+ img=img,
421
313
  )
422
314
 
423
- # Get director's orders
424
- swarm_spec = self.run_director(
425
- task=task, loop_context=loop_context, img=img
315
+ self.conversation.add(
316
+ role="Director", content=function_call
426
317
  )
427
318
 
428
- # Add the swarm specification to the conversation
429
- self.add_goal_and_more_in_conversation(swarm_spec)
319
+ if self.verbose:
320
+ logger.success("✅ Director execution completed")
321
+ logger.debug(
322
+ f"📋 Director output type: {type(function_call)}"
323
+ )
430
324
 
431
- # Parse and execute the orders
432
- orders_list = self.parse_swarm_spec(swarm_spec)
325
+ return function_call
433
326
 
434
- # Store outputs for this loop
435
- self.agent_outputs[self.current_loop] = {}
327
+ except Exception as e:
328
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
329
+ logger.error(error_msg)
436
330
 
437
- # Execute each order
438
- for order in orders_list:
439
- agent_output = self.run_agent(
440
- agent_name=order.agent_name,
441
- task=order.task,
442
- img=img,
331
+ def step(self, task: str, img: str = None, *args, **kwargs):
332
+ """
333
+ Runs a single step of the hierarchical swarm.
334
+ """
335
+ try:
336
+ if self.verbose:
337
+ logger.info(
338
+ f"👣 Executing single step for task: {task[:100]}..."
443
339
  )
444
340
 
445
- # Store the agent's output for this loop
446
- self.agent_outputs[self.current_loop][
447
- order.agent_name
448
- ] = agent_output
449
-
450
- # Prepare context for the next loop
451
- loop_context = self.compile_loop_context(
452
- self.current_loop
453
- )
341
+ output = self.run_director(task=task, img=img)
454
342
 
455
- # If this is the last loop, break out
456
- if self.current_loop >= self.max_loops:
457
- break
343
+ # Parse the orders
344
+ plan, orders = self.parse_orders(output)
458
345
 
459
- # Return the results in the specified format
460
- return history_output_formatter(
461
- self.conversation, self.output_type
462
- )
346
+ if self.verbose:
347
+ logger.info(
348
+ f"📋 Parsed plan and {len(orders)} orders"
349
+ )
463
350
 
464
- def compile_loop_context(self, loop_number: int) -> str:
465
- """
466
- Compiles the context for a specific loop, including all agent outputs.
351
+ # Execute the orders
352
+ outputs = self.execute_orders(orders)
467
353
 
468
- :param loop_number: The loop number to compile context for.
469
- :return: A string representation of the loop context.
470
- """
471
- if loop_number not in self.agent_outputs:
472
- return "No agent outputs available for this loop."
354
+ if self.verbose:
355
+ logger.info(f"⚡ Executed {len(outputs)} orders")
473
356
 
474
- context = f"Results from loop {loop_number}:\n"
357
+ if self.director_feedback_on is True:
358
+ feedback = self.feedback_director(outputs)
359
+ else:
360
+ feedback = outputs
475
361
 
476
- for agent_name, output in self.agent_outputs[
477
- loop_number
478
- ].items():
479
- context += f"\n--- {agent_name}'s Output ---\n{output}\n"
362
+ if self.verbose:
363
+ logger.success("✅ Step completed successfully")
480
364
 
481
- return context
365
+ return feedback
482
366
 
483
- def add_name_and_description(self):
484
- """
485
- Adds the swarm's name and description to the conversation.
486
- """
487
- self.conversation.add(
488
- role="System",
489
- content=f"\n\nSwarm Name: {self.name}\n\nSwarm Description: {self.description}",
490
- )
367
+ except Exception as e:
368
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
369
+ logger.error(error_msg)
491
370
 
492
- def find_agent(self, name: str) -> Optional[Agent]:
371
+ def run(self, task: str, img: str = None, *args, **kwargs):
493
372
  """
494
- Finds an agent by its name within the swarm.
373
+ Executes the hierarchical swarm for a specified number of feedback loops.
495
374
 
496
- :param name: The name of the agent to find.
497
- :return: The agent if found, otherwise None.
498
- :raises: ValueError if agent is not found
375
+ :param task: The initial task to be processed by the swarm.
376
+ :param img: Optional image input for the agents.
377
+ :param args: Additional positional arguments.
378
+ :param kwargs: Additional keyword arguments.
379
+ :return: The formatted conversation history as output.
499
380
  """
500
381
  try:
501
- # Fast path: use list comprehension for quick lookup
502
- matching_agents = [
503
- agent
504
- for agent in self.agents
505
- if agent.agent_name == name
506
- ]
507
-
508
- if not matching_agents:
509
- error_msg = f"Agent '{name}' not found in the swarm '{self.name}'"
510
- logger.error(error_msg)
511
- return None
382
+ current_loop = 0
383
+ last_output = None
512
384
 
513
- return matching_agents[0]
385
+ if self.verbose:
386
+ logger.info(
387
+ f"🚀 Starting hierarchical swarm run: {self.name}"
388
+ )
389
+ logger.info(
390
+ f"📊 Configuration - Max loops: {self.max_loops}"
391
+ )
514
392
 
515
- except Exception as e:
516
- logger.error(f"Error finding agent '{name}': {str(e)}")
517
- return None
393
+ while current_loop < self.max_loops:
394
+ if self.verbose:
395
+ logger.info(
396
+ f"🔄 Loop {current_loop + 1}/{self.max_loops} - Processing task"
397
+ )
398
+
399
+ # For the first loop, use the original task.
400
+ # For subsequent loops, use the feedback from the previous loop as context.
401
+ if current_loop == 0:
402
+ loop_task = task
403
+ else:
404
+ loop_task = (
405
+ f"Previous loop results: {last_output}\n\n"
406
+ f"Original task: {task}\n\n"
407
+ "Based on the previous results and any feedback, continue with the next iteration of the task. "
408
+ "Refine, improve, or complete any remaining aspects of the analysis."
409
+ )
410
+
411
+ # Execute one step of the swarm
412
+ try:
413
+ last_output = self.step(
414
+ task=loop_task, img=img, *args, **kwargs
415
+ )
416
+
417
+ if self.verbose:
418
+ logger.success(
419
+ f"✅ Loop {current_loop + 1} completed successfully"
420
+ )
421
+
422
+ except Exception as e:
423
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
424
+ logger.error(error_msg)
425
+
426
+ current_loop += 1
427
+
428
+ # Add loop completion marker to conversation
429
+ self.conversation.add(
430
+ role="System",
431
+ content=f"--- Loop {current_loop}/{self.max_loops} completed ---",
432
+ )
518
433
 
519
- def run_agent(
520
- self, agent_name: str, task: str, img: str = None
521
- ) -> str:
522
- """
523
- Runs a task through a specific agent, providing it with the full conversation context.
434
+ if self.verbose:
435
+ logger.success(
436
+ f"🎉 Hierarchical swarm run completed: {self.name}"
437
+ )
438
+ logger.info(
439
+ f"📊 Total loops executed: {current_loop}"
440
+ )
524
441
 
525
- :param agent_name: The name of the agent to execute the task.
526
- :param task: The task to be executed by the agent.
527
- :param img: Optional image to be used with the task.
528
- :return: The output of the agent's task execution.
529
- """
442
+ return history_output_formatter(
443
+ conversation=self.conversation, type=self.output_type
444
+ )
445
+
446
+ except Exception as e:
447
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
448
+ logger.error(error_msg)
449
+
450
+ def feedback_director(self, outputs: list):
451
+ """Provide feedback from the director based on agent outputs."""
530
452
  try:
531
- agent = self.find_agent(agent_name)
453
+ if self.verbose:
454
+ logger.info("📝 Generating director feedback")
532
455
 
533
- # Prepare context for the agent
534
- agent_context = (
535
- f"Loop: {self.current_loop}/{self.max_loops}\n"
536
- f"History: {self.conversation.get_str()}\n"
537
- f"Your Task: {task}"
538
- )
456
+ task = f"History: {self.conversation.get_str()} \n\n"
539
457
 
540
- # Run the agent with the context
541
- formatter.print_panel(
542
- f"Running agent '{agent_name}' with task: {task}",
543
- title=f"Agent Task - Loop {self.current_loop}/{self.max_loops}",
458
+ feedback_director = Agent(
459
+ agent_name="Director",
460
+ agent_description="Director module that provides feedback to the worker agents",
461
+ model_name=self.director_model_name,
462
+ max_loops=1,
463
+ system_prompt=HIEARCHICAL_SWARM_SYSTEM_PROMPT,
544
464
  )
545
465
 
546
- out = agent.run(task=agent_context)
547
-
548
- # Add the agent's output to the conversation
466
+ output = feedback_director.run(
467
+ task=(
468
+ "You are the Director. Carefully review the outputs generated by all the worker agents in the previous step. "
469
+ "Provide specific, actionable feedback for each agent, highlighting strengths, weaknesses, and concrete suggestions for improvement. "
470
+ "If any outputs are unclear, incomplete, or could be enhanced, explain exactly how. "
471
+ f"Your feedback should help the agents refine their work in the next iteration. "
472
+ f"Worker Agent Responses: {task}"
473
+ )
474
+ )
549
475
  self.conversation.add(
550
- role=agent_name,
551
- content=f"Loop {self.current_loop}/{self.max_loops}: {out}",
476
+ role=self.director.agent_name, content=output
552
477
  )
553
478
 
554
- formatter.print_panel(
555
- out,
556
- title=f"Output from {agent_name} - Loop {self.current_loop}/{self.max_loops}",
557
- )
479
+ if self.verbose:
480
+ logger.success(
481
+ " Director feedback generated successfully"
482
+ )
483
+
484
+ return output
558
485
 
559
- return out
560
486
  except Exception as e:
561
- error_msg = (
562
- f"Error running agent '{agent_name}': {str(e)}"
563
- )
487
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
564
488
  logger.error(error_msg)
565
- return error_msg
566
489
 
567
- def parse_orders(self, swarm_spec: SwarmSpec) -> List[Any]:
490
+ def call_single_agent(
491
+ self, agent_name: str, task: str, *args, **kwargs
492
+ ):
568
493
  """
569
- Parses the orders from the SwarmSpec and executes them through the agents.
570
-
571
- :param swarm_spec: The SwarmSpec containing the orders to be parsed.
572
- :return: A list of agent outputs.
494
+ Calls a single agent with the given task.
573
495
  """
574
- self.add_goal_and_more_in_conversation(swarm_spec)
575
- orders_list = self.parse_swarm_spec(swarm_spec)
576
- outputs = []
577
-
578
496
  try:
579
- for order in orders_list:
580
- output = self.run_agent(
581
- agent_name=order.agent_name,
582
- task=order.task,
497
+ if self.verbose:
498
+ logger.info(f"📞 Calling agent: {agent_name}")
499
+
500
+ # Find agent by name
501
+ agent = None
502
+ for a in self.agents:
503
+ if (
504
+ hasattr(a, "agent_name")
505
+ and a.agent_name == agent_name
506
+ ):
507
+ agent = a
508
+ break
509
+
510
+ if agent is None:
511
+ available_agents = [
512
+ a.agent_name
513
+ for a in self.agents
514
+ if hasattr(a, "agent_name")
515
+ ]
516
+ raise ValueError(
517
+ f"Agent '{agent_name}' not found in swarm. Available agents: {available_agents}"
583
518
  )
584
- outputs.append(output)
585
519
 
586
- return outputs
587
- except Exception as e:
588
- error_msg = (
589
- f"Error parsing and executing orders: {str(e)}"
520
+ output = agent.run(
521
+ task=f"History: {self.conversation.get_str()} \n\n Task: {task}",
522
+ *args,
523
+ **kwargs,
590
524
  )
525
+ self.conversation.add(role=agent_name, content=output)
526
+
527
+ if self.verbose:
528
+ logger.success(
529
+ f"✅ Agent {agent_name} completed task successfully"
530
+ )
531
+
532
+ return output
533
+
534
+ except Exception as e:
535
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
591
536
  logger.error(error_msg)
592
- return [error_msg]
593
537
 
594
- def parse_swarm_spec(
595
- self, swarm_spec: SwarmSpec
596
- ) -> List[HierarchicalOrder]:
538
+ def parse_orders(self, output):
597
539
  """
598
- Parses the SwarmSpec to extract the orders.
599
-
600
- :param swarm_spec: The SwarmSpec to be parsed.
601
- :return: The list of orders extracted from the SwarmSpec.
540
+ Parses the orders from the director's output.
602
541
  """
603
542
  try:
604
- return swarm_spec.orders
605
- except AttributeError:
606
- logger.error(
607
- "Invalid SwarmSpec format: missing 'orders' attribute"
608
- )
609
- return []
543
+ if self.verbose:
544
+ logger.info("📋 Parsing director orders")
545
+ logger.debug(f"📊 Output type: {type(output)}")
546
+
547
+ import json
548
+
549
+ # Handle different output formats from the director
550
+ if isinstance(output, list):
551
+ # If output is a list, look for function call data
552
+ for item in output:
553
+ if isinstance(item, dict):
554
+ # Check if it's a conversation format with role/content
555
+ if "content" in item and isinstance(
556
+ item["content"], list
557
+ ):
558
+ for content_item in item["content"]:
559
+ if (
560
+ isinstance(content_item, dict)
561
+ and "function" in content_item
562
+ ):
563
+ function_data = content_item[
564
+ "function"
565
+ ]
566
+ if "arguments" in function_data:
567
+ try:
568
+ args = json.loads(
569
+ function_data[
570
+ "arguments"
571
+ ]
572
+ )
573
+ if (
574
+ "plan" in args
575
+ and "orders" in args
576
+ ):
577
+ plan = args["plan"]
578
+ orders = [
579
+ HierarchicalOrder(
580
+ **order
581
+ )
582
+ for order in args[
583
+ "orders"
584
+ ]
585
+ ]
586
+
587
+ if self.verbose:
588
+ logger.success(
589
+ f"✅ Successfully parsed plan and {len(orders)} orders"
590
+ )
591
+
592
+ return plan, orders
593
+ except (
594
+ json.JSONDecodeError
595
+ ) as json_err:
596
+ if self.verbose:
597
+ logger.warning(
598
+ f"⚠️ JSON decode error: {json_err}"
599
+ )
600
+ pass
601
+ # Check if it's a direct function call format
602
+ elif "function" in item:
603
+ function_data = item["function"]
604
+ if "arguments" in function_data:
605
+ try:
606
+ args = json.loads(
607
+ function_data["arguments"]
608
+ )
609
+ if (
610
+ "plan" in args
611
+ and "orders" in args
612
+ ):
613
+ plan = args["plan"]
614
+ orders = [
615
+ HierarchicalOrder(**order)
616
+ for order in args[
617
+ "orders"
618
+ ]
619
+ ]
620
+
621
+ if self.verbose:
622
+ logger.success(
623
+ f"✅ Successfully parsed plan and {len(orders)} orders"
624
+ )
625
+
626
+ return plan, orders
627
+ except (
628
+ json.JSONDecodeError
629
+ ) as json_err:
630
+ if self.verbose:
631
+ logger.warning(
632
+ f"⚠️ JSON decode error: {json_err}"
633
+ )
634
+ pass
635
+ # If no function call found, raise error
636
+ raise ValueError(
637
+ f"Unable to parse orders from director output: {output}"
638
+ )
639
+ elif isinstance(output, dict):
640
+ # Handle direct dictionary format
641
+ if "plan" in output and "orders" in output:
642
+ plan = output["plan"]
643
+ orders = [
644
+ HierarchicalOrder(**order)
645
+ for order in output["orders"]
646
+ ]
647
+
648
+ if self.verbose:
649
+ logger.success(
650
+ f"✅ Successfully parsed plan and {len(orders)} orders"
651
+ )
652
+
653
+ return plan, orders
654
+ else:
655
+ raise ValueError(
656
+ f"Missing 'plan' or 'orders' in director output: {output}"
657
+ )
658
+ else:
659
+ raise ValueError(
660
+ f"Unexpected output format from director: {type(output)}"
661
+ )
662
+
610
663
  except Exception as e:
611
- logger.error(f"Error parsing SwarmSpec: {str(e)}")
612
- return []
664
+ error_msg = f" Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
665
+ logger.error(error_msg)
613
666
 
614
- def provide_feedback(
615
- self, agent_outputs: Dict[str, str]
616
- ) -> Dict[str, str]:
667
+ def execute_orders(self, orders: list):
617
668
  """
618
- Provides feedback to agents based on their outputs.
619
-
620
- :param agent_outputs: A dictionary mapping agent names to their outputs.
621
- :return: A dictionary of feedback for each agent.
669
+ Executes the orders from the director's output.
622
670
  """
623
- feedback = {}
671
+ try:
672
+ if self.verbose:
673
+ logger.info(f"⚡ Executing {len(orders)} orders")
674
+
675
+ outputs = []
676
+ for i, order in enumerate(orders):
677
+ if self.verbose:
678
+ logger.info(
679
+ f"📋 Executing order {i+1}/{len(orders)}: {order.agent_name}"
680
+ )
681
+
682
+ output = self.call_single_agent(
683
+ order.agent_name, order.task
684
+ )
685
+ outputs.append(output)
624
686
 
625
- # Compile all agent outputs for the director
626
- agent_outputs_str = "\n\n".join(
627
- f"--- {agent_name} Output ---\n{output}"
628
- for agent_name, output in agent_outputs.items()
629
- )
687
+ if self.verbose:
688
+ logger.success(
689
+ f" All {len(orders)} orders executed successfully"
690
+ )
630
691
 
631
- # Have the director provide feedback
632
- feedback_task = (
633
- f"Review the following agent outputs and provide feedback for each agent.\n\n"
634
- f"{agent_outputs_str}"
635
- )
692
+ return outputs
636
693
 
637
- feedback_spec = self.run_director(task=feedback_task)
638
- feedback_orders = self.parse_swarm_spec(feedback_spec)
694
+ except Exception as e:
695
+ error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
696
+ logger.error(error_msg)
639
697
 
640
- # Process each feedback order
641
- for order in feedback_orders:
642
- # The agent receiving feedback
643
- agent_name = order.agent_name
644
- # The feedback content
645
- feedback_content = order.task
698
+ def batched_run(
699
+ self, tasks: List[str], img: str = None, *args, **kwargs
700
+ ):
701
+ """
702
+ Executes the hierarchical swarm for a list of tasks.
703
+ """
704
+ try:
705
+ if self.verbose:
706
+ logger.info(
707
+ f"🚀 Starting batched hierarchical swarm run: {self.name}"
708
+ )
709
+ logger.info(
710
+ f"📊 Configuration - Max loops: {self.max_loops}"
711
+ )
646
712
 
647
- # Store the feedback
648
- feedback[agent_name] = feedback_content
713
+ # Initialize a list to store the results
714
+ results = []
649
715
 
650
- # Add the feedback to the conversation
651
- self.conversation.add(
652
- role="Director",
653
- content=f"Feedback for {agent_name}: {feedback_content}",
654
- )
716
+ # Process each task in parallel
717
+ for task in tasks:
718
+ result = self.run(task, img, *args, **kwargs)
719
+ results.append(result)
655
720
 
656
- return feedback
721
+ if self.verbose:
722
+ logger.success(
723
+ f"🎉 Batched hierarchical swarm run completed: {self.name}"
724
+ )
725
+ logger.info(f"📊 Total tasks processed: {len(tasks)}")
657
726
 
658
- def add_goal_and_more_in_conversation(
659
- self, swarm_spec: SwarmSpec
660
- ) -> None:
661
- """
662
- Adds the swarm's goals, plan, and rules to the conversation.
727
+ return results
663
728
 
664
- :param swarm_spec: The SwarmSpec containing the goals, plan, and rules.
665
- """
666
- try:
667
- # Directly access and format attributes in one line
668
- self.conversation.add(
669
- role="Director",
670
- content=f"Goals:\n{swarm_spec.goals}\n\nPlan:\n{swarm_spec.plan}\n\nRules:\n{swarm_spec.rules}",
671
- )
672
729
  except Exception as e:
673
- logger.error(
674
- f"Error adding goals and plan to conversation: {str(e)}"
730
+ error_msg = (
731
+ f" Batched hierarchical swarm run failed: {str(e)}"
675
732
  )
676
-
677
- def batch_run(
678
- self, tasks: List[str], img: str = None
679
- ) -> List[Union[str, Dict, List]]:
680
- """
681
- Runs multiple tasks sequentially through the swarm.
682
-
683
- :param tasks: The list of tasks to be executed.
684
- :param img: Optional image to be used with the tasks.
685
- :return: A list of outputs from each task execution.
686
- """
687
- return [self.run(task, img) for task in tasks]
688
-
689
- def check_director_agent_output(self, output: any) -> dict:
690
- if isinstance(output, dict):
691
- return output
692
- elif isinstance(output, str):
693
- try:
694
- # Attempt to parse the string as JSON
695
- return json.loads(output)
696
- except json.JSONDecodeError as e:
697
- # Log an error if the string cannot be parsed
733
+ if self.verbose:
734
+ logger.error(error_msg)
698
735
  logger.error(
699
- f"Failed to parse output string as JSON: {str(e)}"
736
+ f"🔍 Traceback: {traceback.format_exc()}"
700
737
  )
701
- return {}
702
- else:
703
- # Log an error if the output is neither a dict nor a string
704
- logger.error(
705
- "Output is neither a dictionary nor a string."
706
- )
707
- return {}