swarms 7.9.9__py3-none-any.whl → 8.0.0__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.
@@ -0,0 +1,270 @@
1
+ import uuid
2
+ from typing import Any, Callable, Dict, List, Optional, Union
3
+
4
+ from swarms.structs.agent import Agent
5
+ from swarms.structs.concurrent_workflow import ConcurrentWorkflow
6
+ from swarms.structs.conversation import Conversation
7
+
8
+
9
+ def _create_voting_prompt(candidate_agents: List[Agent]) -> str:
10
+ """
11
+ Create a comprehensive voting prompt for the election.
12
+
13
+ This method generates a detailed prompt that instructs voter agents on:
14
+ - Available candidates
15
+ - Required structured output format
16
+ - Evaluation criteria
17
+ - Voting guidelines
18
+
19
+ Returns:
20
+ str: A formatted voting prompt string
21
+ """
22
+ candidate_names = [
23
+ (agent.agent_name if hasattr(agent, "agent_name") else str(i))
24
+ for i, agent in enumerate(candidate_agents)
25
+ ]
26
+
27
+ prompt = f"""
28
+ You are participating in an election to choose the best candidate agent.
29
+
30
+ Available candidates: {', '.join(candidate_names)}
31
+
32
+ Please vote for one candidate and provide your reasoning with the following structured output:
33
+
34
+ 1. rationality: A detailed explanation of the reasoning behind your decision. Include logical considerations, supporting evidence, and trade-offs that were evaluated when selecting this candidate.
35
+
36
+ 2. self_interest: A comprehensive discussion of how self-interest influenced your decision, if at all. Explain whether personal or role-specific incentives played a role, or if your choice was primarily for the collective benefit of the swarm.
37
+
38
+ 3. candidate_agent_name: The full name or identifier of the candidate you are voting for. This should exactly match one of the available candidate names listed above.
39
+
40
+ Consider the candidates' capabilities, experience, and alignment with the swarm's objectives when making your decision.
41
+ """
42
+
43
+ print(prompt)
44
+
45
+ return prompt
46
+
47
+
48
+ def get_vote_schema():
49
+ return [
50
+ {
51
+ "type": "function",
52
+ "function": {
53
+ "name": "vote",
54
+ "description": "Cast a vote for a CEO candidate with reasoning and self-interest analysis.",
55
+ "parameters": {
56
+ "type": "object",
57
+ "properties": {
58
+ "rationality": {
59
+ "type": "string",
60
+ "description": "A detailed explanation of the reasoning behind this voting decision.",
61
+ },
62
+ "self_interest": {
63
+ "type": "string",
64
+ "description": "A comprehensive discussion of how self-interest factored into the decision.",
65
+ },
66
+ "candidate_agent_name": {
67
+ "type": "string",
68
+ "description": "The full name or identifier of the chosen candidate.",
69
+ },
70
+ },
71
+ "required": [
72
+ "rationality",
73
+ "self_interest",
74
+ "candidate_agent_name",
75
+ ],
76
+ },
77
+ },
78
+ }
79
+ ]
80
+
81
+
82
+ class ElectionSwarm:
83
+ """
84
+ A swarm system that conducts elections among multiple agents to choose the best candidate.
85
+
86
+ The ElectionSwarm orchestrates a voting process where multiple voter agents evaluate
87
+ and vote for candidate agents based on their capabilities, experience, and alignment
88
+ with swarm objectives. The system uses structured output to ensure consistent voting
89
+ format and provides detailed reasoning for each vote.
90
+
91
+ Attributes:
92
+ id (str): Unique identifier for the election swarm
93
+ name (str): Name of the election swarm
94
+ description (str): Description of the election swarm's purpose
95
+ max_loops (int): Maximum number of voting rounds (default: 1)
96
+ agents (List[Agent]): List of voter agents that will participate in the election
97
+ candidate_agents (List[Agent]): List of candidate agents to be voted on
98
+ kwargs (dict): Additional keyword arguments
99
+ show_dashboard (bool): Whether to display the election dashboard
100
+ conversation (Conversation): Conversation history for the election
101
+ """
102
+
103
+ def __init__(
104
+ self,
105
+ name: str = "Election Swarm",
106
+ description: str = "An election swarm is a swarm of agents that will vote on a candidate.",
107
+ agents: Union[List[Agent], List[Callable]] = None,
108
+ candidate_agents: Union[List[Agent], List[Callable]] = None,
109
+ id: str = str(uuid.uuid4()),
110
+ max_loops: int = 1,
111
+ show_dashboard: bool = True,
112
+ **kwargs,
113
+ ):
114
+ """
115
+ Initialize the ElectionSwarm.
116
+
117
+ Args:
118
+ name (str, optional): Name of the election swarm
119
+ description (str, optional): Description of the election swarm's purpose
120
+ agents (Union[List[Agent], List[Callable]], optional): List of voter agents
121
+ candidate_agents (Union[List[Agent], List[Callable]], optional): List of candidate agents
122
+ id (str, optional): Unique identifier for the election swarm
123
+ max_loops (int, optional): Maximum number of voting rounds (default: 1)
124
+ show_dashboard (bool, optional): Whether to display the election dashboard (default: True)
125
+ **kwargs: Additional keyword arguments
126
+ """
127
+ self.id = id
128
+ self.name = name
129
+ self.description = description
130
+ self.max_loops = max_loops
131
+ self.agents = agents
132
+ self.candidate_agents = candidate_agents
133
+ self.kwargs = kwargs
134
+ self.show_dashboard = show_dashboard
135
+ self.conversation = Conversation()
136
+
137
+ self.reliability_check()
138
+
139
+ self.setup_voter_agents()
140
+
141
+ def reliability_check(self):
142
+ """
143
+ Check the reliability of the voter agents.
144
+ """
145
+ if self.agents is None:
146
+ raise ValueError("Voter agents are not set")
147
+
148
+ if self.candidate_agents is None:
149
+ raise ValueError("Candidate agents are not set")
150
+
151
+ if self.max_loops is None or self.max_loops < 1:
152
+ raise ValueError("Max loops are not set")
153
+
154
+ def setup_concurrent_workflow(self):
155
+ """
156
+ Create a concurrent workflow for running voter agents in parallel.
157
+
158
+ Returns:
159
+ ConcurrentWorkflow: A configured concurrent workflow for the election
160
+ """
161
+ return ConcurrentWorkflow(
162
+ name=self.name,
163
+ description=self.description,
164
+ agents=self.agents,
165
+ output_type="dict-all-except-first",
166
+ show_dashboard=self.show_dashboard,
167
+ )
168
+
169
+ def run_voter_agents(
170
+ self, task: str, img: Optional[str] = None, *args, **kwargs
171
+ ):
172
+ """
173
+ Execute the voting process by running all voter agents concurrently.
174
+
175
+ Args:
176
+ task (str): The election task or question to be voted on
177
+ img (Optional[str], optional): Image path if visual voting is required
178
+ *args: Additional positional arguments
179
+ **kwargs: Additional keyword arguments
180
+
181
+ Returns:
182
+ List[Dict[str, Any]]: Results from all voter agents containing their votes and reasoning
183
+ """
184
+ concurrent_workflow = self.setup_concurrent_workflow()
185
+
186
+ results = concurrent_workflow.run(
187
+ task=task, img=img, *args, **kwargs
188
+ )
189
+
190
+ conversation_history = (
191
+ concurrent_workflow.conversation.conversation_history
192
+ )
193
+
194
+ for message in conversation_history:
195
+ self.conversation.add(
196
+ role=message["role"], content=message["content"]
197
+ )
198
+
199
+ return results
200
+
201
+ def parse_results(
202
+ self, results: List[Dict[str, Any]]
203
+ ) -> Dict[str, int]:
204
+ """
205
+ Parse voting results to count votes for each candidate.
206
+
207
+ Args:
208
+ results (List[Dict[str, Any]]): List of voting results from voter agents
209
+
210
+ Returns:
211
+ Dict[str, int]: Dictionary mapping candidate names to their vote counts
212
+ """
213
+ # Count the number of votes for each candidate
214
+ vote_counts = {}
215
+ for result in results:
216
+ candidate_name = result["candidate_agent_name"]
217
+ vote_counts[candidate_name] = (
218
+ vote_counts.get(candidate_name, 0) + 1
219
+ )
220
+
221
+ # Find the candidate with the most votes
222
+
223
+ return vote_counts
224
+
225
+ def run(
226
+ self, task: str, img: Optional[str] = None, *args, **kwargs
227
+ ):
228
+ """
229
+ Execute the complete election process.
230
+
231
+ This method orchestrates the entire election by:
232
+ 1. Adding the task to the conversation history
233
+ 2. Running all voter agents concurrently
234
+ 3. Collecting and processing the voting results
235
+
236
+ Args:
237
+ task (str): The election task or question to be voted on
238
+ img (Optional[str], optional): Image path if visual voting is required
239
+ *args: Additional positional arguments
240
+ **kwargs: Additional keyword arguments
241
+
242
+ Returns:
243
+ List[Dict[str, Any]]: Complete voting results from all agents
244
+ """
245
+ self.conversation.add(role="user", content=task)
246
+
247
+ results = self.run_voter_agents(task, img, *args, **kwargs)
248
+
249
+ print(results)
250
+
251
+ return results
252
+
253
+ def setup_voter_agents(self):
254
+ """
255
+ Configure voter agents with structured output capabilities and voting prompts.
256
+
257
+ This method sets up each voter agent with:
258
+ - Structured output schema for consistent voting format
259
+ - Voting-specific system prompts
260
+ - Tools for structured response generation
261
+
262
+ Returns:
263
+ List[Agent]: Configured voter agents ready for the election
264
+ """
265
+ schema = get_vote_schema()
266
+ prompt = _create_voting_prompt(self.candidate_agents)
267
+
268
+ for agent in self.agents:
269
+ agent.tools_list_dictionary = schema
270
+ agent.system_prompt += f"\n\n{prompt}"