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.
- swarms/agents/agent_judge.py +350 -61
- swarms/agents/reasoning_agents.py +62 -72
- swarms/agents/reasoning_duo.py +77 -24
- swarms/structs/__init__.py +2 -0
- swarms/structs/agent.py +21 -15
- swarms/structs/election_swarm.py +270 -0
- swarms/structs/heavy_swarm.py +1701 -0
- swarms/structs/qa_swarm.py +253 -0
- swarms/structs/swarm_router.py +61 -21
- swarms/telemetry/log_executions.py +257 -8
- swarms/utils/agent_cache.py +675 -0
- swarms/utils/concurrent_wrapper.py +520 -0
- {swarms-7.9.9.dist-info → swarms-8.0.0.dist-info}/METADATA +20 -16
- {swarms-7.9.9.dist-info → swarms-8.0.0.dist-info}/RECORD +17 -12
- {swarms-7.9.9.dist-info → swarms-8.0.0.dist-info}/LICENSE +0 -0
- {swarms-7.9.9.dist-info → swarms-8.0.0.dist-info}/WHEEL +0 -0
- {swarms-7.9.9.dist-info → swarms-8.0.0.dist-info}/entry_points.txt +0 -0
@@ -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}"
|