fix: remove dead last_consolidated field from Session
Build Nanobot OAuth / build (pull_request) Successful in 5m51s
Build Nanobot OAuth / cleanup (pull_request) Has been skipped

The `last_consolidated` marker was designed for incremental consolidation
assuming append-only messages. However, deferred trim removes messages from
the session, which broke the incremental assumption and caused consolidation
to fail silently (early exit when end_idx <= stale last_consolidated).

After trim, the session only contains NEW unconsolidated messages, making
the marker unnecessary. Consolidation now always starts from index 0,
processing all messages in the session (which are by definition not yet
consolidated due to trim).

Fixes the bug where extraction completely stopped working after trim
(zero facts extracted despite multiple consolidation attempts).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 17:23:21 +00:00
parent e782318338
commit 83d2acf07f
3 changed files with 7 additions and 24 deletions
+2 -5
View File
@@ -87,9 +87,7 @@ class MemoryStore:
keep_count = memory_window // 2
if len(session.messages) <= keep_count:
return True
if len(session.messages) - session.last_consolidated <= 0:
return True
old_messages = session.messages[session.last_consolidated:-keep_count]
old_messages = session.messages[:-keep_count]
if not old_messages:
return True
logger.info("Memory consolidation: {} to consolidate, {} keep", len(old_messages), keep_count)
@@ -142,8 +140,7 @@ class MemoryStore:
if update != current_memory:
self.write_long_term(update)
session.last_consolidated = 0 if archive_all else len(session.messages) - keep_count
logger.info("Memory consolidation done: {} messages, last_consolidated={}", len(session.messages), session.last_consolidated)
logger.info("Memory consolidation done: {} messages total", len(session.messages))
return True
except Exception:
logger.exception("Memory consolidation failed")
+3 -10
View File
@@ -332,8 +332,8 @@ Here is the conversation to extract facts from:
if len(session.messages) <= keep_count:
return True
# Get unconsolidated messages
start_idx = session.last_consolidated
# Consolidate messages except the most recent (kept for context)
start_idx = 0
end_idx = len(session.messages) - keep_count
if end_idx <= start_idx:
@@ -414,15 +414,8 @@ Here is the conversation to extract facts from:
session_id=session.key
)
# Update consolidation marker
if archive_all:
session.last_consolidated = len(session.messages)
else:
session.last_consolidated = end_idx
logger.info(
f"Mem0 consolidation done: {len(session.messages)} messages, "
f"last_consolidated={session.last_consolidated}"
f"Mem0 consolidation done: {len(session.messages)} messages total"
)
return True
+2 -9
View File
@@ -19,9 +19,7 @@ class Session:
Stores messages in JSONL format for easy reading and persistence.
Important: Messages are append-only for LLM cache efficiency.
The consolidation process writes summaries to MEMORY.md/HISTORY.md
but does NOT modify the messages list or get_history() output.
Messages are trimmed after consolidation to keep session size manageable.
"""
key: str # channel:chat_id
@@ -29,7 +27,6 @@ class Session:
created_at: datetime = field(default_factory=datetime.now)
updated_at: datetime = field(default_factory=datetime.now)
metadata: dict[str, Any] = field(default_factory=dict)
last_consolidated: int = 0 # Number of messages already consolidated to files
def add_message(self, role: str, content: str, **kwargs: Any) -> None:
"""Add a message to the session."""
@@ -73,7 +70,6 @@ class Session:
def clear(self) -> None:
"""Clear all messages and reset session to initial state."""
self.messages = []
self.last_consolidated = 0
self.updated_at = datetime.now()
@@ -139,7 +135,6 @@ class SessionManager:
messages = []
metadata = {}
created_at = None
last_consolidated = 0
with open(path, encoding="utf-8") as f:
for line in f:
@@ -152,7 +147,7 @@ class SessionManager:
if data.get("_type") == "metadata":
metadata = data.get("metadata", {})
created_at = datetime.fromisoformat(data["created_at"]) if data.get("created_at") else None
last_consolidated = data.get("last_consolidated", 0)
# Ignore legacy last_consolidated field
else:
messages.append(data)
@@ -161,7 +156,6 @@ class SessionManager:
messages=messages,
created_at=created_at or datetime.now(),
metadata=metadata,
last_consolidated=last_consolidated
)
except Exception as e:
logger.warning("Failed to load session {}: {}", key, e)
@@ -178,7 +172,6 @@ class SessionManager:
"created_at": session.created_at.isoformat(),
"updated_at": session.updated_at.isoformat(),
"metadata": session.metadata,
"last_consolidated": session.last_consolidated
}
f.write(json.dumps(metadata_line, ensure_ascii=False) + "\n")
for msg in session.messages: