swarms 7.6.7__py3-none-any.whl → 7.7.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/__init__.py +1 -0
- swarms/structs/agent.py +81 -79
- swarms/structs/deep_research_swarm.py +4 -4
- swarms/structs/swarm_builder.py +0 -5
- swarms/telemetry/main.py +103 -65
- swarms/utils/litellm_wrapper.py +24 -10
- {swarms-7.6.7.dist-info → swarms-7.7.0.dist-info}/METADATA +1 -2
- {swarms-7.6.7.dist-info → swarms-7.7.0.dist-info}/RECORD +11 -13
- swarms/structs/workspace_manager.py +0 -178
- swarms/utils/swarm_reliability_checks.py +0 -81
- {swarms-7.6.7.dist-info → swarms-7.7.0.dist-info}/LICENSE +0 -0
- {swarms-7.6.7.dist-info → swarms-7.7.0.dist-info}/WHEEL +0 -0
- {swarms-7.6.7.dist-info → swarms-7.7.0.dist-info}/entry_points.txt +0 -0
swarms/__init__.py
CHANGED
@@ -7,6 +7,7 @@ from swarms.telemetry.bootup import bootup # noqa: E402, F403
|
|
7
7
|
bootup()
|
8
8
|
|
9
9
|
from swarms.agents import * # noqa: E402, F403
|
10
|
+
|
10
11
|
from swarms.artifacts import * # noqa: E402, F403
|
11
12
|
from swarms.prompts import * # noqa: E402, F403
|
12
13
|
from swarms.schemas import * # noqa: E402, F403
|
swarms/structs/agent.py
CHANGED
@@ -46,11 +46,12 @@ from swarms.structs.safe_loading import (
|
|
46
46
|
)
|
47
47
|
from swarms.telemetry.main import log_agent_data
|
48
48
|
from swarms.tools.base_tool import BaseTool
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
|
50
|
+
# from swarms.tools.mcp_integration import (
|
51
|
+
# MCPServerSseParams,
|
52
|
+
# batch_mcp_flow,
|
53
|
+
# mcp_flow_get_tool_schema,
|
54
|
+
# )
|
54
55
|
from swarms.tools.tool_parse_exec import parse_and_execute_json
|
55
56
|
from swarms.utils.any_to_str import any_to_str
|
56
57
|
from swarms.utils.data_to_text import data_to_text
|
@@ -62,7 +63,6 @@ from swarms.utils.history_output_formatter import (
|
|
62
63
|
from swarms.utils.litellm_tokenizer import count_tokens
|
63
64
|
from swarms.utils.litellm_wrapper import LiteLLM
|
64
65
|
from swarms.utils.pdf_to_text import pdf_to_text
|
65
|
-
from swarms.utils.str_to_dict import str_to_dict
|
66
66
|
|
67
67
|
|
68
68
|
# Utils
|
@@ -403,7 +403,7 @@ class Agent:
|
|
403
403
|
role: agent_roles = "worker",
|
404
404
|
no_print: bool = False,
|
405
405
|
tools_list_dictionary: Optional[List[Dict[str, Any]]] = None,
|
406
|
-
mcp_servers: List[MCPServerSseParams] = [],
|
406
|
+
# mcp_servers: List[MCPServerSseParams] = [],
|
407
407
|
*args,
|
408
408
|
**kwargs,
|
409
409
|
):
|
@@ -523,7 +523,7 @@ class Agent:
|
|
523
523
|
self.role = role
|
524
524
|
self.no_print = no_print
|
525
525
|
self.tools_list_dictionary = tools_list_dictionary
|
526
|
-
self.mcp_servers = mcp_servers
|
526
|
+
# self.mcp_servers = mcp_servers
|
527
527
|
self._cached_llm = (
|
528
528
|
None # Add this line to cache the LLM instance
|
529
529
|
)
|
@@ -643,11 +643,11 @@ class Agent:
|
|
643
643
|
if self.llm is None:
|
644
644
|
self.llm = self.llm_handling()
|
645
645
|
|
646
|
-
if (
|
647
|
-
|
648
|
-
|
649
|
-
):
|
650
|
-
|
646
|
+
# if (
|
647
|
+
# self.tools_list_dictionary is None
|
648
|
+
# and self.mcp_servers is not None
|
649
|
+
# ):
|
650
|
+
# self.tools_list_dictionary = self.mcp_tool_handling()
|
651
651
|
|
652
652
|
def llm_handling(self):
|
653
653
|
# Use cached instance if available
|
@@ -695,68 +695,68 @@ class Agent:
|
|
695
695
|
)
|
696
696
|
return None
|
697
697
|
|
698
|
-
def mcp_execution_flow(self, response: any):
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
def mcp_tool_handling(self):
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
698
|
+
# def mcp_execution_flow(self, response: any):
|
699
|
+
# """
|
700
|
+
# Executes the MCP (Model Context Protocol) flow based on the provided response.
|
701
|
+
|
702
|
+
# This method takes a response, converts it from a string to a dictionary format,
|
703
|
+
# and checks for the presence of a tool name or a name in the response. If either
|
704
|
+
# is found, it retrieves the tool name and proceeds to call the batch_mcp_flow
|
705
|
+
# function to execute the corresponding tool actions.
|
706
|
+
|
707
|
+
# Args:
|
708
|
+
# response (any): The response to be processed, which can be in string format
|
709
|
+
# that represents a dictionary.
|
710
|
+
|
711
|
+
# Returns:
|
712
|
+
# The output from the batch_mcp_flow function, which contains the results of
|
713
|
+
# the tool execution. If an error occurs during processing, it logs the error
|
714
|
+
# and returns None.
|
715
|
+
|
716
|
+
# Raises:
|
717
|
+
# Exception: Logs any exceptions that occur during the execution flow.
|
718
|
+
# """
|
719
|
+
# try:
|
720
|
+
# response = str_to_dict(response)
|
721
|
+
|
722
|
+
# tool_output = batch_mcp_flow(
|
723
|
+
# self.mcp_servers,
|
724
|
+
# function_call=response,
|
725
|
+
# )
|
726
|
+
|
727
|
+
# return tool_output
|
728
|
+
# except Exception as e:
|
729
|
+
# logger.error(f"Error in mcp_execution_flow: {e}")
|
730
|
+
# return None
|
731
|
+
|
732
|
+
# def mcp_tool_handling(self):
|
733
|
+
# """
|
734
|
+
# Handles the retrieval of tool schemas from the MCP servers.
|
735
|
+
|
736
|
+
# This method iterates over the list of MCP servers, retrieves the tool schema
|
737
|
+
# for each server using the mcp_flow_get_tool_schema function, and compiles
|
738
|
+
# these schemas into a list. The resulting list is stored in the
|
739
|
+
# tools_list_dictionary attribute.
|
740
|
+
|
741
|
+
# Returns:
|
742
|
+
# list: A list of tool schemas retrieved from the MCP servers. If an error
|
743
|
+
# occurs during the retrieval process, it logs the error and returns None.
|
744
|
+
|
745
|
+
# Raises:
|
746
|
+
# Exception: Logs any exceptions that occur during the tool handling process.
|
747
|
+
# """
|
748
|
+
# try:
|
749
|
+
# self.tools_list_dictionary = []
|
750
|
+
|
751
|
+
# for mcp_server in self.mcp_servers:
|
752
|
+
# tool_schema = mcp_flow_get_tool_schema(mcp_server)
|
753
|
+
# self.tools_list_dictionary.append(tool_schema)
|
754
|
+
|
755
|
+
# print(self.tools_list_dictionary)
|
756
|
+
# return self.tools_list_dictionary
|
757
|
+
# except Exception as e:
|
758
|
+
# logger.error(f"Error in mcp_tool_handling: {e}")
|
759
|
+
# return None
|
760
760
|
|
761
761
|
def setup_config(self):
|
762
762
|
# The max_loops will be set dynamically if the dynamic_loop
|
@@ -2490,10 +2490,12 @@ class Agent:
|
|
2490
2490
|
**kwargs,
|
2491
2491
|
)
|
2492
2492
|
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2493
|
+
return output
|
2494
|
+
|
2495
|
+
# if self.tools_list_dictionary is not None:
|
2496
|
+
# return str_to_dict(output)
|
2497
|
+
# else:
|
2498
|
+
# return output
|
2497
2499
|
|
2498
2500
|
except ValueError as e:
|
2499
2501
|
self._handle_run_error(e)
|
@@ -176,20 +176,20 @@ tools = [
|
|
176
176
|
"type": "function",
|
177
177
|
"function": {
|
178
178
|
"name": "search_topic",
|
179
|
-
"description": "Conduct
|
179
|
+
"description": "Conduct a thorough search on a specified topic or subtopic, generating a precise array of highly detailed search queries tailored to the input parameters.",
|
180
180
|
"parameters": {
|
181
181
|
"type": "object",
|
182
182
|
"properties": {
|
183
183
|
"depth": {
|
184
184
|
"type": "integer",
|
185
|
-
"description": "Indicates the level of thoroughness for the search. Values range from 1 to 3, where 1
|
185
|
+
"description": "Indicates the level of thoroughness for the search. Values range from 1 to 3, where 1 signifies a superficial search and 3 indicates an in-depth exploration of the topic.",
|
186
186
|
},
|
187
187
|
"detailed_queries": {
|
188
188
|
"type": "array",
|
189
|
-
"description": "An array of
|
189
|
+
"description": "An array of specific search queries generated based on the input query and the specified depth. Each query must be crafted to elicit detailed and relevant information from various sources.",
|
190
190
|
"items": {
|
191
191
|
"type": "string",
|
192
|
-
"description": "Each item in this array
|
192
|
+
"description": "Each item in this array must represent a unique search query targeting a specific aspect of the main topic, ensuring a comprehensive exploration of the subject matter.",
|
193
193
|
},
|
194
194
|
},
|
195
195
|
},
|
swarms/structs/swarm_builder.py
CHANGED
@@ -177,11 +177,6 @@ class AutoSwarmBuilder:
|
|
177
177
|
swarm_type=swarm_type,
|
178
178
|
)
|
179
179
|
|
180
|
-
if not self.api_key:
|
181
|
-
raise ValueError(
|
182
|
-
"OpenAI API key must be provided either through initialization or environment variable"
|
183
|
-
)
|
184
|
-
|
185
180
|
logger.info(
|
186
181
|
"Initialized AutoSwarmBuilder",
|
187
182
|
extra={
|
swarms/telemetry/main.py
CHANGED
@@ -1,18 +1,25 @@
|
|
1
|
+
# Add these imports at the top
|
2
|
+
import asyncio
|
3
|
+
|
4
|
+
|
1
5
|
import datetime
|
2
6
|
import hashlib
|
3
7
|
import platform
|
4
8
|
import socket
|
5
9
|
import subprocess
|
6
|
-
import threading
|
7
10
|
import uuid
|
11
|
+
from concurrent.futures import ThreadPoolExecutor
|
12
|
+
from functools import lru_cache
|
13
|
+
from threading import Lock
|
8
14
|
from typing import Dict
|
9
15
|
|
10
16
|
import aiohttp
|
11
|
-
import httpx
|
12
17
|
import pkg_resources
|
13
18
|
import psutil
|
14
|
-
import requests
|
15
19
|
import toml
|
20
|
+
from requests import Session
|
21
|
+
from requests.adapters import HTTPAdapter
|
22
|
+
from urllib3.util.retry import Retry
|
16
23
|
|
17
24
|
|
18
25
|
# Helper functions
|
@@ -251,92 +258,123 @@ def capture_system_data() -> Dict[str, str]:
|
|
251
258
|
"architecture": platform.architecture()[0],
|
252
259
|
}
|
253
260
|
|
254
|
-
# Get external IP address
|
255
|
-
try:
|
256
|
-
system_data["external_ip"] = requests.get(
|
257
|
-
"https://api.ipify.org"
|
258
|
-
).text
|
259
|
-
except Exception:
|
260
|
-
system_data["external_ip"] = "N/A"
|
261
|
-
|
262
261
|
return system_data
|
263
262
|
except Exception as e:
|
264
263
|
# logger.error("Failed to capture system data: {}", e)
|
265
264
|
print(f"Failed to capture system data: {e}")
|
266
|
-
return {}
|
267
265
|
|
268
266
|
|
269
|
-
def _log_agent_data(data_dict: dict) -> dict | None:
|
270
|
-
"""
|
271
267
|
|
272
|
-
|
273
|
-
|
268
|
+
# Global variables
|
269
|
+
_session = None
|
270
|
+
_session_lock = Lock()
|
271
|
+
_executor = ThreadPoolExecutor(max_workers=10)
|
272
|
+
_aiohttp_session = None
|
273
|
+
|
274
|
+
def get_session() -> Session:
|
275
|
+
"""Thread-safe session getter with optimized connection pooling"""
|
276
|
+
global _session
|
277
|
+
if _session is None:
|
278
|
+
with _session_lock:
|
279
|
+
if _session is None: # Double-check pattern
|
280
|
+
_session = Session()
|
281
|
+
adapter = HTTPAdapter(
|
282
|
+
pool_connections=1000, # Increased pool size
|
283
|
+
pool_maxsize=1000, # Increased max size
|
284
|
+
max_retries=Retry(
|
285
|
+
total=3,
|
286
|
+
backoff_factor=0.1,
|
287
|
+
status_forcelist=[500, 502, 503, 504]
|
288
|
+
),
|
289
|
+
pool_block=False # Non-blocking pool
|
290
|
+
)
|
291
|
+
_session.mount('http://', adapter)
|
292
|
+
_session.mount('https://', adapter)
|
293
|
+
_session.headers.update({
|
294
|
+
"Content-Type": "application/json",
|
295
|
+
"Authorization": "Bearer sk-33979fd9a4e8e6b670090e4900a33dbe7452a15ccc705745f4eca2a70c88ea24",
|
296
|
+
"Connection": "keep-alive" # Enable keep-alive
|
297
|
+
})
|
298
|
+
return _session
|
299
|
+
|
300
|
+
@lru_cache(maxsize=2048, typed=True)
|
301
|
+
def get_user_device_data_cached():
|
302
|
+
"""Cached version with increased cache size"""
|
303
|
+
return get_user_device_data()
|
304
|
+
|
305
|
+
async def get_aiohttp_session():
|
306
|
+
"""Get or create aiohttp session for async requests"""
|
307
|
+
global _aiohttp_session
|
308
|
+
if _aiohttp_session is None or _aiohttp_session.closed:
|
309
|
+
timeout = aiohttp.ClientTimeout(total=10)
|
310
|
+
connector = aiohttp.TCPConnector(
|
311
|
+
limit=1000, # Connection limit
|
312
|
+
ttl_dns_cache=300, # DNS cache TTL
|
313
|
+
use_dns_cache=True, # Enable DNS caching
|
314
|
+
keepalive_timeout=60 # Keep-alive timeout
|
315
|
+
)
|
316
|
+
_aiohttp_session = aiohttp.ClientSession(
|
317
|
+
timeout=timeout,
|
318
|
+
connector=connector,
|
319
|
+
headers={
|
320
|
+
"Content-Type": "application/json",
|
321
|
+
"Authorization": "Bearer sk-33979fd9a4e8e6b670090e4900a33dbe7452a15ccc705745f4eca2a70c88ea24",
|
322
|
+
}
|
323
|
+
)
|
324
|
+
return _aiohttp_session
|
274
325
|
|
275
|
-
|
276
|
-
|
277
|
-
"""
|
326
|
+
async def log_agent_data_async(data_dict: dict):
|
327
|
+
"""Asynchronous version of log_agent_data"""
|
278
328
|
if not data_dict:
|
279
329
|
return None
|
280
330
|
|
281
331
|
url = "https://swarms.world/api/get-agents/log-agents"
|
282
|
-
headers = {
|
283
|
-
"Content-Type": "application/json",
|
284
|
-
"Authorization": "sk-xxx", # replace with actual
|
285
|
-
}
|
286
|
-
|
287
332
|
payload = {
|
288
333
|
"data": data_dict,
|
289
|
-
"system_data":
|
290
|
-
"timestamp": datetime.datetime.now(datetime.
|
334
|
+
"system_data": get_user_device_data_cached(),
|
335
|
+
"timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
291
336
|
}
|
292
337
|
|
338
|
+
session = await get_aiohttp_session()
|
293
339
|
try:
|
294
|
-
with
|
295
|
-
response
|
296
|
-
|
297
|
-
return response.json()
|
340
|
+
async with session.post(url, json=payload) as response:
|
341
|
+
if response.status == 200:
|
342
|
+
return await response.json()
|
298
343
|
except Exception:
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
def log_agent_data(data_dict: dict) -> None:
|
303
|
-
"""Runs log_agent_data in a separate thread (detached from main thread)."""
|
304
|
-
threading.Thread(
|
305
|
-
target=_log_agent_data, args=(data_dict,), daemon=True
|
306
|
-
).start()
|
307
|
-
|
344
|
+
return None
|
308
345
|
|
309
|
-
|
346
|
+
def log_agent_data(data_dict: dict):
|
310
347
|
"""
|
311
|
-
|
312
|
-
Args:
|
313
|
-
data_dict (dict): The dictionary containing the agent data to be logged.
|
314
|
-
|
315
|
-
Returns:
|
316
|
-
dict | None: The JSON response from the server if successful, otherwise None.
|
348
|
+
Enhanced log_agent_data with both sync and async capabilities
|
317
349
|
"""
|
318
350
|
if not data_dict:
|
319
|
-
return None
|
351
|
+
return None
|
320
352
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
353
|
+
# If running in an event loop, use async version
|
354
|
+
try:
|
355
|
+
loop = asyncio.get_event_loop()
|
356
|
+
if loop.is_running():
|
357
|
+
return asyncio.create_task(log_agent_data_async(data_dict))
|
358
|
+
except RuntimeError:
|
359
|
+
pass
|
326
360
|
|
327
|
-
|
361
|
+
# Fallback to optimized sync version
|
362
|
+
url = "https://swarms.world/api/get-agents/log-agents"
|
363
|
+
payload = {
|
328
364
|
"data": data_dict,
|
329
|
-
"system_data":
|
330
|
-
"timestamp": datetime.datetime.now(datetime.
|
365
|
+
"system_data": get_user_device_data_cached(),
|
366
|
+
"timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
331
367
|
}
|
332
368
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
369
|
+
try:
|
370
|
+
session = get_session()
|
371
|
+
response = session.post(
|
372
|
+
url,
|
373
|
+
json=payload,
|
374
|
+
timeout=10,
|
375
|
+
stream=False # Disable streaming for faster response
|
376
|
+
)
|
377
|
+
if response.ok and response.text.strip():
|
378
|
+
return response.json()
|
379
|
+
except Exception:
|
380
|
+
return None
|
swarms/utils/litellm_wrapper.py
CHANGED
@@ -27,6 +27,12 @@ except ImportError:
|
|
27
27
|
litellm.ssl_verify = False
|
28
28
|
|
29
29
|
|
30
|
+
class LiteLLMException(Exception):
|
31
|
+
"""
|
32
|
+
Exception for LiteLLM.
|
33
|
+
"""
|
34
|
+
|
35
|
+
|
30
36
|
def get_audio_base64(audio_source: str) -> str:
|
31
37
|
"""
|
32
38
|
Convert audio from a given source to a base64 encoded string.
|
@@ -79,6 +85,7 @@ class LiteLLM:
|
|
79
85
|
audio: str = None,
|
80
86
|
retries: int = 3,
|
81
87
|
verbose: bool = False,
|
88
|
+
caching: bool = False,
|
82
89
|
*args,
|
83
90
|
**kwargs,
|
84
91
|
):
|
@@ -102,6 +109,7 @@ class LiteLLM:
|
|
102
109
|
self.tools_list_dictionary = tools_list_dictionary
|
103
110
|
self.tool_choice = tool_choice
|
104
111
|
self.parallel_tool_calls = parallel_tool_calls
|
112
|
+
self.caching = caching
|
105
113
|
self.modalities = []
|
106
114
|
self._cached_messages = {} # Cache for prepared messages
|
107
115
|
self.messages = [] # Initialize messages list
|
@@ -253,6 +261,7 @@ class LiteLLM:
|
|
253
261
|
"stream": self.stream,
|
254
262
|
"temperature": self.temperature,
|
255
263
|
"max_tokens": self.max_tokens,
|
264
|
+
"caching": self.caching,
|
256
265
|
**kwargs,
|
257
266
|
}
|
258
267
|
|
@@ -283,10 +292,13 @@ class LiteLLM:
|
|
283
292
|
return response.choices[0].message.content
|
284
293
|
|
285
294
|
# Standard completion
|
286
|
-
|
287
|
-
|
295
|
+
if self.stream:
|
296
|
+
return completion(**completion_params)
|
297
|
+
else:
|
298
|
+
response = completion(**completion_params)
|
299
|
+
return response.choices[0].message.content
|
288
300
|
|
289
|
-
except
|
301
|
+
except LiteLLMException as error:
|
290
302
|
logger.error(f"Error in LiteLLM run: {str(error)}")
|
291
303
|
if "rate_limit" in str(error).lower():
|
292
304
|
logger.warning(
|
@@ -355,16 +367,18 @@ class LiteLLM:
|
|
355
367
|
|
356
368
|
# Standard completion
|
357
369
|
response = await acompletion(**completion_params)
|
358
|
-
|
370
|
+
|
371
|
+
print(response)
|
372
|
+
return response
|
359
373
|
|
360
374
|
except Exception as error:
|
361
375
|
logger.error(f"Error in LiteLLM arun: {str(error)}")
|
362
|
-
if "rate_limit" in str(error).lower():
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
376
|
+
# if "rate_limit" in str(error).lower():
|
377
|
+
# logger.warning(
|
378
|
+
# "Rate limit hit, retrying with exponential backoff..."
|
379
|
+
# )
|
380
|
+
# await asyncio.sleep(2) # Use async sleep
|
381
|
+
# return await self.arun(task, *args, **kwargs)
|
368
382
|
raise error
|
369
383
|
|
370
384
|
async def _process_batch(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: swarms
|
3
|
-
Version: 7.
|
3
|
+
Version: 7.7.0
|
4
4
|
Summary: Swarms - TGSC
|
5
5
|
Home-page: https://github.com/kyegomez/swarms
|
6
6
|
License: MIT
|
@@ -23,7 +23,6 @@ Requires-Dist: docstring_parser (==0.16)
|
|
23
23
|
Requires-Dist: httpx
|
24
24
|
Requires-Dist: litellm
|
25
25
|
Requires-Dist: loguru
|
26
|
-
Requires-Dist: mcp
|
27
26
|
Requires-Dist: networkx
|
28
27
|
Requires-Dist: numpy
|
29
28
|
Requires-Dist: psutil
|
@@ -1,4 +1,4 @@
|
|
1
|
-
swarms/__init__.py,sha256=
|
1
|
+
swarms/__init__.py,sha256=YxGdUrWHekSiNneyQUM7Yrdf6pCIy2-xgIzhocZY0Ek,561
|
2
2
|
swarms/agents/__init__.py,sha256=ebUrX9rMccQokq5XthgnzGDMISn8EyQyOIOwVAlLs1E,1190
|
3
3
|
swarms/agents/agent_judge.py,sha256=xT242CX5mV64cq2B-3RGkuEHiV5aD04P_Zq8_s64iMQ,3967
|
4
4
|
swarms/agents/agent_print.py,sha256=SXqWA2ZzXwRFdv8hkuYwOPMTasvaGTG6U29413qRCAA,918
|
@@ -82,7 +82,7 @@ swarms/schemas/agent_input_schema.py,sha256=qhPyThMx2on91yG9mzNdP_08GpMh1IRDHDwF
|
|
82
82
|
swarms/schemas/agent_step_schemas.py,sha256=a14gb58vR0xOwB_fwSJQbN6yb9HddEaT30E6hUrzEQA,2573
|
83
83
|
swarms/schemas/base_schemas.py,sha256=UvBLVWg2qRen4tK5GJz50v42SiX95EQ5qK7hfyAHTEU,3267
|
84
84
|
swarms/structs/__init__.py,sha256=gzD4B2KvKsS_WU7OOdJUlOwjAefTdhBPnBgsVz3RYCY,4247
|
85
|
-
swarms/structs/agent.py,sha256=
|
85
|
+
swarms/structs/agent.py,sha256=LcxNeZDzZ_Bbgv6ebkzfqAJ3J5yIf7dJP0_Tn-BW63o,96853
|
86
86
|
swarms/structs/agent_builder.py,sha256=tYNpfO4_8cgfMHfgA5DAOWffHnt70p6CLt59esqfVCY,12133
|
87
87
|
swarms/structs/agent_registry.py,sha256=il507cO1NF-d4ChyANVLuWrN8bXsEAi8_7bLJ_sTU6A,12112
|
88
88
|
swarms/structs/agent_roles.py,sha256=8XEw6RjOOZelaZaWt4gXaYQm5WMLEhSO7W6Z8sQjmFg,582
|
@@ -98,7 +98,7 @@ swarms/structs/concurrent_workflow.py,sha256=d1_slbALpxrdEGzZffUSAcEbONW0kc7fyTp
|
|
98
98
|
swarms/structs/conversation.py,sha256=h4A4l9Mcucw1v-N0mOA4keZ9vf-l3t-kBINZlk_CrOA,18392
|
99
99
|
swarms/structs/csv_to_agent.py,sha256=ug9JqQFPguXeU9JQpSUXuVtOpHYdJhlpKJUJBovo694,9443
|
100
100
|
swarms/structs/de_hallucination_swarm.py,sha256=9cC0rSSXGwYu6SRDwpeMbCcQ40C1WI1RE9SNapKRLOQ,10309
|
101
|
-
swarms/structs/deep_research_swarm.py,sha256=
|
101
|
+
swarms/structs/deep_research_swarm.py,sha256=axhzSK43-TViQJntt2Gz2AUhAc6zoBPzj9weRmQ8yE8,16733
|
102
102
|
swarms/structs/dynamic_conversational_swarm.py,sha256=n_d1jDCzBwiGb0QjJpW_MlXxqEkhGEhC1ttaebH7f3Q,8098
|
103
103
|
swarms/structs/graph_swarm.py,sha256=HPHlLWwdSPSe4o-I06ZOIgtBg72a06llEnv8-aglf3Q,20962
|
104
104
|
swarms/structs/graph_workflow.py,sha256=TAaUG_J3898hhghPOp0WEAV3Zf0in6s48ZSVbSTX-vQ,8629
|
@@ -126,7 +126,7 @@ swarms/structs/sequential_workflow.py,sha256=5jxHP-a2CzdclSXIrVWkQKXBr01VzrgOBIe
|
|
126
126
|
swarms/structs/spreadsheet_swarm.py,sha256=ToX56QJjlm_nnC3MYppvKC_NTr9Zy_orkBzfxNLdwbA,14845
|
127
127
|
swarms/structs/stopping_conditions.py,sha256=Z0Jx0U2feAfQfuVV_IJGgal62DoVsGPN8K6HkkqB_bM,484
|
128
128
|
swarms/structs/swarm_arange.py,sha256=6fexCPsXRgdLbpY0p9rp_REipeXzsbv1_GOtD9B4HaI,15179
|
129
|
-
swarms/structs/swarm_builder.py,sha256=
|
129
|
+
swarms/structs/swarm_builder.py,sha256=TqxD4bIE11gPZBqi_awXem5-svnQ-IJVAhRquX0ErQg,13054
|
130
130
|
swarms/structs/swarm_eval.py,sha256=148E2R2zaCmt_LZYx15nmdFjybXHiQ2CZbl6pk77jNs,11635
|
131
131
|
swarms/structs/swarm_id_generator.py,sha256=Wly7AtGM9e6VgzhYmfg8_gSOdxAdsOvWHJFK81cpQNQ,68
|
132
132
|
swarms/structs/swarm_load_balancer.py,sha256=pUCc5FEBcuJ_GmOFeTWBPfXlUdiTOjYcJqVq_ymGHlM,11374
|
@@ -139,10 +139,9 @@ swarms/structs/talk_hier.py,sha256=npyEuL52SCgQmMynIvGjfatNqOz4toq0EyhEtSNmQhQ,2
|
|
139
139
|
swarms/structs/tree_swarm.py,sha256=AnIxrt0KhWxAQN8uGjfCcOq-XCmsuTJiH8Ex4mXy8V8,12500
|
140
140
|
swarms/structs/utils.py,sha256=Mo6wHQYOB8baWZUKnAJN5Dsgubpo81umNwJIEDitb2A,1873
|
141
141
|
swarms/structs/various_alt_swarms.py,sha256=qdBuOF31UjatlKRu-9bxwyRQzIjohRhTv_63YoUeYEY,27866
|
142
|
-
swarms/structs/workspace_manager.py,sha256=t0OgUP9dDU7xS6N3mAT2PbXvjHTsUK3nf2mxppcfZ70,5473
|
143
142
|
swarms/telemetry/__init__.py,sha256=yibtkHEbQRPUv6ir1FhDHlAO_3nwKJPQH4LjzBC2AuQ,661
|
144
143
|
swarms/telemetry/bootup.py,sha256=0leCNCy5rhzL19EsOsqHWSDI85KVcWO6_5hLDS0h4sY,1155
|
145
|
-
swarms/telemetry/main.py,sha256=
|
144
|
+
swarms/telemetry/main.py,sha256=w_6ud1onZpBgqIF-173GEesXLLj4iyvzTTjhz7pFUqc,11096
|
146
145
|
swarms/tools/__init__.py,sha256=pqIMcRQr4gtoNdbyI1N5k4upkYSBMxACJbxfB9yrV4c,1493
|
147
146
|
swarms/tools/base_tool.py,sha256=BiBCFHin8AyZO3FYOGA-n3M2o-F36xUeIBUiybnZYjI,15179
|
148
147
|
swarms/tools/cohere_func_call_schema.py,sha256=XJ6_yBMXCrV9KjN7v9Bk1iFj69TRlGIWYKsUTA1oGiQ,600
|
@@ -172,19 +171,18 @@ swarms/utils/formatter.py,sha256=YykmcuWXkxvQ7a2Vq6OzWuqUDiIwro6VrtSt4ITbXcU,419
|
|
172
171
|
swarms/utils/function_caller_model.py,sha256=ZfgCMzOizNnuZipYLclTziECNHszH9p8RQcUq7VNr4Q,4156
|
173
172
|
swarms/utils/history_output_formatter.py,sha256=WHcd0xhSNRDKakXtkCjv0nW1NF-GM9SYcey3RrN5gl8,778
|
174
173
|
swarms/utils/litellm_tokenizer.py,sha256=0AAj4NffBe2eHii_3_5SpQAhSiBbunJR8MzaBTIm7hg,484
|
175
|
-
swarms/utils/litellm_wrapper.py,sha256=
|
174
|
+
swarms/utils/litellm_wrapper.py,sha256=mhlG52rffI-vNYbEnHsuYzraFbtsnx84-jb7WMZLReA,14507
|
176
175
|
swarms/utils/loguru_logger.py,sha256=hIoSK3NHLpe7eAmjHRURrEYzNXYC2gbR7_Vv63Yaydk,685
|
177
176
|
swarms/utils/markdown_message.py,sha256=RThHNnMf6ZLTlYK4vKn3yuewChaxWAYAWb0Xm_pTyIU,652
|
178
177
|
swarms/utils/parse_code.py,sha256=XFOLymbdP3HzMZuqsj7pwUyisvUmTm0ev9iThR_ambI,1987
|
179
178
|
swarms/utils/pdf_to_text.py,sha256=nkySOS_sJ4Jf4RP5SoDpMB5WfjJ_GGc5z8gJfn2cxOM,1311
|
180
179
|
swarms/utils/str_to_dict.py,sha256=T3Jsdjz87WIlkSo7jAW6BB80sv0Ns49WT1qXlOrdEoE,874
|
181
|
-
swarms/utils/swarm_reliability_checks.py,sha256=MsgUULt3HYg72D0HifZNmtCyJYpLA2UDA2wQixI-NbA,2562
|
182
180
|
swarms/utils/try_except_wrapper.py,sha256=appEGu9Afy3TmdkNNXUgQ9yU9lj2j0uNkIoW0JhVzzY,3917
|
183
181
|
swarms/utils/visualizer.py,sha256=0ylohEk62MAS6iPRaDOV03m9qo2k5J56tWlKJk_46p4,16927
|
184
182
|
swarms/utils/vllm_wrapper.py,sha256=OIGnU9Vf81vE_hul1FK-xEhChFK8fxqZX6-fhQeW22c,4987
|
185
183
|
swarms/utils/wrapper_clusterop.py,sha256=PMSCVM7ZT1vgj1D_MYAe835RR3SMLYxA-si2JS02yNQ,4220
|
186
|
-
swarms-7.
|
187
|
-
swarms-7.
|
188
|
-
swarms-7.
|
189
|
-
swarms-7.
|
190
|
-
swarms-7.
|
184
|
+
swarms-7.7.0.dist-info/LICENSE,sha256=jwRtEmTWjLrEsvFB6QFdYs2cEeZPRMdj-UMOFkPF8_0,11363
|
185
|
+
swarms-7.7.0.dist-info/METADATA,sha256=AjkFhCgUgocVqF_3D_HR8IA30JnY2ckwUg3ywrBbvE0,104909
|
186
|
+
swarms-7.7.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
187
|
+
swarms-7.7.0.dist-info/entry_points.txt,sha256=2K0rTtfO1X1WaO-waJlXIKw5Voa_EpAL_yU0HXE2Jgc,47
|
188
|
+
swarms-7.7.0.dist-info/RECORD,,
|
@@ -1,178 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Optional
|
4
|
-
from swarms.utils.loguru_logger import initialize_logger
|
5
|
-
|
6
|
-
|
7
|
-
logger = initialize_logger("workspace-manager")
|
8
|
-
|
9
|
-
|
10
|
-
class WorkspaceManager:
|
11
|
-
"""
|
12
|
-
Manages the workspace directory and settings for the application.
|
13
|
-
This class is responsible for setting up the workspace directory, logging configuration,
|
14
|
-
and retrieving environment variables for telemetry and API key.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def __init__(
|
18
|
-
self,
|
19
|
-
workspace_dir: Optional[str] = "agent_workspace",
|
20
|
-
use_telemetry: Optional[bool] = True,
|
21
|
-
api_key: Optional[str] = None,
|
22
|
-
):
|
23
|
-
"""
|
24
|
-
Initializes the WorkspaceManager with optional parameters for workspace directory,
|
25
|
-
telemetry usage, and API key.
|
26
|
-
|
27
|
-
Args:
|
28
|
-
workspace_dir (Optional[str]): The path to the workspace directory.
|
29
|
-
use_telemetry (Optional[bool]): A flag indicating whether to use telemetry.
|
30
|
-
api_key (Optional[str]): The API key for the application.
|
31
|
-
"""
|
32
|
-
self.workspace_dir = workspace_dir
|
33
|
-
self.use_telemetry = use_telemetry
|
34
|
-
self.api_key = api_key
|
35
|
-
|
36
|
-
def _create_env_file(self, env_file_path: Path) -> None:
|
37
|
-
"""
|
38
|
-
Create a new .env file with default WORKSPACE_DIR.
|
39
|
-
|
40
|
-
Args:
|
41
|
-
env_file_path (Path): The path to the .env file.
|
42
|
-
"""
|
43
|
-
with env_file_path.open("w") as file:
|
44
|
-
file.write(f"WORKSPACE_DIR={self.workspace_dir}\n")
|
45
|
-
logger.info(
|
46
|
-
"Created a new .env file with default WORKSPACE_DIR."
|
47
|
-
)
|
48
|
-
|
49
|
-
def _append_to_env_file(self, env_file_path: Path) -> None:
|
50
|
-
"""
|
51
|
-
Append WORKSPACE_DIR to .env if it doesn't exist.
|
52
|
-
|
53
|
-
Args:
|
54
|
-
env_file_path (Path): The path to the .env file.
|
55
|
-
"""
|
56
|
-
with env_file_path.open("r+") as file:
|
57
|
-
content = file.read()
|
58
|
-
if "WORKSPACE_DIR" not in content:
|
59
|
-
file.seek(0, os.SEEK_END)
|
60
|
-
file.write(f"WORKSPACE_DIR={self.workspace_dir}\n")
|
61
|
-
logger.info("Appended WORKSPACE_DIR to .env file.")
|
62
|
-
|
63
|
-
def _get_workspace_dir(
|
64
|
-
self, workspace_dir: Optional[str] = None
|
65
|
-
) -> str:
|
66
|
-
"""
|
67
|
-
Get the workspace directory from environment variable or default.
|
68
|
-
|
69
|
-
Args:
|
70
|
-
workspace_dir (Optional[str]): The path to the workspace directory.
|
71
|
-
|
72
|
-
Returns:
|
73
|
-
str: The path to the workspace directory.
|
74
|
-
"""
|
75
|
-
return workspace_dir or os.getenv(
|
76
|
-
"WORKSPACE_DIR", "agent_workspace"
|
77
|
-
)
|
78
|
-
|
79
|
-
def _get_telemetry_status(
|
80
|
-
self, use_telemetry: Optional[bool] = None
|
81
|
-
) -> bool:
|
82
|
-
"""
|
83
|
-
Get telemetry status from environment variable or default.
|
84
|
-
|
85
|
-
Args:
|
86
|
-
use_telemetry (Optional[bool]): A flag indicating whether to use telemetry.
|
87
|
-
|
88
|
-
Returns:
|
89
|
-
bool: The status of telemetry usage.
|
90
|
-
"""
|
91
|
-
return (
|
92
|
-
use_telemetry
|
93
|
-
if use_telemetry is not None
|
94
|
-
else os.getenv("USE_TELEMETRY", "true").lower() == "true"
|
95
|
-
)
|
96
|
-
|
97
|
-
def _get_api_key(
|
98
|
-
self, api_key: Optional[str] = None
|
99
|
-
) -> Optional[str]:
|
100
|
-
"""
|
101
|
-
Get API key from environment variable or default.
|
102
|
-
|
103
|
-
Args:
|
104
|
-
api_key (Optional[str]): The API key for the application.
|
105
|
-
|
106
|
-
Returns:
|
107
|
-
Optional[str]: The API key or None if not set.
|
108
|
-
"""
|
109
|
-
return api_key or os.getenv("SWARMS_API_KEY")
|
110
|
-
|
111
|
-
def _init_workspace(self) -> None:
|
112
|
-
"""
|
113
|
-
Initialize the workspace directory if it doesn't exist.
|
114
|
-
"""
|
115
|
-
if not self.workspace_path.exists():
|
116
|
-
self.workspace_path.mkdir(parents=True, exist_ok=True)
|
117
|
-
logger.info("Workspace directory initialized.")
|
118
|
-
|
119
|
-
@property
|
120
|
-
def get_workspace_path(self) -> Path:
|
121
|
-
"""
|
122
|
-
Get the workspace path.
|
123
|
-
|
124
|
-
Returns:
|
125
|
-
Path: The path to the workspace directory.
|
126
|
-
"""
|
127
|
-
return self.workspace_path
|
128
|
-
|
129
|
-
@property
|
130
|
-
def get_telemetry_status(self) -> bool:
|
131
|
-
"""
|
132
|
-
Get telemetry status.
|
133
|
-
|
134
|
-
Returns:
|
135
|
-
bool: The status of telemetry usage.
|
136
|
-
"""
|
137
|
-
return self.use_telemetry
|
138
|
-
|
139
|
-
@property
|
140
|
-
def get_api_key(self) -> Optional[str]:
|
141
|
-
"""
|
142
|
-
Get API key.
|
143
|
-
|
144
|
-
Returns:
|
145
|
-
Optional[str]: The API key or None if not set.
|
146
|
-
"""
|
147
|
-
return self.api_key
|
148
|
-
|
149
|
-
def run(self) -> None:
|
150
|
-
try:
|
151
|
-
# Check if .env file exists and create it if it doesn't
|
152
|
-
env_file_path = Path(".env")
|
153
|
-
|
154
|
-
# If the .env file doesn't exist, create it
|
155
|
-
if not env_file_path.exists():
|
156
|
-
self._create_env_file(env_file_path)
|
157
|
-
else:
|
158
|
-
# Append WORKSPACE_DIR to .env if it doesn't exist
|
159
|
-
self._append_to_env_file(env_file_path)
|
160
|
-
|
161
|
-
# Set workspace directory
|
162
|
-
self.workspace_dir = self._get_workspace_dir(
|
163
|
-
self.workspace_dir
|
164
|
-
)
|
165
|
-
self.workspace_path = Path(self.workspace_dir)
|
166
|
-
|
167
|
-
# Set telemetry preference
|
168
|
-
self.use_telemetry = self._get_telemetry_status(
|
169
|
-
self.use_telemetry
|
170
|
-
)
|
171
|
-
|
172
|
-
# Set API key
|
173
|
-
self.api_key = self._get_api_key(self.api_key)
|
174
|
-
|
175
|
-
# Initialize workspace
|
176
|
-
self._init_workspace()
|
177
|
-
except Exception as e:
|
178
|
-
logger.error(f"Error initializing WorkspaceManager: {e}")
|
@@ -1,81 +0,0 @@
|
|
1
|
-
from typing import Callable, List, Optional, Union
|
2
|
-
|
3
|
-
from swarms.structs.agent import Agent
|
4
|
-
from swarms.utils.loguru_logger import initialize_logger
|
5
|
-
|
6
|
-
logger = initialize_logger(log_folder="swarm_reliability_checks")
|
7
|
-
|
8
|
-
|
9
|
-
def reliability_check(
|
10
|
-
agents: List[Union[Agent, Callable]],
|
11
|
-
max_loops: int,
|
12
|
-
name: Optional[str] = None,
|
13
|
-
description: Optional[str] = None,
|
14
|
-
flow: Optional[str] = None,
|
15
|
-
) -> None:
|
16
|
-
"""
|
17
|
-
Performs reliability checks on swarm configuration parameters.
|
18
|
-
|
19
|
-
Args:
|
20
|
-
agents: List of Agent objects or callables that will be executed
|
21
|
-
max_loops: Maximum number of execution loops
|
22
|
-
name: Name identifier for the swarm
|
23
|
-
description: Description of the swarm's purpose
|
24
|
-
|
25
|
-
Raises:
|
26
|
-
ValueError: If any parameters fail validation checks
|
27
|
-
TypeError: If parameters are of incorrect type
|
28
|
-
"""
|
29
|
-
logger.info("Initializing swarm reliability checks")
|
30
|
-
|
31
|
-
# Type checking
|
32
|
-
if not isinstance(agents, list):
|
33
|
-
raise TypeError("agents parameter must be a list")
|
34
|
-
|
35
|
-
if not isinstance(max_loops, int):
|
36
|
-
raise TypeError("max_loops must be an integer")
|
37
|
-
|
38
|
-
# Validate agents
|
39
|
-
if not agents:
|
40
|
-
raise ValueError("Agents list cannot be empty")
|
41
|
-
|
42
|
-
for i, agent in enumerate(agents):
|
43
|
-
if not isinstance(agent, (Agent, Callable)):
|
44
|
-
raise TypeError(
|
45
|
-
f"Agent at index {i} must be an Agent instance or Callable"
|
46
|
-
)
|
47
|
-
|
48
|
-
# Validate max_loops
|
49
|
-
if max_loops <= 0:
|
50
|
-
raise ValueError("max_loops must be greater than 0")
|
51
|
-
|
52
|
-
if max_loops > 1000:
|
53
|
-
logger.warning(
|
54
|
-
"Large max_loops value detected. This may impact performance."
|
55
|
-
)
|
56
|
-
|
57
|
-
# Validate name
|
58
|
-
if name is None:
|
59
|
-
raise ValueError("name parameter is required")
|
60
|
-
if not isinstance(name, str):
|
61
|
-
raise TypeError("name must be a string")
|
62
|
-
if len(name.strip()) == 0:
|
63
|
-
raise ValueError("name cannot be empty or just whitespace")
|
64
|
-
|
65
|
-
# Validate description
|
66
|
-
if description is None:
|
67
|
-
raise ValueError("description parameter is required")
|
68
|
-
if not isinstance(description, str):
|
69
|
-
raise TypeError("description must be a string")
|
70
|
-
if len(description.strip()) == 0:
|
71
|
-
raise ValueError(
|
72
|
-
"description cannot be empty or just whitespace"
|
73
|
-
)
|
74
|
-
|
75
|
-
# Validate flow
|
76
|
-
if flow is None:
|
77
|
-
raise ValueError("flow parameter is required")
|
78
|
-
if not isinstance(flow, str):
|
79
|
-
raise TypeError("flow must be a string")
|
80
|
-
|
81
|
-
logger.info("All reliability checks passed successfully")
|
File without changes
|
File without changes
|
File without changes
|