swarms 7.8.3__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.
Files changed (60) hide show
  1. swarms/agents/ape_agent.py +5 -22
  2. swarms/agents/consistency_agent.py +1 -1
  3. swarms/agents/i_agent.py +1 -1
  4. swarms/agents/reasoning_agents.py +99 -3
  5. swarms/agents/reasoning_duo.py +1 -1
  6. swarms/cli/main.py +1 -1
  7. swarms/communication/__init__.py +1 -0
  8. swarms/communication/duckdb_wrap.py +32 -2
  9. swarms/communication/pulsar_struct.py +45 -19
  10. swarms/communication/redis_wrap.py +56 -11
  11. swarms/communication/supabase_wrap.py +1659 -0
  12. swarms/prompts/agent_conversation_aggregator.py +38 -0
  13. swarms/prompts/prompt.py +0 -3
  14. swarms/schemas/agent_completion_response.py +71 -0
  15. swarms/schemas/agent_rag_schema.py +7 -0
  16. swarms/schemas/conversation_schema.py +9 -0
  17. swarms/schemas/llm_agent_schema.py +99 -81
  18. swarms/schemas/swarms_api_schemas.py +164 -0
  19. swarms/structs/__init__.py +15 -9
  20. swarms/structs/agent.py +219 -199
  21. swarms/structs/agent_rag_handler.py +685 -0
  22. swarms/structs/base_swarm.py +2 -1
  23. swarms/structs/conversation.py +832 -264
  24. swarms/structs/csv_to_agent.py +153 -100
  25. swarms/structs/deep_research_swarm.py +197 -193
  26. swarms/structs/dynamic_conversational_swarm.py +18 -7
  27. swarms/structs/hiearchical_swarm.py +1 -1
  28. swarms/structs/hybrid_hiearchical_peer_swarm.py +2 -18
  29. swarms/structs/image_batch_processor.py +261 -0
  30. swarms/structs/interactive_groupchat.py +356 -0
  31. swarms/structs/ma_blocks.py +159 -0
  32. swarms/structs/majority_voting.py +1 -1
  33. swarms/structs/mixture_of_agents.py +1 -1
  34. swarms/structs/multi_agent_exec.py +25 -26
  35. swarms/structs/multi_agent_router.py +3 -2
  36. swarms/structs/rearrange.py +3 -3
  37. swarms/structs/sequential_workflow.py +3 -3
  38. swarms/structs/swarm_matcher.py +499 -408
  39. swarms/structs/swarm_router.py +15 -97
  40. swarms/structs/swarming_architectures.py +1 -1
  41. swarms/tools/mcp_client_call.py +3 -0
  42. swarms/utils/__init__.py +10 -2
  43. swarms/utils/check_all_model_max_tokens.py +43 -0
  44. swarms/utils/generate_keys.py +0 -27
  45. swarms/utils/history_output_formatter.py +5 -20
  46. swarms/utils/litellm_wrapper.py +208 -60
  47. swarms/utils/output_types.py +24 -0
  48. swarms/utils/vllm_wrapper.py +14 -13
  49. swarms/utils/xml_utils.py +37 -2
  50. {swarms-7.8.3.dist-info → swarms-7.8.7.dist-info}/METADATA +31 -55
  51. {swarms-7.8.3.dist-info → swarms-7.8.7.dist-info}/RECORD +55 -48
  52. swarms/structs/multi_agent_collab.py +0 -242
  53. swarms/structs/output_types.py +0 -6
  54. swarms/utils/markdown_message.py +0 -21
  55. swarms/utils/visualizer.py +0 -510
  56. swarms/utils/wrapper_clusterop.py +0 -127
  57. /swarms/{tools → schemas}/tool_schema_base_model.py +0 -0
  58. {swarms-7.8.3.dist-info → swarms-7.8.7.dist-info}/LICENSE +0 -0
  59. {swarms-7.8.3.dist-info → swarms-7.8.7.dist-info}/WHEEL +0 -0
  60. {swarms-7.8.3.dist-info → swarms-7.8.7.dist-info}/entry_points.txt +0 -0
@@ -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 # Using str instead of ModelName for flexibility
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(config: Dict[str, Any]) -> AgentConfigDict:
72
- """Validate and convert agent configuration"""
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
- # Validate model name
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 ModelName.is_valid_model(model_name):
77
- valid_models = ModelName.get_model_names()
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
- f"Invalid model name. Must be one of: {', '.join(valid_models)}",
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 CSV with type safety"""
142
-
143
- csv_path: Path
144
-
145
- def __post_init__(self) -> None:
146
- """Convert string path to Path object if necessary"""
147
- if isinstance(self.csv_path, str):
148
- self.csv_path = Path(self.csv_path)
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 headers(self) -> List[str]:
152
- """CSV headers for agent configuration"""
153
- return [
154
- "agent_name",
155
- "system_prompt",
156
- "model_name",
157
- "max_loops",
158
- "autosave",
159
- "dashboard",
160
- "verbose",
161
- "dynamic_temperature",
162
- "saved_state_path",
163
- "user_name",
164
- "retry_attempts",
165
- "context_length",
166
- "return_step_meta",
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
- with open(self.csv_path, "w", newline="") as f:
187
- writer = csv.DictWriter(f, fieldnames=self.headers)
188
- writer.writeheader()
189
- writer.writerows(validated_agents)
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 CSV with {len(validated_agents)} agents at {self.csv_path}"
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, file_type: str = "csv") -> List[Agent]:
196
- """Load and create agents from CSV or JSON with validation"""
197
- if file_type == "csv":
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"JSON file not found at {self.csv_path.with_suffix('.json')}"
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 open(self.csv_path.with_suffix(".json"), "r") as f:
242
- agents_data = json.load(f)
243
- for agent in agents_data:
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
- validated_config = AgentValidator.validate_config(
246
- agent
247
- )
248
- agent = self._create_agent(validated_config)
249
- agents.append(agent)
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)