feat: Enhance memory system with isolated memory configuration (#2597)

* feat: support defining any memory in an isolated way

This change makes it easier to use a specific memory type without unintentionally enabling all others.

Previously, setting memory=True would implicitly configure all available memories (like LTM and STM), which might not be ideal in all cases. For example, when building a chatbot that only needs an external memory, users were forced to also configure LTM and STM — which rely on default OpenAPI embeddings — even if they weren’t needed.

With this update, users can now define a single memory in isolation, making the configuration process simpler and more flexible.

* feat: add tests to ensure we are able to use contextual memory by set individual memories

* docs: enhance memory documentation

* feat: warn when long-term memory is defined but entity memory is not
This commit is contained in:
Lucas Gomide
2025-04-14 16:48:48 -03:00
committed by GitHub
parent 88455cd52c
commit 9dffd42e6d
17 changed files with 5018 additions and 1528 deletions

View File

@@ -275,46 +275,51 @@ class Crew(BaseModel):
return self
def _initialize_user_memory(self):
if (
self.memory_config
and "user_memory" in self.memory_config
and self.memory_config.get("provider") == "mem0"
): # Check for user_memory in config
user_memory_config = self.memory_config["user_memory"]
if isinstance(
user_memory_config, dict
): # Check if it's a configuration dict
self._user_memory = UserMemory(crew=self)
else:
raise TypeError("user_memory must be a configuration dictionary")
def _initialize_default_memories(self):
self._long_term_memory = self._long_term_memory or LongTermMemory()
self._short_term_memory = self._short_term_memory or ShortTermMemory(
crew=self,
embedder_config=self.embedder,
)
self._entity_memory = self.entity_memory or EntityMemory(
crew=self, embedder_config=self.embedder
)
@model_validator(mode="after")
def create_crew_memory(self) -> "Crew":
"""Set private attributes."""
"""Initialize private memory attributes."""
self._external_memory = (
# External memory doesnt support a default value since it was designed to be managed entirely externally
self.external_memory.set_crew(self)
if self.external_memory
else None
)
self._long_term_memory = self.long_term_memory
self._short_term_memory = self.short_term_memory
self._entity_memory = self.entity_memory
# UserMemory is gonna to be deprecated in the future, but we have to initialize a default value for now
self._user_memory = None
if self.memory:
self._long_term_memory = (
self.long_term_memory if self.long_term_memory else LongTermMemory()
)
self._short_term_memory = (
self.short_term_memory
if self.short_term_memory
else ShortTermMemory(
crew=self,
embedder_config=self.embedder,
)
)
self._entity_memory = (
self.entity_memory
if self.entity_memory
else EntityMemory(crew=self, embedder_config=self.embedder)
)
self._external_memory = (
# External memory doesnt support a default value since it was designed to be managed entirely externally
self.external_memory.set_crew(self)
if self.external_memory
else None
)
if (
self.memory_config
and "user_memory" in self.memory_config
and self.memory_config.get("provider") == "mem0"
): # Check for user_memory in config
user_memory_config = self.memory_config["user_memory"]
if isinstance(
user_memory_config, dict
): # Check if it's a configuration dict
self._user_memory = UserMemory(crew=self)
else:
raise TypeError("user_memory must be a configuration dictionary")
else:
self._user_memory = None # No user memory if not in config
self._initialize_default_memories()
self._initialize_user_memory()
return self
@model_validator(mode="after")