forked from Rockachopa/Timmy-time-dashboard
feat: heartbeat memory hooks — pre-recall and post-update
Wire MEMORY.md + soul.md into the thinking loop so each heartbeat is grounded in identity and recent context, breaking repetitive loops. Pre-hook: _load_memory_context() reads hot memory first (changes each cycle) then soul.md (stable identity), truncated to 1500 chars. Post-hook: _update_memory() writes a "Last Reflection" section to MEMORY.md after each thought so the next cycle has fresh context. soul.md is read-only from the heartbeat — never modified by it. All hooks degrade gracefully and never crash the heartbeat. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ logger = logging.getLogger(__name__)
|
||||
PROJECT_ROOT = Path(__file__).parent.parent.parent
|
||||
HOT_MEMORY_PATH = PROJECT_ROOT / "MEMORY.md"
|
||||
VAULT_PATH = PROJECT_ROOT / "memory"
|
||||
SOUL_PATH = VAULT_PATH / "self" / "soul.md"
|
||||
HANDOFF_PATH = VAULT_PATH / "notes" / "last-session-handoff.md"
|
||||
|
||||
|
||||
@@ -433,6 +434,15 @@ class MemorySystem:
|
||||
|
||||
return "\n".join(summary_parts) if summary_parts else ""
|
||||
|
||||
def read_soul(self) -> str:
|
||||
"""Read soul.md — Timmy's core identity. Returns empty string if missing."""
|
||||
try:
|
||||
if SOUL_PATH.exists():
|
||||
return SOUL_PATH.read_text()
|
||||
except Exception as exc:
|
||||
logger.debug("Failed to read soul.md: %s", exc)
|
||||
return ""
|
||||
|
||||
def get_system_context(self) -> str:
|
||||
"""Get full context for system prompt injection.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user