swarms 7.7.7__py3-none-any.whl → 7.7.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.
- swarms/__init__.py +0 -1
- swarms/agents/cort_agent.py +206 -0
- swarms/agents/react_agent.py +173 -0
- swarms/communication/base_communication.py +290 -0
- swarms/communication/duckdb_wrap.py +369 -72
- swarms/communication/pulsar_struct.py +691 -0
- swarms/communication/redis_wrap.py +1362 -0
- swarms/communication/sqlite_wrap.py +547 -44
- swarms/prompts/safety_prompt.py +50 -0
- swarms/structs/agent.py +13 -8
- swarms/structs/concurrent_workflow.py +56 -242
- swarms/structs/conversation.py +228 -38
- swarms/structs/council_judge.py +456 -0
- swarms/structs/deep_research_swarm.py +19 -22
- swarms/structs/malt.py +30 -28
- swarms/structs/multi_model_gpu_manager.py +1 -1
- swarms/structs/output_types.py +1 -1
- swarms/structs/swarm_router.py +2 -2
- swarms/tools/mcp_client.py +1 -1
- swarms/tools/py_func_to_openai_func_str.py +2 -2
- swarms/utils/history_output_formatter.py +5 -5
- swarms/utils/try_except_wrapper.py +2 -2
- swarms/utils/xml_utils.py +42 -0
- {swarms-7.7.7.dist-info → swarms-7.7.9.dist-info}/METADATA +4 -3
- {swarms-7.7.7.dist-info → swarms-7.7.9.dist-info}/RECORD +28 -22
- {swarms-7.7.7.dist-info → swarms-7.7.9.dist-info}/WHEEL +1 -1
- swarms/client/__init__.py +0 -15
- swarms/client/main.py +0 -407
- {swarms-7.7.7.dist-info → swarms-7.7.9.dist-info}/LICENSE +0 -0
- {swarms-7.7.7.dist-info → swarms-7.7.9.dist-info}/entry_points.txt +0 -0
swarms/client/main.py
DELETED
@@ -1,407 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import os
|
3
|
-
from typing import List, Literal, Optional
|
4
|
-
|
5
|
-
import httpx
|
6
|
-
from swarms.utils.loguru_logger import initialize_logger
|
7
|
-
from pydantic import BaseModel, Field
|
8
|
-
from tenacity import retry, stop_after_attempt, wait_exponential
|
9
|
-
from swarms.structs.swarm_router import SwarmType
|
10
|
-
from typing import Any
|
11
|
-
|
12
|
-
logger = initialize_logger(log_folder="swarms_api")
|
13
|
-
|
14
|
-
|
15
|
-
class AgentInput(BaseModel):
|
16
|
-
agent_name: Optional[str] = Field(
|
17
|
-
None,
|
18
|
-
description="The name of the agent, limited to 100 characters.",
|
19
|
-
max_length=100,
|
20
|
-
)
|
21
|
-
description: Optional[str] = Field(
|
22
|
-
None,
|
23
|
-
description="A detailed description of the agent's purpose and capabilities, up to 500 characters.",
|
24
|
-
max_length=500,
|
25
|
-
)
|
26
|
-
system_prompt: Optional[str] = Field(
|
27
|
-
None,
|
28
|
-
description="The initial prompt or instructions given to the agent.",
|
29
|
-
)
|
30
|
-
model_name: Optional[str] = Field(
|
31
|
-
"gpt-4o",
|
32
|
-
description="The name of the model used by the agent. Model names can be configured like provider/model_name",
|
33
|
-
)
|
34
|
-
auto_generate_prompt: Optional[bool] = Field(
|
35
|
-
False,
|
36
|
-
description="Indicates whether the agent should automatically generate prompts.",
|
37
|
-
)
|
38
|
-
max_tokens: Optional[int] = Field(
|
39
|
-
8192,
|
40
|
-
description="The maximum number of tokens the agent can use in its responses.",
|
41
|
-
)
|
42
|
-
temperature: Optional[float] = Field(
|
43
|
-
0.5,
|
44
|
-
description="Controls the randomness of the agent's responses; higher values result in more random outputs.",
|
45
|
-
)
|
46
|
-
role: Optional[str] = Field(
|
47
|
-
"worker",
|
48
|
-
description="The role assigned to the agent, such as 'worker' or 'manager'.",
|
49
|
-
)
|
50
|
-
max_loops: Optional[int] = Field(
|
51
|
-
1,
|
52
|
-
description="The maximum number of iterations the agent is allowed to perform.",
|
53
|
-
)
|
54
|
-
dynamic_temperature_enabled: Optional[bool] = Field(
|
55
|
-
True,
|
56
|
-
description="Indicates whether the agent should use dynamic temperature.",
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
class SwarmRequest(BaseModel):
|
61
|
-
name: Optional[str] = Field(
|
62
|
-
"swarms-01",
|
63
|
-
description="The name of the swarm, limited to 100 characters.",
|
64
|
-
max_length=100,
|
65
|
-
)
|
66
|
-
description: Optional[str] = Field(
|
67
|
-
None,
|
68
|
-
description="A comprehensive description of the swarm's objectives and scope, up to 500 characters.",
|
69
|
-
max_length=500,
|
70
|
-
)
|
71
|
-
agents: Optional[List[AgentInput]] = Field(
|
72
|
-
None,
|
73
|
-
description="A list of agents that are part of the swarm.",
|
74
|
-
)
|
75
|
-
max_loops: Optional[int] = Field(
|
76
|
-
1,
|
77
|
-
description="The maximum number of iterations the swarm can execute.",
|
78
|
-
)
|
79
|
-
swarm_type: Optional[SwarmType] = Field(
|
80
|
-
None,
|
81
|
-
description="The type of swarm, defining its operational structure and behavior.",
|
82
|
-
)
|
83
|
-
rearrange_flow: Optional[str] = Field(
|
84
|
-
None,
|
85
|
-
description="The flow or sequence in which agents are rearranged during the swarm's operation.",
|
86
|
-
)
|
87
|
-
task: Optional[str] = Field(
|
88
|
-
None,
|
89
|
-
description="The specific task or objective the swarm is designed to accomplish.",
|
90
|
-
)
|
91
|
-
img: Optional[str] = Field(
|
92
|
-
None,
|
93
|
-
description="A URL to an image associated with the swarm, if applicable.",
|
94
|
-
)
|
95
|
-
return_history: Optional[bool] = Field(
|
96
|
-
True,
|
97
|
-
description="Determines whether the full history of the swarm's operations should be returned.",
|
98
|
-
)
|
99
|
-
rules: Optional[str] = Field(
|
100
|
-
None,
|
101
|
-
description="Any specific rules or guidelines that the swarm should follow.",
|
102
|
-
)
|
103
|
-
output_type: Optional[str] = Field(
|
104
|
-
"str",
|
105
|
-
description="The format in which the swarm's output should be returned, such as 'str', 'json', or 'dict'.",
|
106
|
-
)
|
107
|
-
|
108
|
-
|
109
|
-
# class SwarmResponse(BaseModel):
|
110
|
-
# swarm_id: str
|
111
|
-
# status: str
|
112
|
-
# result: Optional[str]
|
113
|
-
# error: Optional[str]
|
114
|
-
|
115
|
-
|
116
|
-
class HealthResponse(BaseModel):
|
117
|
-
status: str
|
118
|
-
version: str
|
119
|
-
|
120
|
-
|
121
|
-
class SwarmAPIError(Exception):
|
122
|
-
"""Base exception for Swarms API errors."""
|
123
|
-
|
124
|
-
pass
|
125
|
-
|
126
|
-
|
127
|
-
class SwarmAuthenticationError(SwarmAPIError):
|
128
|
-
"""Raised when authentication fails."""
|
129
|
-
|
130
|
-
pass
|
131
|
-
|
132
|
-
|
133
|
-
class SwarmValidationError(SwarmAPIError):
|
134
|
-
"""Raised when request validation fails."""
|
135
|
-
|
136
|
-
pass
|
137
|
-
|
138
|
-
|
139
|
-
class SwarmsAPIClient:
|
140
|
-
"""Production-grade client for the Swarms API."""
|
141
|
-
|
142
|
-
def __init__(
|
143
|
-
self,
|
144
|
-
api_key: Optional[str] = None,
|
145
|
-
base_url: str = "https://api.swarms.world",
|
146
|
-
timeout: int = 30,
|
147
|
-
max_retries: int = 3,
|
148
|
-
format_type: Literal["pydantic", "json", "dict"] = "pydantic",
|
149
|
-
):
|
150
|
-
"""Initialize the Swarms API client.
|
151
|
-
|
152
|
-
Args:
|
153
|
-
api_key: API key for authentication. If not provided, looks for SWARMS_API_KEY env var
|
154
|
-
base_url: Base URL for the API
|
155
|
-
timeout: Request timeout in seconds
|
156
|
-
max_retries: Maximum number of retries for failed requests
|
157
|
-
format_type: Desired output format ('pydantic', 'json', 'dict')
|
158
|
-
"""
|
159
|
-
self.api_key = api_key or os.getenv("SWARMS_API_KEY")
|
160
|
-
|
161
|
-
if not self.api_key:
|
162
|
-
logger.error(
|
163
|
-
"API key not provided and SWARMS_API_KEY env var not found"
|
164
|
-
)
|
165
|
-
raise SwarmAuthenticationError(
|
166
|
-
"API key not provided and SWARMS_API_KEY env var not found"
|
167
|
-
)
|
168
|
-
|
169
|
-
self.base_url = base_url.rstrip("/")
|
170
|
-
self.timeout = timeout
|
171
|
-
self.max_retries = max_retries
|
172
|
-
self.format_type = format_type
|
173
|
-
# Setup HTTP client
|
174
|
-
self.client = httpx.Client(
|
175
|
-
timeout=timeout,
|
176
|
-
headers={
|
177
|
-
"x-api-key": self.api_key,
|
178
|
-
"Content-Type": "application/json",
|
179
|
-
},
|
180
|
-
)
|
181
|
-
logger.info(
|
182
|
-
"SwarmsAPIClient initialized with base_url: {}",
|
183
|
-
self.base_url,
|
184
|
-
)
|
185
|
-
|
186
|
-
@retry(
|
187
|
-
stop=stop_after_attempt(3),
|
188
|
-
wait=wait_exponential(multiplier=1, min=4, max=10),
|
189
|
-
reraise=True,
|
190
|
-
)
|
191
|
-
async def health_check(self) -> HealthResponse:
|
192
|
-
"""Check the API health status.
|
193
|
-
|
194
|
-
Args:
|
195
|
-
output_format: Desired output format ('pydantic', 'json', 'dict')
|
196
|
-
|
197
|
-
Returns:
|
198
|
-
HealthResponse object or formatted output
|
199
|
-
"""
|
200
|
-
logger.info("Performing health check")
|
201
|
-
try:
|
202
|
-
response = self.client.get(f"{self.base_url}/health")
|
203
|
-
response.raise_for_status()
|
204
|
-
health_response = HealthResponse(**response.json())
|
205
|
-
logger.info("Health check successful")
|
206
|
-
return self.format_output(
|
207
|
-
health_response, self.format_type
|
208
|
-
)
|
209
|
-
except httpx.HTTPError as e:
|
210
|
-
logger.error("Health check failed: {}", str(e))
|
211
|
-
raise SwarmAPIError(f"Health check failed: {str(e)}")
|
212
|
-
|
213
|
-
@retry(
|
214
|
-
stop=stop_after_attempt(3),
|
215
|
-
wait=wait_exponential(multiplier=1, min=4, max=10),
|
216
|
-
reraise=True,
|
217
|
-
)
|
218
|
-
async def arun(self, swarm_request: SwarmRequest) -> Any:
|
219
|
-
"""Create and run a new swarm.
|
220
|
-
|
221
|
-
Args:
|
222
|
-
swarm_request: SwarmRequest object containing the swarm configuration
|
223
|
-
output_format: Desired output format ('pydantic', 'json', 'dict')
|
224
|
-
|
225
|
-
Returns:
|
226
|
-
SwarmResponse object or formatted output
|
227
|
-
"""
|
228
|
-
logger.info(
|
229
|
-
"Creating and running a new swarm with request: {}",
|
230
|
-
swarm_request,
|
231
|
-
)
|
232
|
-
try:
|
233
|
-
response = self.client.post(
|
234
|
-
f"{self.base_url}/v1/swarm/completions",
|
235
|
-
json=swarm_request.model_dump(),
|
236
|
-
)
|
237
|
-
response.raise_for_status()
|
238
|
-
logger.info("Swarm creation and run successful")
|
239
|
-
return self.format_output(
|
240
|
-
response.json(), self.format_type
|
241
|
-
)
|
242
|
-
except httpx.HTTPStatusError as e:
|
243
|
-
if e.response.status_code == 401:
|
244
|
-
logger.error("Invalid API key")
|
245
|
-
raise SwarmAuthenticationError("Invalid API key")
|
246
|
-
elif e.response.status_code == 422:
|
247
|
-
logger.error("Invalid request parameters")
|
248
|
-
raise SwarmValidationError(
|
249
|
-
"Invalid request parameters"
|
250
|
-
)
|
251
|
-
logger.error("Swarm creation failed: {}", str(e))
|
252
|
-
raise SwarmAPIError(f"Swarm creation failed: {str(e)}")
|
253
|
-
except Exception as e:
|
254
|
-
logger.error(
|
255
|
-
"Unexpected error during swarm creation: {}", str(e)
|
256
|
-
)
|
257
|
-
raise
|
258
|
-
|
259
|
-
@retry(
|
260
|
-
stop=stop_after_attempt(3),
|
261
|
-
wait=wait_exponential(multiplier=1, min=4, max=10),
|
262
|
-
reraise=True,
|
263
|
-
)
|
264
|
-
def run(self, swarm_request: SwarmRequest) -> Any:
|
265
|
-
"""Create and run a new swarm.
|
266
|
-
|
267
|
-
Args:
|
268
|
-
swarm_request: SwarmRequest object containing the swarm configuration
|
269
|
-
output_format: Desired output format ('pydantic', 'json', 'dict')
|
270
|
-
|
271
|
-
Returns:
|
272
|
-
SwarmResponse object or formatted output
|
273
|
-
"""
|
274
|
-
logger.info(
|
275
|
-
"Creating and running a new swarm with request: {}",
|
276
|
-
swarm_request,
|
277
|
-
)
|
278
|
-
try:
|
279
|
-
response = self.client.post(
|
280
|
-
f"{self.base_url}/v1/swarm/completions",
|
281
|
-
json=swarm_request.model_dump(),
|
282
|
-
)
|
283
|
-
print(response.json())
|
284
|
-
logger.info("Swarm creation and run successful")
|
285
|
-
return response.json()
|
286
|
-
except httpx.HTTPStatusError as e:
|
287
|
-
if e.response.status_code == 401:
|
288
|
-
logger.error("Invalid API key")
|
289
|
-
raise SwarmAuthenticationError("Invalid API key")
|
290
|
-
elif e.response.status_code == 422:
|
291
|
-
logger.error("Invalid request parameters")
|
292
|
-
raise SwarmValidationError(
|
293
|
-
"Invalid request parameters"
|
294
|
-
)
|
295
|
-
logger.error("Swarm creation failed: {}", str(e))
|
296
|
-
raise SwarmAPIError(f"Swarm creation failed: {str(e)}")
|
297
|
-
except Exception as e:
|
298
|
-
logger.error(
|
299
|
-
"Unexpected error during swarm creation: {}", str(e)
|
300
|
-
)
|
301
|
-
raise
|
302
|
-
|
303
|
-
@retry(
|
304
|
-
stop=stop_after_attempt(3),
|
305
|
-
wait=wait_exponential(multiplier=1, min=4, max=10),
|
306
|
-
reraise=True,
|
307
|
-
)
|
308
|
-
async def run_batch(
|
309
|
-
self, swarm_requests: List[SwarmRequest]
|
310
|
-
) -> List[Any]:
|
311
|
-
"""Create and run multiple swarms in batch.
|
312
|
-
|
313
|
-
Args:
|
314
|
-
swarm_requests: List of SwarmRequest objects
|
315
|
-
output_format: Desired output format ('pydantic', 'json', 'dict')
|
316
|
-
|
317
|
-
Returns:
|
318
|
-
List of SwarmResponse objects or formatted outputs
|
319
|
-
"""
|
320
|
-
logger.info(
|
321
|
-
"Creating and running batch swarms with requests: {}",
|
322
|
-
swarm_requests,
|
323
|
-
)
|
324
|
-
try:
|
325
|
-
response = self.client.post(
|
326
|
-
f"{self.base_url}/v1/swarm/batch/completions",
|
327
|
-
json=[req.model_dump() for req in swarm_requests],
|
328
|
-
)
|
329
|
-
response.raise_for_status()
|
330
|
-
logger.info("Batch swarm creation and run successful")
|
331
|
-
return [
|
332
|
-
self.format_output(resp, self.format_type)
|
333
|
-
for resp in response.json()
|
334
|
-
]
|
335
|
-
except httpx.HTTPStatusError as e:
|
336
|
-
if e.response.status_code == 401:
|
337
|
-
logger.error("Invalid API key")
|
338
|
-
raise SwarmAuthenticationError("Invalid API key")
|
339
|
-
elif e.response.status_code == 422:
|
340
|
-
logger.error("Invalid request parameters")
|
341
|
-
raise SwarmValidationError(
|
342
|
-
"Invalid request parameters"
|
343
|
-
)
|
344
|
-
logger.error("Batch swarm creation failed: {}", str(e))
|
345
|
-
raise SwarmAPIError(
|
346
|
-
f"Batch swarm creation failed: {str(e)}"
|
347
|
-
)
|
348
|
-
except Exception as e:
|
349
|
-
logger.error(
|
350
|
-
"Unexpected error during batch swarm creation: {}",
|
351
|
-
str(e),
|
352
|
-
)
|
353
|
-
raise
|
354
|
-
|
355
|
-
def get_logs(self):
|
356
|
-
logger.info("Retrieving logs")
|
357
|
-
try:
|
358
|
-
response = self.client.get(
|
359
|
-
f"{self.base_url}/v1/swarm/logs"
|
360
|
-
)
|
361
|
-
response.raise_for_status()
|
362
|
-
logs = response.json()
|
363
|
-
logger.info("Logs retrieved successfully")
|
364
|
-
return self.format_output(logs, self.format_type)
|
365
|
-
except httpx.HTTPError as e:
|
366
|
-
logger.error("Failed to retrieve logs: {}", str(e))
|
367
|
-
raise SwarmAPIError(f"Failed to retrieve logs: {str(e)}")
|
368
|
-
|
369
|
-
def format_output(self, data, output_format: str):
|
370
|
-
"""Format the output based on the specified format.
|
371
|
-
|
372
|
-
Args:
|
373
|
-
data: The data to format
|
374
|
-
output_format: The desired output format ('pydantic', 'json', 'dict')
|
375
|
-
|
376
|
-
Returns:
|
377
|
-
Formatted data
|
378
|
-
"""
|
379
|
-
logger.info(
|
380
|
-
"Formatting output with format: {}", output_format
|
381
|
-
)
|
382
|
-
if output_format == "json":
|
383
|
-
return (
|
384
|
-
data.model_dump_json(indent=4)
|
385
|
-
if isinstance(data, BaseModel)
|
386
|
-
else json.dumps(data)
|
387
|
-
)
|
388
|
-
elif output_format == "dict":
|
389
|
-
return (
|
390
|
-
data.model_dump()
|
391
|
-
if isinstance(data, BaseModel)
|
392
|
-
else data
|
393
|
-
)
|
394
|
-
return data # Default to returning the pydantic model
|
395
|
-
|
396
|
-
def close(self):
|
397
|
-
"""Close the HTTP client."""
|
398
|
-
logger.info("Closing HTTP client")
|
399
|
-
self.client.close()
|
400
|
-
|
401
|
-
async def __aenter__(self):
|
402
|
-
logger.info("Entering async context")
|
403
|
-
return self
|
404
|
-
|
405
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
406
|
-
logger.info("Exiting async context")
|
407
|
-
self.close()
|
File without changes
|
File without changes
|