Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change agent.py #741

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 55 additions & 28 deletions swarms/structs/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1578,31 +1578,32 @@
Called automatically after load() to ensure all components are properly set up.
"""
try:
# Always create a new executor
self.executor = ThreadPoolExecutor(max_workers=os.cpu_count())

# Reinitialize tokenizer
self.tokenizer = TikTokenizer()

# Reinitialize conversation if needed
if (
not hasattr(self, "short_memory")
or self.short_memory is None
):
if not hasattr(self, "short_memory") or self.short_memory is None:
self.short_memory = Conversation(
system_prompt=self.system_prompt,
time_enabled=True,
user=self.user_name,
rules=self.rules,
)

# Reinitialize executor if needed
if not hasattr(self, "executor") or self.executor is None:
self.executor = ThreadPoolExecutor(
max_workers=os.cpu_count()
# Reinitialize tool structure if needed
if hasattr(self, 'tools') and (self.tools or getattr(self, 'list_base_models', None)):
self.tool_struct = BaseTool(
tools=self.tools,
base_models=getattr(self, 'list_base_models', None),
tool_system_prompt=self.tool_system_prompt
)

Check failure

Code scanning / Pyre

Unexpected keyword Error

Unexpected keyword [28]: Unexpected keyword argument tools to call object.\_\_init\_\_.

# # Reinitialize tool structure if needed
# if hasattr(self, 'tools') and (self.tools or getattr(self, 'list_base_models', None)):
# self.tool_struct = BaseTool(
# tools=self.tools,
# base_models=getattr(self, 'list_base_models', None),
# tool_system_prompt=self.tool_system_prompt
# )
# Restart autosave if it was enabled
if getattr(self, 'autosave', False):
self.enable_autosave()

except Exception as e:
logger.error(f"Error reinitializing components: {e}")
Expand Down Expand Up @@ -2284,40 +2285,66 @@
def _serialize_attr(self, attr_name: str, attr_value: Any) -> Any:
"""
Serializes an individual attribute, handling non-serializable objects.
Excludes certain attributes that should be recreated on load rather than serialized.

Args:
attr_name (str): The name of the attribute.
attr_value (Any): The value of the attribute.

Returns:
Any: The serialized value of the attribute.
"""
Any: The serialized value of the attribute, or None if it should be excluded.
"""
# List of attributes that should not be serialized
non_serializable_attrs = {
'executor', # ThreadPoolExecutor
'autosave_thread', # Thread object
'llm', # LLM instance that should be passed in constructor
'tokenizer', # Should be recreated
'tool_struct', # Should be recreated from tools and base_models
'long_term_memory', # Should be handled separately
'memory_manager', # Should be handled separately
'sentiment_analyzer', # Function/callable
'stopping_condition', # Function/callable
'stopping_func', # Function/callable
'custom_loop_condition', # Function/callable
'limit_tokens_from_string', # Function/callable
'output_cleaner', # Function/callable
'parser', # Function/callable
'callback', # Function/callable
'callbacks', # List of functions/callables
'search_algorithm', # Function/callable
'evaluator', # Function/callable
}

# Skip serialization for non-serializable attributes
if attr_name in non_serializable_attrs:
return None

try:
if callable(attr_value):
return self._serialize_callable(attr_value)
elif hasattr(attr_value, "to_dict"):
return (
attr_value.to_dict()
) # Recursive serialization for nested objects
return attr_value.to_dict()
else:
json.dumps(
attr_value
) # Attempt to serialize to catch non-serializable objects
# Test if it can be serialized
json.dumps(attr_value)
return attr_value
except (TypeError, ValueError):
return f"<Non-serializable: {type(attr_value).__name__}>"
except (TypeError, ValueError, AttributeError):
logger.warning(f"Attribute {attr_name} could not be serialized, excluding from save state")
return None

def to_dict(self) -> Dict[str, Any]:
"""
Converts all attributes of the class, including callables, into a dictionary.
Handles non-serializable attributes by converting them or skipping them.
Converts serializable attributes of the class into a dictionary.
Excludes non-serializable attributes that should be recreated on load.

Returns:
Dict[str, Any]: A dictionary representation of the class attributes.
Dict[str, Any]: A dictionary representation of the serializable class attributes.
"""
return {
attr_name: self._serialize_attr(attr_name, attr_value)
for attr_name, attr_value in self.__dict__.items()
if self._serialize_attr(attr_name, attr_value) is not None
}

def to_json(self, indent: int = 4, *args, **kwargs):
Expand Down
Loading