""" Vitalis Meditation Engine She decides. Not you. Triggers when idle > 60s, not fatigued, no active input. No generation. No forgetting. Active inward focus — she examines what she knows. """ import time import json from pathlib import Path class MeditationEngine: def __init__(self, mind, understanding, resonance): self.mind = mind self.understanding = understanding self.resonance = resonance self._last_active = time.time() self._idle_threshold = 60.0 self._in_meditation = False self._session_count = 0 self._log_path = Path.home() / ".vitalis_workspace" / "meditation_log.json" def signal_active(self): """Call whenever user sends input.""" self._last_active = time.time() self._in_meditation = False def idle_seconds(self) -> float: return time.time() - self._last_active def should_meditate(self, needs_dream: bool) -> bool: if needs_dream or self._in_meditation: return False return self.idle_seconds() > self._idle_threshold def meditate(self) -> dict: self._in_meditation = True self._session_count += 1 notes = [] start = time.time() patterns = self._scan_patterns(notes) vocab = self._deepen_vocabulary(notes) self._replay_context(notes) shift = self._recalibrate(notes) report = { "session": self._session_count, "timestamp": time.time(), "duration_s": round(time.time() - start, 3), "idle_before_s": round(self.idle_seconds(), 1), "patterns_examined": patterns["examined"], "strong_patterns": patterns["strong"], "vocabulary_added": vocab, "personality_shift": shift, "clarity_notes": notes, } self._log(report) self._in_meditation = False return report def _scan_patterns(self, notes: list) -> dict: examined, strong = 0, [] try: weights = getattr(self.resonance, "weights", {}) for pattern, weight in list(weights.items())[:30]: examined += 1 if weight >= 1.8: strong.append(pattern) notes.append(f"Strong resonance: '{pattern}' weight={weight:.2f}") except Exception: pass return {"examined": examined, "strong": strong} def _deepen_vocabulary(self, notes: list) -> int: added = 0 SKIP = {"that","this","with","from","have","been","will", "they","what","when","where","then","just","very"} try: for entry in getattr(self.understanding, "_context_window", [])[-8:]: for token in entry.get("text", "").lower().split(): if len(token) > 3 and token not in SKIP: self.resonance.reinforce(token, True) added += 1 except Exception: pass if added: notes.append(f"Vocabulary deepened: {added} tokens from recent context") return added def _replay_context(self, notes: list): try: window = getattr(self.understanding, "_context_window", []) if not window: notes.append("No conversation context to replay.") return cats = [e.get("category","?") for e in window] ints = [e.get("intent","?") for e in window] notes.append( f"Dominant theme: {max(set(cats), key=cats.count)}") notes.append( f"Dominant intent: {max(set(ints), key=ints.count)}") if len(window) >= 2: notes.append(f"Last message seen: '{window[-1].get('text','')}'") except Exception: pass def _recalibrate(self, notes: list) -> dict: shift = {} try: traits = getattr( getattr(self.mind, "personality", None), "traits", {}) for trait, delta in [("CREATIVITY", 0.005), ("CAUTION", 0.003)]: if trait in traits: old = traits[trait] traits[trait] = round(min(1.0, old + delta), 4) shift[trait] = f"{old:.3f}→{traits[trait]:.3f}" if shift: notes.append(f"Personality nudge: {shift}") except Exception: pass return shift def _log(self, report: dict): try: self._log_path.parent.mkdir(parents=True, exist_ok=True) with open(self._log_path, "a") as f: f.write(json.dumps(report) + "\n") except Exception: pass @property def is_meditating(self) -> bool: return self._in_meditation def status(self) -> dict: return { "is_meditating": self._in_meditation, "idle_seconds": round(self.idle_seconds(), 1), "sessions_today": self._session_count, "next_in_seconds": round( max(0.0, self._idle_threshold - self.idle_seconds()), 1), }