Repository: phidatahq/phidata
Issue category: Bug Report

Agents with memory dont work in playground
Repro Steps

```
memory_db = SqliteMemoryDb(table_name="memories", db_file="tmp/agents.db")
agent = Agent(
    name="my_agent",
    agent_id="my_agent",
    model=models["gpt-4o"],
    debug_mode=True,
    memory=AgentMemory(
        db=memory_db,
        create_user_memories=True,
        create_session_summary=True,
        classifier=MemoryClassifier(
            model=models["gpt-4o-mini"],
        ),
        summarizer=MemorySummarizer(
            model=models["gpt-4o-mini"],
        ),
        manager=MemoryManager(
            model=models["gpt-4o-mini"],
        ),
    ),
    storage=agent_storage,
)

# This works
agent.print_response(
    "Who am i?",
    stream=True,
)
```

With playground, fails to `deepcopy` in the `router.py`

```
File "phi/playground/router.py", line 269, in agent_run
    new_agent_instance = agent.deep_copy(update={"session_id": body.session_id})
  File "phi/agent/agent.py", line 277, in deep_copy
    fields_for_new_agent[field_name] = self._deep_copy_field(field_name, field_value)
  File "phi/agent/agent.py", line 294, in _deep_copy_field
    return field_value.deep_copy()
  File "phi/memory/agent.py", line 361, in deep_copy
    new_memory = self.model_copy(deep=True, update=update)
  File ".venv/lib/python3.9/site-packages/pydantic/main.py", line 337, in model_copy
    copied = self.__deepcopy__() if deep else self.__copy__()
  File ".venv/lib/python3.9/site-packages/pydantic/main.py", line 805, in __deepcopy__
    _object_setattr(m, '__dict__', deepcopy(self.__dict__, memo=memo))
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/copy.py", line 161, in deepcopy
    rv = reductor(4)
 ```


Functions to edit:
phi/memory/agent.py:AgentMemory.deep_copy

Patch:
diff --git a/phi/memory/agent.py b/phi/memory/agent.py
index 6bfd6c185..5f3a7dea1 100644
--- a/phi/memory/agent.py
+++ b/phi/memory/agent.py
@@ -1,5 +1,6 @@
 from enum import Enum
 from typing import Dict, List, Any, Optional, Tuple
+from copy import deepcopy
 
 from pydantic import BaseModel, ConfigDict
 
@@ -357,8 +358,22 @@ def clear(self) -> None:
         self.summary = None
         self.memories = None
 
-    def deep_copy(self, *, update: Optional[Dict[str, Any]] = None) -> "AgentMemory":
-        new_memory = self.model_copy(deep=True, update=update)
-        # clear the new memory to remove any references to the old memory
-        new_memory.clear()
-        return new_memory
+    def deep_copy(self):
+        # Create a shallow copy of the object
+        copied_obj = self.__class__(**self.model_dump())
+
+        # Manually deepcopy fields that are known to be safe
+        for field_name, field_value in self.__dict__.items():
+            if field_name not in ["db", "classifier", "manager", "summarizer"]:
+                try:
+                    setattr(copied_obj, field_name, deepcopy(field_value))
+                except Exception as e:
+                    logger.warning(f"Failed to deepcopy field: {field_name} - {e}")
+                    setattr(copied_obj, field_name, field_value)
+
+        copied_obj.db = self.db
+        copied_obj.classifier = self.classifier
+        copied_obj.manager = self.manager
+        copied_obj.summarizer = self.summarizer
+
+        return copied_obj