From d80511898c36ff926bff57422014d4e9e6c87609 Mon Sep 17 00:00:00 2001 From: Joao Moura Date: Wed, 13 May 2026 04:51:28 -0400 Subject: [PATCH] fix: enhance memory handling and logging in agent executor - Added checks for read-only memory settings in `ConversationalAgentExecutor` to prevent modifications when memory is not writable. - Improved memory extraction logic to include metadata when remembering memories, enhancing context retention. - Updated logging from debug to warning level for memory initialization and save failures, ensuring better visibility of issues. These changes aim to improve the robustness and clarity of memory management within the CrewAI framework. --- lib/crewai/src/crewai/new_agent/executor.py | 12 +++++-- lib/crewai/src/crewai/new_agent/new_agent.py | 35 +++++++++----------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/lib/crewai/src/crewai/new_agent/executor.py b/lib/crewai/src/crewai/new_agent/executor.py index e4da7a4e2..d13cdeab3 100644 --- a/lib/crewai/src/crewai/new_agent/executor.py +++ b/lib/crewai/src/crewai/new_agent/executor.py @@ -1233,6 +1233,8 @@ class ConversationalAgentExecutor(BaseModel): """Save provenance entry to memory backend for long-term auditing.""" if not self.agent._memory_instance: return + if self.agent.settings.memory_read_only: + return try: value = f"[provenance] {entry.action}: {entry.outcome or ''}" metadata: dict[str, Any] = { @@ -1253,6 +1255,8 @@ class ConversationalAgentExecutor(BaseModel): agent = self.agent if not agent.settings.memory_enabled: return + if agent.settings.memory_read_only: + return memory = getattr(agent, "_memory_instance", None) if memory is None: return @@ -1273,7 +1277,11 @@ class ConversationalAgentExecutor(BaseModel): pass extracted = memory.extract_memories(raw) if extracted: - memory.remember_many(extracted, agent_role=agent.role) + scope = self._get_provider_scope() + kwargs: dict[str, Any] = {"agent_role": agent.role} + if scope: + kwargs["metadata"] = scope + memory.remember_many(extracted, **kwargs) try: from crewai.new_agent.events import NewAgentMemorySaveEvent @@ -1288,7 +1296,7 @@ class ConversationalAgentExecutor(BaseModel): if dreaming: dreaming.increment_memory_count() except Exception as e: - logger.debug(f"Memory save failed: {e}") + logger.warning(f"Memory save failed: {e}") async def ainvoke(self, user_message: Message) -> Message: """Process a single conversational turn (async).""" diff --git a/lib/crewai/src/crewai/new_agent/new_agent.py b/lib/crewai/src/crewai/new_agent/new_agent.py index dc2a9fbb6..e7ba53160 100644 --- a/lib/crewai/src/crewai/new_agent/new_agent.py +++ b/lib/crewai/src/crewai/new_agent/new_agent.py @@ -232,28 +232,25 @@ class NewAgent(BaseModel): self._memory_namespace = self.memory.namespace self._memory_shared = self.memory.shared self._init_memory_instance() - return - - if isinstance(self.memory, MemorySlice): + elif isinstance(self.memory, MemorySlice): self._memory_namespace = self.memory.scope or None self._memory_filter = self.memory self._init_memory_instance() - return + else: + try: + from crewai.memory.unified_memory import Memory + from crewai.memory.utils import sanitize_scope_name - try: - from crewai.memory.unified_memory import Memory - from crewai.memory.utils import sanitize_scope_name - - if isinstance(self.memory, Memory): - self._memory_instance = self.memory - elif self.memory is True or self.memory is None: - agent_name = sanitize_scope_name(self.role or str(self.id)) - self._memory_instance = Memory(root_scope=f"/agent/{agent_name}") - else: - self._memory_instance = self.memory - except Exception as e: - self._logger.debug(f"Memory initialization failed: {e}") - self._memory_instance = None + if isinstance(self.memory, Memory): + self._memory_instance = self.memory + elif self.memory is True or self.memory is None: + agent_name = sanitize_scope_name(self.role or str(self.id)) + self._memory_instance = Memory(root_scope=f"/agent/{agent_name}") + else: + self._memory_instance = self.memory + except Exception as e: + self._logger.warning(f"Memory initialization failed: {e}") + self._memory_instance = None if self._memory_instance and self.settings.memory_read_only: self._memory_instance.read_only = True @@ -276,7 +273,7 @@ class NewAgent(BaseModel): agent_name = sanitize_scope_name(self.role or str(self.id)) self._memory_instance = Memory(root_scope=f"/agent/{agent_name}") except Exception as e: - self._logger.debug(f"Memory initialization failed: {e}") + self._logger.warning(f"Memory initialization failed: {e}") self._memory_instance = None def _init_tools(self) -> None: