fix(memory): prevent duplicate Deep Dream runs

This commit is contained in:
zhayujie
2026-04-28 15:30:51 +08:00
parent c9c99de3d9
commit 02bfe30848
2 changed files with 15 additions and 7 deletions

View File

@@ -115,7 +115,7 @@ class MemoryFlushManager:
self.last_flush_timestamp: Optional[datetime] = None self.last_flush_timestamp: Optional[datetime] = None
self._trim_flushed_hashes: set = set() # Content hashes of already-flushed messages self._trim_flushed_hashes: set = set() # Content hashes of already-flushed messages
self._last_flushed_content_hash: str = "" # Content hash at last flush, for daily dedup self._last_flushed_content_hash: str = "" # Content hash at last flush, for daily dedup
self._last_dream_input_hash: str = "" # Hash of dream input, for dedup self._last_dream_input_hash: str = "" # "{date}:{daily_hash}" of last dream, for dedup
self._last_flush_thread: Optional[threading.Thread] = None self._last_flush_thread: Optional[threading.Thread] = None
def get_today_memory_file(self, user_id: Optional[str] = None, ensure_exists: bool = False) -> Path: def get_today_memory_file(self, user_id: Optional[str] = None, ensure_exists: bool = False) -> Path:
@@ -323,13 +323,18 @@ class MemoryFlushManager:
logger.info("[DeepDream] No recent daily records, skipping to preserve existing MEMORY.md") logger.info("[DeepDream] No recent daily records, skipping to preserve existing MEMORY.md")
return False return False
# Dedup: skip if input materials haven't changed since last dream # Dedup: skip if same daily content already dreamed today.
# Note: only hash daily_content (not memory_content), because deep_dream
# itself rewrites MEMORY.md as a side effect, which would otherwise
# invalidate the hash on every subsequent call within the same window.
import hashlib import hashlib
input_hash = hashlib.md5((memory_content + daily_content).encode("utf-8")).hexdigest() daily_hash = hashlib.md5(daily_content.encode("utf-8")).hexdigest()
if not force and input_hash == self._last_dream_input_hash: today_str = datetime.now().strftime("%Y-%m-%d")
logger.debug("[DeepDream] Input unchanged since last dream, skipping") dedup_key = f"{today_str}:{daily_hash}"
if not force and dedup_key == self._last_dream_input_hash:
logger.info("[DeepDream] Already dreamed today with same daily content, skipping")
return False return False
self._last_dream_input_hash = input_hash self._last_dream_input_hash = dedup_key
logger.info( logger.info(
f"[DeepDream] Materials collected: " f"[DeepDream] Materials collected: "

View File

@@ -549,19 +549,22 @@ class AgentInitializer:
def _daily_flush_loop(): def _daily_flush_loop():
import random import random
last_run_date = None # Track last successful run date to prevent same-day re-trigger
while True: while True:
try: try:
now = datetime.datetime.now() now = datetime.datetime.now()
jitter_min = random.randint(50, 55) jitter_min = random.randint(50, 55)
jitter_sec = random.randint(0, 59) jitter_sec = random.randint(0, 59)
target = now.replace(hour=23, minute=jitter_min, second=jitter_sec, microsecond=0) target = now.replace(hour=23, minute=jitter_min, second=jitter_sec, microsecond=0)
if target <= now: # Always schedule for tomorrow if we already ran today, or if target time has passed
if target <= now or (last_run_date == now.date()):
target += datetime.timedelta(days=1) target += datetime.timedelta(days=1)
wait_seconds = (target - now).total_seconds() wait_seconds = (target - now).total_seconds()
logger.info(f"[DailyFlush] Next flush at {target.strftime('%Y-%m-%d %H:%M:%S')} (in {wait_seconds/3600:.1f}h)") logger.info(f"[DailyFlush] Next flush at {target.strftime('%Y-%m-%d %H:%M:%S')} (in {wait_seconds/3600:.1f}h)")
time.sleep(wait_seconds) time.sleep(wait_seconds)
self._flush_all_agents() self._flush_all_agents()
last_run_date = datetime.datetime.now().date()
except Exception as e: except Exception as e:
logger.warning(f"[DailyFlush] Error in daily flush loop: {e}") logger.warning(f"[DailyFlush] Error in daily flush loop: {e}")
time.sleep(3600) time.sleep(3600)