swarms 7.8.4__py3-none-any.whl → 7.8.7__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/ape_agent.py +5 -22
- swarms/agents/consistency_agent.py +1 -1
- swarms/agents/i_agent.py +1 -1
- swarms/agents/reasoning_agents.py +99 -3
- swarms/agents/reasoning_duo.py +1 -1
- swarms/cli/main.py +1 -1
- swarms/communication/__init__.py +1 -0
- swarms/communication/duckdb_wrap.py +32 -2
- swarms/communication/pulsar_struct.py +45 -19
- swarms/communication/redis_wrap.py +56 -11
- swarms/communication/supabase_wrap.py +1659 -0
- swarms/prompts/prompt.py +0 -3
- swarms/schemas/agent_completion_response.py +71 -0
- swarms/schemas/agent_rag_schema.py +7 -0
- swarms/schemas/conversation_schema.py +9 -0
- swarms/schemas/llm_agent_schema.py +99 -81
- swarms/schemas/swarms_api_schemas.py +164 -0
- swarms/structs/__init__.py +14 -11
- swarms/structs/agent.py +219 -199
- swarms/structs/agent_rag_handler.py +685 -0
- swarms/structs/base_swarm.py +2 -1
- swarms/structs/conversation.py +608 -87
- swarms/structs/csv_to_agent.py +153 -100
- swarms/structs/deep_research_swarm.py +197 -193
- swarms/structs/dynamic_conversational_swarm.py +18 -7
- swarms/structs/hiearchical_swarm.py +1 -1
- swarms/structs/hybrid_hiearchical_peer_swarm.py +2 -18
- swarms/structs/image_batch_processor.py +261 -0
- swarms/structs/interactive_groupchat.py +356 -0
- swarms/structs/ma_blocks.py +75 -0
- swarms/structs/majority_voting.py +1 -1
- swarms/structs/mixture_of_agents.py +1 -1
- swarms/structs/multi_agent_router.py +3 -2
- swarms/structs/rearrange.py +3 -3
- swarms/structs/sequential_workflow.py +3 -3
- swarms/structs/swarm_matcher.py +500 -411
- swarms/structs/swarm_router.py +15 -97
- swarms/structs/swarming_architectures.py +1 -1
- swarms/tools/mcp_client_call.py +3 -0
- swarms/utils/__init__.py +10 -2
- swarms/utils/check_all_model_max_tokens.py +43 -0
- swarms/utils/generate_keys.py +0 -27
- swarms/utils/history_output_formatter.py +5 -20
- swarms/utils/litellm_wrapper.py +208 -60
- swarms/utils/output_types.py +24 -0
- swarms/utils/vllm_wrapper.py +5 -6
- swarms/utils/xml_utils.py +37 -2
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/METADATA +31 -55
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/RECORD +53 -48
- swarms/structs/multi_agent_collab.py +0 -242
- swarms/structs/output_types.py +0 -6
- swarms/utils/markdown_message.py +0 -21
- swarms/utils/visualizer.py +0 -510
- swarms/utils/wrapper_clusterop.py +0 -127
- /swarms/{tools → schemas}/tool_schema_base_model.py +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/LICENSE +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/WHEEL +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/entry_points.txt +0 -0
swarms/structs/csv_to_agent.py
CHANGED
@@ -3,12 +3,25 @@ from typing import (
|
|
3
3
|
Dict,
|
4
4
|
TypedDict,
|
5
5
|
Any,
|
6
|
+
Union,
|
7
|
+
TypeVar,
|
6
8
|
)
|
7
9
|
from dataclasses import dataclass
|
8
10
|
import csv
|
11
|
+
import json
|
12
|
+
import yaml
|
9
13
|
from pathlib import Path
|
10
14
|
from enum import Enum
|
11
15
|
from swarms.structs.agent import Agent
|
16
|
+
from swarms.schemas.swarms_api_schemas import AgentSpec
|
17
|
+
from litellm import model_list
|
18
|
+
import concurrent.futures
|
19
|
+
from tqdm import tqdm
|
20
|
+
|
21
|
+
# Type variable for agent configuration
|
22
|
+
AgentConfigType = TypeVar(
|
23
|
+
"AgentConfigType", bound=Union[AgentSpec, Dict[str, Any]]
|
24
|
+
)
|
12
25
|
|
13
26
|
|
14
27
|
class ModelName(str, Enum):
|
@@ -32,12 +45,20 @@ class ModelName(str, Enum):
|
|
32
45
|
return model_name in cls.get_model_names()
|
33
46
|
|
34
47
|
|
48
|
+
class FileType(str, Enum):
|
49
|
+
"""Supported file types for agent configuration"""
|
50
|
+
|
51
|
+
CSV = "csv"
|
52
|
+
JSON = "json"
|
53
|
+
YAML = "yaml"
|
54
|
+
|
55
|
+
|
35
56
|
class AgentConfigDict(TypedDict):
|
36
57
|
"""TypedDict for agent configuration"""
|
37
58
|
|
38
59
|
agent_name: str
|
39
60
|
system_prompt: str
|
40
|
-
model_name: str
|
61
|
+
model_name: str
|
41
62
|
max_loops: int
|
42
63
|
autosave: bool
|
43
64
|
dashboard: bool
|
@@ -68,15 +89,26 @@ class AgentValidator:
|
|
68
89
|
"""Validates agent configuration data"""
|
69
90
|
|
70
91
|
@staticmethod
|
71
|
-
def validate_config(
|
72
|
-
|
92
|
+
def validate_config(
|
93
|
+
config: Union[AgentSpec, Dict[str, Any]],
|
94
|
+
) -> AgentConfigDict:
|
95
|
+
"""Validate and convert agent configuration from either AgentSpec or Dict"""
|
73
96
|
try:
|
74
|
-
#
|
97
|
+
# Convert AgentSpec to dict if needed
|
98
|
+
if isinstance(config, AgentSpec):
|
99
|
+
config = config.model_dump()
|
100
|
+
|
101
|
+
# Validate model name using litellm model list
|
75
102
|
model_name = str(config["model_name"])
|
76
|
-
if not
|
77
|
-
|
103
|
+
if not any(
|
104
|
+
model_name in model["model_name"]
|
105
|
+
for model in model_list
|
106
|
+
):
|
107
|
+
valid_models = [
|
108
|
+
model["model_name"] for model in model_list
|
109
|
+
]
|
78
110
|
raise AgentValidationError(
|
79
|
-
|
111
|
+
"Invalid model name. Must be one of the supported litellm models",
|
80
112
|
"model_name",
|
81
113
|
model_name,
|
82
114
|
)
|
@@ -138,38 +170,36 @@ class AgentValidator:
|
|
138
170
|
|
139
171
|
|
140
172
|
class AgentLoader:
|
141
|
-
"""Class to manage agents through
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
"""
|
147
|
-
|
148
|
-
|
173
|
+
"""Class to manage agents through various file formats with type safety and high performance"""
|
174
|
+
|
175
|
+
def __init__(
|
176
|
+
self, file_path: Union[str, Path], max_workers: int = 10
|
177
|
+
):
|
178
|
+
"""Initialize the AgentLoader with file path and max workers for parallel processing"""
|
179
|
+
self.file_path = (
|
180
|
+
Path(file_path)
|
181
|
+
if isinstance(file_path, str)
|
182
|
+
else file_path
|
183
|
+
)
|
184
|
+
self.max_workers = max_workers
|
149
185
|
|
150
186
|
@property
|
151
|
-
def
|
152
|
-
"""
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
"
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
"output_type",
|
168
|
-
"streaming",
|
169
|
-
]
|
170
|
-
|
171
|
-
def create_agent_csv(self, agents: List[Dict[str, Any]]) -> None:
|
172
|
-
"""Create a CSV file with validated agent configurations"""
|
187
|
+
def file_type(self) -> FileType:
|
188
|
+
"""Determine the file type based on extension"""
|
189
|
+
ext = self.file_path.suffix.lower()
|
190
|
+
if ext == ".csv":
|
191
|
+
return FileType.CSV
|
192
|
+
elif ext == ".json":
|
193
|
+
return FileType.JSON
|
194
|
+
elif ext in [".yaml", ".yml"]:
|
195
|
+
return FileType.YAML
|
196
|
+
else:
|
197
|
+
raise ValueError(f"Unsupported file type: {ext}")
|
198
|
+
|
199
|
+
def create_agent_file(
|
200
|
+
self, agents: List[Union[AgentSpec, Dict[str, Any]]]
|
201
|
+
) -> None:
|
202
|
+
"""Create a file with validated agent configurations"""
|
173
203
|
validated_agents = []
|
174
204
|
for agent in agents:
|
175
205
|
try:
|
@@ -183,81 +213,71 @@ class AgentLoader:
|
|
183
213
|
)
|
184
214
|
raise
|
185
215
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
216
|
+
if self.file_type == FileType.CSV:
|
217
|
+
self._write_csv(validated_agents)
|
218
|
+
elif self.file_type == FileType.JSON:
|
219
|
+
self._write_json(validated_agents)
|
220
|
+
elif self.file_type == FileType.YAML:
|
221
|
+
self._write_yaml(validated_agents)
|
190
222
|
|
191
223
|
print(
|
192
|
-
f"Created
|
224
|
+
f"Created {self.file_type.value} file with {len(validated_agents)} agents at {self.file_path}"
|
193
225
|
)
|
194
226
|
|
195
|
-
def load_agents(self
|
196
|
-
"""Load and create agents from
|
197
|
-
if
|
198
|
-
if not self.csv_path.exists():
|
199
|
-
raise FileNotFoundError(
|
200
|
-
f"CSV file not found at {self.csv_path}"
|
201
|
-
)
|
202
|
-
return self._load_agents_from_csv()
|
203
|
-
elif file_type == "json":
|
204
|
-
return self._load_agents_from_json()
|
205
|
-
else:
|
206
|
-
raise ValueError(
|
207
|
-
"Unsupported file type. Use 'csv' or 'json'."
|
208
|
-
)
|
209
|
-
|
210
|
-
def _load_agents_from_csv(self) -> List[Agent]:
|
211
|
-
"""Load agents from a CSV file"""
|
212
|
-
agents: List[Agent] = []
|
213
|
-
with open(self.csv_path, "r") as f:
|
214
|
-
reader = csv.DictReader(f)
|
215
|
-
for row in reader:
|
216
|
-
try:
|
217
|
-
validated_config = AgentValidator.validate_config(
|
218
|
-
row
|
219
|
-
)
|
220
|
-
agent = self._create_agent(validated_config)
|
221
|
-
agents.append(agent)
|
222
|
-
except AgentValidationError as e:
|
223
|
-
print(
|
224
|
-
f"Skipping invalid agent configuration: {e}"
|
225
|
-
)
|
226
|
-
continue
|
227
|
-
|
228
|
-
print(f"Loaded {len(agents)} agents from {self.csv_path}")
|
229
|
-
return agents
|
230
|
-
|
231
|
-
def _load_agents_from_json(self) -> List[Agent]:
|
232
|
-
"""Load agents from a JSON file"""
|
233
|
-
import json
|
234
|
-
|
235
|
-
if not self.csv_path.with_suffix(".json").exists():
|
227
|
+
def load_agents(self) -> List[Agent]:
|
228
|
+
"""Load and create agents from file with validation and parallel processing"""
|
229
|
+
if not self.file_path.exists():
|
236
230
|
raise FileNotFoundError(
|
237
|
-
f"
|
231
|
+
f"File not found at {self.file_path}"
|
238
232
|
)
|
239
233
|
|
234
|
+
if self.file_type == FileType.CSV:
|
235
|
+
agents_data = self._read_csv()
|
236
|
+
elif self.file_type == FileType.JSON:
|
237
|
+
agents_data = self._read_json()
|
238
|
+
elif self.file_type == FileType.YAML:
|
239
|
+
agents_data = self._read_yaml()
|
240
|
+
|
241
|
+
# Process agents in parallel with progress bar
|
240
242
|
agents: List[Agent] = []
|
241
|
-
with
|
242
|
-
|
243
|
-
|
243
|
+
with concurrent.futures.ThreadPoolExecutor(
|
244
|
+
max_workers=self.max_workers
|
245
|
+
) as executor:
|
246
|
+
futures = []
|
247
|
+
for agent_data in agents_data:
|
248
|
+
futures.append(
|
249
|
+
executor.submit(self._process_agent, agent_data)
|
250
|
+
)
|
251
|
+
|
252
|
+
# Use tqdm to show progress
|
253
|
+
for future in tqdm(
|
254
|
+
concurrent.futures.as_completed(futures),
|
255
|
+
total=len(futures),
|
256
|
+
desc="Loading agents",
|
257
|
+
):
|
244
258
|
try:
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
except AgentValidationError as e:
|
251
|
-
print(
|
252
|
-
f"Skipping invalid agent configuration: {e}"
|
253
|
-
)
|
254
|
-
continue
|
259
|
+
agent = future.result()
|
260
|
+
if agent:
|
261
|
+
agents.append(agent)
|
262
|
+
except Exception as e:
|
263
|
+
print(f"Error processing agent: {e}")
|
255
264
|
|
256
|
-
print(
|
257
|
-
f"Loaded {len(agents)} agents from {self.csv_path.with_suffix('.json')}"
|
258
|
-
)
|
265
|
+
print(f"Loaded {len(agents)} agents from {self.file_path}")
|
259
266
|
return agents
|
260
267
|
|
268
|
+
def _process_agent(
|
269
|
+
self, agent_data: Union[AgentSpec, Dict[str, Any]]
|
270
|
+
) -> Union[Agent, None]:
|
271
|
+
"""Process a single agent configuration"""
|
272
|
+
try:
|
273
|
+
validated_config = AgentValidator.validate_config(
|
274
|
+
agent_data
|
275
|
+
)
|
276
|
+
return self._create_agent(validated_config)
|
277
|
+
except AgentValidationError as e:
|
278
|
+
print(f"Skipping invalid agent configuration: {e}")
|
279
|
+
return None
|
280
|
+
|
261
281
|
def _create_agent(
|
262
282
|
self, validated_config: AgentConfigDict
|
263
283
|
) -> Agent:
|
@@ -281,3 +301,36 @@ class AgentLoader:
|
|
281
301
|
output_type=validated_config["output_type"],
|
282
302
|
streaming_on=validated_config["streaming"],
|
283
303
|
)
|
304
|
+
|
305
|
+
def _write_csv(self, agents: List[Dict[str, Any]]) -> None:
|
306
|
+
"""Write agents to CSV file"""
|
307
|
+
with open(self.file_path, "w", newline="") as f:
|
308
|
+
writer = csv.DictWriter(f, fieldnames=agents[0].keys())
|
309
|
+
writer.writeheader()
|
310
|
+
writer.writerows(agents)
|
311
|
+
|
312
|
+
def _write_json(self, agents: List[Dict[str, Any]]) -> None:
|
313
|
+
"""Write agents to JSON file"""
|
314
|
+
with open(self.file_path, "w") as f:
|
315
|
+
json.dump(agents, f, indent=2)
|
316
|
+
|
317
|
+
def _write_yaml(self, agents: List[Dict[str, Any]]) -> None:
|
318
|
+
"""Write agents to YAML file"""
|
319
|
+
with open(self.file_path, "w") as f:
|
320
|
+
yaml.dump(agents, f, default_flow_style=False)
|
321
|
+
|
322
|
+
def _read_csv(self) -> List[Dict[str, Any]]:
|
323
|
+
"""Read agents from CSV file"""
|
324
|
+
with open(self.file_path, "r") as f:
|
325
|
+
reader = csv.DictReader(f)
|
326
|
+
return list(reader)
|
327
|
+
|
328
|
+
def _read_json(self) -> List[Dict[str, Any]]:
|
329
|
+
"""Read agents from JSON file"""
|
330
|
+
with open(self.file_path, "r") as f:
|
331
|
+
return json.load(f)
|
332
|
+
|
333
|
+
def _read_yaml(self) -> List[Dict[str, Any]]:
|
334
|
+
"""Read agents from YAML file"""
|
335
|
+
with open(self.file_path, "r") as f:
|
336
|
+
return yaml.safe_load(f)
|