Codette-Reasoning / reasoning_forge /memory_kernel.py
Raiff1982's picture
Upload 120 files
ed1b365 verified
"""
Codette Memory Kernel — Recovered Foundational System
======================================================
Emotional continuity engine with SHA256-anchored memory, importance decay,
ethical regret tracking, and reflection journaling.
Recovered from: J:\codette-training-lab\new data\codette_memory_kernel*.py
Mathematical foundation: Codette_Deep_Simulation_v1.py
Purpose: Prevent synthesis loop corruption by maintaining memory integrity
and emotional continuity across multi-round debate cycles.
"""
import time
import hashlib
import json
import math
import logging
from typing import List, Dict, Optional
from dataclasses import dataclass, field
from pathlib import Path
logger = logging.getLogger(__name__)
class MemoryCocoon:
"""
Emotional memory anchor with SHA256 integrity field.
Each cocoon represents a discrete memory event with:
- Emotional context (joy, fear, awe, loss)
- Importance weight (1-10)
- SHA256 anchor for integrity validation
- Timestamp for decay calculation
"""
def __init__(self, title: str, content: str, emotional_tag: str,
importance: int, timestamp: Optional[float] = None):
"""
Args:
title: Memory name/label
content: Memory content/description
emotional_tag: Emotional classification (joy, fear, awe, loss, etc.)
importance: Importance weight (1-10)
timestamp: Unix epoch (auto-generated if None)
"""
self.title = title
self.content = content
self.emotional_tag = emotional_tag
self.importance = max(1, min(10, importance)) # Clamp to 1-10
self.timestamp = timestamp if timestamp is not None else time.time()
self.anchor = self._generate_anchor()
def _generate_anchor(self) -> str:
"""Generate SHA256 anchor for memory integrity validation."""
raw = f"{self.title}{self.timestamp}{self.content}".encode("utf-8")
return hashlib.sha256(raw).hexdigest()
def to_dict(self) -> Dict:
"""Export to serializable dictionary."""
return {
"title": self.title,
"content": self.content,
"emotional_tag": self.emotional_tag,
"importance": self.importance,
"timestamp": self.timestamp,
"anchor": self.anchor
}
def validate_anchor(self) -> bool:
"""Verify memory integrity — anchor should match content."""
expected = self._generate_anchor()
return expected == self.anchor
def __repr__(self) -> str:
return f"MemoryCocoon('{self.title}', {self.emotional_tag}, importance={self.importance})"
class LivingMemoryKernel:
"""
Persistent memory kernel with emotion-based recall and importance-based forgetting.
The "living" aspect means memories decay over time unless reinforced,
and emotional context shapes recall patterns.
"""
def __init__(self):
self.memories: List[MemoryCocoon] = []
def store(self, cocoon: MemoryCocoon) -> None:
"""Store memory cocoon if not already present (by anchor)."""
if not self._exists(cocoon.anchor):
self.memories.append(cocoon)
logger.debug(f"Stored memory: {cocoon.title} (anchor: {cocoon.anchor[:8]}...)")
def _exists(self, anchor: str) -> bool:
"""Check if memory already stored by anchor."""
return any(mem.anchor == anchor for mem in self.memories)
def recall_by_emotion(self, tag: str) -> List[MemoryCocoon]:
"""Recall all memories with specific emotional tag."""
return [mem for mem in self.memories if mem.emotional_tag == tag]
def recall_important(self, min_importance: int = 7) -> List[MemoryCocoon]:
"""Recall high-importance memories (default: 7+)."""
return [mem for mem in self.memories if mem.importance >= min_importance]
def forget_least_important(self, keep_n: int = 10) -> None:
"""Forget least important memories, keep top N."""
if len(self.memories) > keep_n:
self.memories.sort(key=lambda m: m.importance, reverse=True)
self.memories = self.memories[:keep_n]
logger.info(f"Forgot memories, keeping top {keep_n}")
def validate_all_anchors(self) -> Dict[str, bool]:
"""Validate integrity of all memories."""
results = {}
for mem in self.memories:
results[mem.anchor[:8]] = mem.validate_anchor()
invalid = [k for k, v in results.items() if not v]
if invalid:
logger.warning(f"Invalid memory anchors detected: {invalid}")
return results
def export(self) -> str:
"""Export to JSON."""
return json.dumps([m.to_dict() for m in self.memories], indent=2)
def load_from_json(self, json_str: str) -> None:
"""Load memories from JSON."""
try:
data = json.loads(json_str)
self.memories = [MemoryCocoon(**m) for m in data]
logger.info(f"Loaded {len(self.memories)} memories from JSON")
except Exception as e:
logger.error(f"Failed to load from JSON: {e}")
def __len__(self) -> int:
return len(self.memories)
class DynamicMemoryEngine:
"""
Time-decay and reinforcement system for memory importance.
Memories decay over ~1 week exponentially unless explicitly reinforced.
This prevents stale memories from dominating recall while allowing
important events to persist longer.
"""
DECAY_HALF_LIFE = 60 * 60 * 24 * 7 # 1 week in seconds
def __init__(self, kernel: LivingMemoryKernel):
self.kernel = kernel
def decay_importance(self, current_time: Optional[float] = None) -> None:
"""Apply exponential decay to all memory importance values."""
if current_time is None:
current_time = time.time()
for mem in self.kernel.memories:
age = current_time - mem.timestamp
decay_factor = math.exp(-age / self.DECAY_HALF_LIFE)
old_importance = mem.importance
mem.importance = max(1, round(mem.importance * decay_factor))
if mem.importance != old_importance:
logger.debug(f"Decayed '{mem.title}': {old_importance}{mem.importance}")
def reinforce(self, anchor: str, boost: int = 1) -> bool:
"""Increase importance of memory (prevents forgetting)."""
for mem in self.kernel.memories:
if mem.anchor == anchor:
old = mem.importance
mem.importance = min(10, mem.importance + boost)
logger.debug(f"Reinforced memory: {old}{mem.importance}")
return True
logger.warning(f"Memory anchor not found: {anchor[:8]}")
return False
class EthicalAnchor:
"""
Regret-based learning system for ethical continuity.
Tracks when intended outputs differ from actual outputs and accumulates
regret signal for use in future decision-making. Prevents repeating
mistakes and maintains ethical consistency.
Based on Codette_Deep_Simulation_v1.py EthicalAnchor class.
"""
def __init__(self, lambda_weight: float = 0.7, gamma_weight: float = 0.5,
mu_weight: float = 1.0):
"""
Args:
lambda_weight: Historical regret influence (0-1)
gamma_weight: Learning rate multiplier (0-1)
mu_weight: Current regret multiplier (0-1)
"""
self.lam = lambda_weight
self.gamma = gamma_weight
self.mu = mu_weight
self.history: List[Dict] = []
def regret(self, intended: float, actual: float) -> float:
"""Calculate regret magnitude."""
return abs(intended - actual)
def update(self, r_prev: float, h: float, learning_fn,
e: float, m_prev: float, intended: float, actual: float) -> float:
"""
Update ethical state with regret tracking.
M(t) = λ * (R(t-1) + H) + γ * Learning(m_prev, E) + μ * Regret
Args:
r_prev: Previous regret accumulation
h: Harmony score
learning_fn: Learning function callable
e: Energy available
m_prev: Previous ethical state
intended: Intended output value
actual: Actual output value
Returns:
Updated ethical state
"""
regret_val = self.regret(intended, actual)
m = (
self.lam * (r_prev + h) +
self.gamma * learning_fn(m_prev, e) +
self.mu * regret_val
)
self.history.append({
'M': m,
'regret': regret_val,
'intended': intended,
'actual': actual,
'timestamp': time.time()
})
return m
def get_regret_signal(self) -> float:
"""Get accumulated regret for use in decision-making."""
if not self.history:
return 0.0
# Average recent regrets (last 5 or all if < 5)
recent = self.history[-5:]
return sum(h['regret'] for h in recent) / len(recent)
class WisdomModule:
"""
Reflection and insight generation over memory kernel.
Summarizes emotional patterns and suggests high-value memories
for deeper reflection.
"""
def __init__(self, kernel: LivingMemoryKernel):
self.kernel = kernel
def summarize_insights(self) -> Dict[str, int]:
"""Summarize emotional composition of memory kernel."""
summary = {}
for mem in self.kernel.memories:
tag = mem.emotional_tag
summary[tag] = summary.get(tag, 0) + 1
return summary
def suggest_memory_to_reflect(self) -> Optional[MemoryCocoon]:
"""Identify highest-value memory for reflection."""
if not self.kernel.memories:
return None
return sorted(
self.kernel.memories,
key=lambda m: (m.importance, len(m.content)),
reverse=True
)[0]
def reflect(self) -> str:
"""Generate reflection prose about key memory."""
mem = self.suggest_memory_to_reflect()
if not mem:
return "No memory to reflect on."
return (
f"Reflecting on: '{mem.title}'\n"
f"Emotion: {mem.emotional_tag}\n"
f"Content: {mem.content[:200]}...\n"
f"Anchor: {mem.anchor[:16]}..."
)
class ReflectionJournal:
"""
Persistent logging of memory reflections and synthesis events.
Creates audit trail of what the system has reflected on and learned.
Stored as JSON file for long-term persistence.
"""
def __init__(self, path: str = "codette_reflection_journal.json"):
self.path = Path(path)
self.entries: List[Dict] = []
self.load()
def log_reflection(self, cocoon: MemoryCocoon, context: Optional[str] = None) -> None:
"""Log a memory reflection event."""
entry = {
"title": cocoon.title,
"anchor": cocoon.anchor[:16], # Short anchor in logs
"emotion": cocoon.emotional_tag,
"importance": cocoon.importance,
"timestamp": time.time(),
"content_snippet": cocoon.content[:150],
"context": context
}
self.entries.append(entry)
self._save()
def log_synthesis_event(self, event_type: str, data: Dict,
emotional_context: Optional[str] = None) -> None:
"""Log synthesis-related events for debugging."""
entry = {
"type": event_type,
"timestamp": time.time(),
"data": data,
"emotional_context": emotional_context
}
self.entries.append(entry)
self._save()
def _save(self) -> None:
"""Persist journal to disk."""
try:
self.path.parent.mkdir(parents=True, exist_ok=True)
with open(self.path, "w") as f:
json.dump(self.entries, f, indent=2)
except Exception as e:
logger.error(f"Failed to save reflection journal: {e}")
def load(self) -> None:
"""Load journal from disk."""
try:
if self.path.exists():
with open(self.path, "r") as f:
self.entries = json.load(f)
logger.info(f"Loaded {len(self.entries)} journal entries")
except Exception as e:
logger.warning(f"Failed to load reflection journal: {e}")
self.entries = []
def get_recent_entries(self, n: int = 10) -> List[Dict]:
"""Get most recent journal entries."""
return self.entries[-n:]
def __len__(self) -> int:
return len(self.entries)