swarms 7.6.4__py3-none-any.whl → 7.6.6__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/structs/__init__.py +1 -3
- swarms/structs/agent.py +167 -38
- swarms/tools/mcp_integration.py +321 -483
- swarms/utils/litellm_wrapper.py +172 -92
- swarms/utils/vllm_wrapper.py +146 -0
- {swarms-7.6.4.dist-info → swarms-7.6.6.dist-info}/METADATA +2 -1
- {swarms-7.6.4.dist-info → swarms-7.6.6.dist-info}/RECORD +10 -10
- swarms/structs/auto_swarm.py +0 -229
- {swarms-7.6.4.dist-info → swarms-7.6.6.dist-info}/LICENSE +0 -0
- {swarms-7.6.4.dist-info → swarms-7.6.6.dist-info}/WHEEL +0 -0
- {swarms-7.6.4.dist-info → swarms-7.6.6.dist-info}/entry_points.txt +0 -0
swarms/structs/__init__.py
CHANGED
@@ -2,7 +2,7 @@ from swarms.structs.agent import Agent
|
|
2
2
|
from swarms.structs.agent_builder import AgentsBuilder
|
3
3
|
from swarms.structs.agents_available import showcase_available_agents
|
4
4
|
from swarms.structs.async_workflow import AsyncWorkflow
|
5
|
-
from
|
5
|
+
from experimental.auto_swarm import AutoSwarm, AutoSwarmRouter
|
6
6
|
from swarms.structs.base_structure import BaseStructure
|
7
7
|
from swarms.structs.base_swarm import BaseSwarm
|
8
8
|
from swarms.structs.base_workflow import BaseWorkflow
|
@@ -85,8 +85,6 @@ from swarms.structs.swarming_architectures import (
|
|
85
85
|
__all__ = [
|
86
86
|
"Agent",
|
87
87
|
"AsyncWorkflow",
|
88
|
-
"AutoSwarm",
|
89
|
-
"AutoSwarmRouter",
|
90
88
|
"BaseStructure",
|
91
89
|
"BaseSwarm",
|
92
90
|
"BaseWorkflow",
|
swarms/structs/agent.py
CHANGED
@@ -46,6 +46,11 @@ 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
|
+
from swarms.tools.mcp_integration import (
|
50
|
+
MCPServerSseParams,
|
51
|
+
batch_mcp_flow,
|
52
|
+
mcp_flow_get_tool_schema,
|
53
|
+
)
|
49
54
|
from swarms.tools.tool_parse_exec import parse_and_execute_json
|
50
55
|
from swarms.utils.any_to_str import any_to_str
|
51
56
|
from swarms.utils.data_to_text import data_to_text
|
@@ -55,6 +60,7 @@ from swarms.utils.history_output_formatter import (
|
|
55
60
|
history_output_formatter,
|
56
61
|
)
|
57
62
|
from swarms.utils.litellm_tokenizer import count_tokens
|
63
|
+
from swarms.utils.litellm_wrapper import LiteLLM
|
58
64
|
from swarms.utils.pdf_to_text import pdf_to_text
|
59
65
|
from swarms.utils.str_to_dict import str_to_dict
|
60
66
|
|
@@ -98,6 +104,51 @@ agent_output_type = Literal[
|
|
98
104
|
ToolUsageType = Union[BaseModel, Dict[str, Any]]
|
99
105
|
|
100
106
|
|
107
|
+
# Agent Exceptions
|
108
|
+
|
109
|
+
|
110
|
+
class AgentError(Exception):
|
111
|
+
"""Base class for all agent-related exceptions."""
|
112
|
+
|
113
|
+
pass
|
114
|
+
|
115
|
+
|
116
|
+
class AgentInitializationError(AgentError):
|
117
|
+
"""Exception raised when the agent fails to initialize properly. Please check the configuration and parameters."""
|
118
|
+
|
119
|
+
pass
|
120
|
+
|
121
|
+
|
122
|
+
class AgentRunError(AgentError):
|
123
|
+
"""Exception raised when the agent encounters an error during execution. Ensure that the task and environment are set up correctly."""
|
124
|
+
|
125
|
+
pass
|
126
|
+
|
127
|
+
|
128
|
+
class AgentLLMError(AgentError):
|
129
|
+
"""Exception raised when there is an issue with the language model (LLM). Verify the model's availability and compatibility."""
|
130
|
+
|
131
|
+
pass
|
132
|
+
|
133
|
+
|
134
|
+
class AgentToolError(AgentError):
|
135
|
+
"""Exception raised when the agent fails to utilize a tool. Check the tool's configuration and availability."""
|
136
|
+
|
137
|
+
pass
|
138
|
+
|
139
|
+
|
140
|
+
class AgentMemoryError(AgentError):
|
141
|
+
"""Exception raised when the agent encounters a memory-related issue. Ensure that memory resources are properly allocated and accessible."""
|
142
|
+
|
143
|
+
pass
|
144
|
+
|
145
|
+
|
146
|
+
class AgentLLMInitializationError(AgentError):
|
147
|
+
"""Exception raised when the LLM fails to initialize properly. Please check the configuration and parameters."""
|
148
|
+
|
149
|
+
pass
|
150
|
+
|
151
|
+
|
101
152
|
# [FEAT][AGENT]
|
102
153
|
class Agent:
|
103
154
|
"""
|
@@ -352,6 +403,7 @@ class Agent:
|
|
352
403
|
role: agent_roles = "worker",
|
353
404
|
no_print: bool = False,
|
354
405
|
tools_list_dictionary: Optional[List[Dict[str, Any]]] = None,
|
406
|
+
mcp_servers: List[MCPServerSseParams] = [],
|
355
407
|
*args,
|
356
408
|
**kwargs,
|
357
409
|
):
|
@@ -471,6 +523,13 @@ class Agent:
|
|
471
523
|
self.role = role
|
472
524
|
self.no_print = no_print
|
473
525
|
self.tools_list_dictionary = tools_list_dictionary
|
526
|
+
self.mcp_servers = mcp_servers
|
527
|
+
self._cached_llm = (
|
528
|
+
None # Add this line to cache the LLM instance
|
529
|
+
)
|
530
|
+
self._default_model = (
|
531
|
+
"gpt-4o-mini" # Move default model name here
|
532
|
+
)
|
474
533
|
|
475
534
|
if (
|
476
535
|
self.agent_name is not None
|
@@ -584,51 +643,119 @@ class Agent:
|
|
584
643
|
if self.llm is None:
|
585
644
|
self.llm = self.llm_handling()
|
586
645
|
|
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
|
+
|
587
652
|
def llm_handling(self):
|
588
|
-
|
653
|
+
# Use cached instance if available
|
654
|
+
if self._cached_llm is not None:
|
655
|
+
return self._cached_llm
|
589
656
|
|
590
657
|
if self.model_name is None:
|
591
|
-
# raise ValueError("Model name cannot be None")
|
592
658
|
logger.warning(
|
593
|
-
"Model name is not provided, using
|
659
|
+
f"Model name is not provided, using {self._default_model}. You can configure any model from litellm if desired."
|
594
660
|
)
|
595
|
-
self.model_name =
|
661
|
+
self.model_name = self._default_model
|
596
662
|
|
597
663
|
try:
|
664
|
+
# Simplify initialization logic
|
665
|
+
common_args = {
|
666
|
+
"model_name": self.model_name,
|
667
|
+
"temperature": self.temperature,
|
668
|
+
"max_tokens": self.max_tokens,
|
669
|
+
"system_prompt": self.system_prompt,
|
670
|
+
}
|
671
|
+
|
598
672
|
if self.llm_args is not None:
|
599
|
-
|
600
|
-
|
673
|
+
self._cached_llm = LiteLLM(
|
674
|
+
**{**common_args, **self.llm_args}
|
601
675
|
)
|
602
676
|
elif self.tools_list_dictionary is not None:
|
603
|
-
|
604
|
-
|
605
|
-
self.tools_list_dictionary
|
606
|
-
)
|
607
|
-
|
608
|
-
if length_of_tools_list_dictionary > 0:
|
609
|
-
|
610
|
-
parallel_tool_calls = True
|
611
|
-
|
612
|
-
llm = LiteLLM(
|
613
|
-
model_name=self.model_name,
|
614
|
-
temperature=self.temperature,
|
615
|
-
max_tokens=self.max_tokens,
|
616
|
-
system_prompt=self.system_prompt,
|
677
|
+
self._cached_llm = LiteLLM(
|
678
|
+
**common_args,
|
617
679
|
tools_list_dictionary=self.tools_list_dictionary,
|
618
680
|
tool_choice="auto",
|
619
|
-
parallel_tool_calls=
|
681
|
+
parallel_tool_calls=len(
|
682
|
+
self.tools_list_dictionary
|
683
|
+
)
|
684
|
+
> 1,
|
620
685
|
)
|
621
686
|
else:
|
622
|
-
|
623
|
-
|
624
|
-
temperature=self.temperature,
|
625
|
-
max_tokens=self.max_tokens,
|
626
|
-
system_prompt=self.system_prompt,
|
627
|
-
stream=self.streaming_on,
|
687
|
+
self._cached_llm = LiteLLM(
|
688
|
+
**common_args, stream=self.streaming_on
|
628
689
|
)
|
629
|
-
|
690
|
+
|
691
|
+
return self._cached_llm
|
692
|
+
except AgentLLMInitializationError as e:
|
693
|
+
logger.error(
|
694
|
+
f"Error in llm_handling: {e} Your current configuration is not supported. Please check the configuration and parameters."
|
695
|
+
)
|
696
|
+
return None
|
697
|
+
|
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
|
630
728
|
except Exception as e:
|
631
|
-
logger.error(f"Error in
|
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}")
|
632
759
|
return None
|
633
760
|
|
634
761
|
def setup_config(self):
|
@@ -2259,6 +2386,8 @@ class Agent:
|
|
2259
2386
|
|
2260
2387
|
Args:
|
2261
2388
|
task (str): The task to be performed by the `llm` object.
|
2389
|
+
img (str, optional): Path or URL to an image file.
|
2390
|
+
audio (str, optional): Path or URL to an audio file.
|
2262
2391
|
*args: Variable length argument list.
|
2263
2392
|
**kwargs: Arbitrary keyword arguments.
|
2264
2393
|
|
@@ -2270,22 +2399,22 @@ class Agent:
|
|
2270
2399
|
TypeError: If task is not a string or llm object is None.
|
2271
2400
|
ValueError: If task is empty.
|
2272
2401
|
"""
|
2273
|
-
if not isinstance(task, str):
|
2274
|
-
|
2402
|
+
# if not isinstance(task, str):
|
2403
|
+
# task = any_to_str(task)
|
2275
2404
|
|
2276
|
-
if
|
2277
|
-
|
2405
|
+
# if img is not None:
|
2406
|
+
# kwargs['img'] = img
|
2278
2407
|
|
2279
|
-
# if
|
2280
|
-
#
|
2408
|
+
# if audio is not None:
|
2409
|
+
# kwargs['audio'] = audio
|
2281
2410
|
|
2282
2411
|
try:
|
2283
|
-
out = self.llm.run(task, *args, **kwargs)
|
2412
|
+
out = self.llm.run(task=task, *args, **kwargs)
|
2284
2413
|
|
2285
2414
|
return out
|
2286
|
-
except
|
2415
|
+
except AgentLLMError as e:
|
2287
2416
|
logger.error(
|
2288
|
-
f"Error calling LLM: {e}
|
2417
|
+
f"Error calling LLM: {e}. Task: {task}, Args: {args}, Kwargs: {kwargs}"
|
2289
2418
|
)
|
2290
2419
|
raise e
|
2291
2420
|
|