forked from Rockachopa/Timmy-time-dashboard
This commit is contained in:
@@ -641,6 +641,38 @@ def store_personal_fact(fact: str, agent_id: str | None = None) -> MemoryEntry:
|
||||
)
|
||||
|
||||
|
||||
def store_last_reflection(reflection: str) -> None:
|
||||
"""Store the last reflection, replacing any previous one.
|
||||
|
||||
Uses a single row with memory_type='reflection' to avoid accumulation.
|
||||
"""
|
||||
if not reflection or not reflection.strip():
|
||||
return
|
||||
with get_connection() as conn:
|
||||
# Delete previous reflections — only the latest matters
|
||||
conn.execute("DELETE FROM memories WHERE memory_type = 'reflection'")
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO memories
|
||||
(id, content, memory_type, source, created_at)
|
||||
VALUES (?, ?, 'reflection', 'system', ?)
|
||||
""",
|
||||
(str(uuid.uuid4()), reflection.strip(), datetime.now(UTC).isoformat()),
|
||||
)
|
||||
conn.commit()
|
||||
logger.debug("Stored last reflection in DB")
|
||||
|
||||
|
||||
def recall_last_reflection() -> str | None:
|
||||
"""Recall the most recent reflection, or None if absent."""
|
||||
with get_connection() as conn:
|
||||
row = conn.execute(
|
||||
"SELECT content FROM memories WHERE memory_type = 'reflection' "
|
||||
"ORDER BY created_at DESC LIMIT 1"
|
||||
).fetchone()
|
||||
return row["content"] if row else None
|
||||
|
||||
|
||||
# ───────────────────────────────────────────────────────────────────────────────
|
||||
# Hot Memory (computed from DB instead of MEMORY.md)
|
||||
# ───────────────────────────────────────────────────────────────────────────────
|
||||
@@ -655,13 +687,23 @@ class HotMemory:
|
||||
self._last_modified: float | None = None
|
||||
|
||||
def read(self, force_refresh: bool = False) -> str:
|
||||
"""Read hot memory — computed view of top facts from DB."""
|
||||
"""Read hot memory — computed view of top facts + last reflection from DB."""
|
||||
try:
|
||||
facts = recall_personal_facts()
|
||||
lines = ["# Timmy Hot Memory\n"]
|
||||
|
||||
if facts:
|
||||
lines = ["# Timmy Hot Memory\n", "## Known Facts\n"]
|
||||
lines.append("## Known Facts\n")
|
||||
for f in facts[:15]:
|
||||
lines.append(f"- {f}")
|
||||
|
||||
# Include the last reflection if available
|
||||
reflection = recall_last_reflection()
|
||||
if reflection:
|
||||
lines.append("\n## Last Reflection\n")
|
||||
lines.append(reflection)
|
||||
|
||||
if len(lines) > 1:
|
||||
return "\n".join(lines)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -707,12 +749,16 @@ class HotMemory:
|
||||
new_section = f"## {section}\n\n{content}\n\n"
|
||||
full_content = full_content[: match.start()] + new_section + full_content[match.end() :]
|
||||
else:
|
||||
# Append section before last updated line
|
||||
# Append section — guard against missing prune marker
|
||||
insert_point = full_content.rfind("*Prune date:")
|
||||
new_section = f"## {section}\n\n{content}\n\n"
|
||||
full_content = (
|
||||
full_content[:insert_point] + new_section + "\n" + full_content[insert_point:]
|
||||
)
|
||||
if insert_point < 0:
|
||||
# No prune marker — just append at end
|
||||
full_content = full_content.rstrip() + "\n\n" + new_section
|
||||
else:
|
||||
full_content = (
|
||||
full_content[:insert_point] + new_section + "\n" + full_content[insert_point:]
|
||||
)
|
||||
|
||||
self.path.write_text(full_content)
|
||||
self._content = full_content
|
||||
|
||||
Reference in New Issue
Block a user