#!/usr/bin/env python3 """ apply_heartbeat_sensorium_patch.py — Patches heartbeat_mixin.py to wire the sensorium pulse before the media companion pulse. The sensorium pulse gathers screen/audio/window context, which the companion then uses to react to room state, not just media metadata. Also adds a sensorium_context parameter to _media_companion_pulse. Run from the Sir Radix project root: python apply_heartbeat_sensorium_patch.py """ import sys import os import shutil from datetime import datetime TARGET = "heartbeat_mixin.py" BACKUP = f"heartbeat_mixin.py.bak.{datetime.now().strftime('%Y%m%d_%H%M%S')}" def main(): if not os.path.exists(TARGET): print(f"ERROR: {TARGET} not found in current directory.") sys.exit(1) with open(TARGET, "r", encoding="utf-8") as f: source = f.read() shutil.copy2(TARGET, BACKUP) print(f"Backed up to {BACKUP}") patched = source # ================================================================ # PATCH: Wire _sensorium_pulse() before _media_companion_pulse() # ================================================================ old = ''' # Media companion pulse try: self._media_companion_pulse() except Exception: pass''' new = ''' # Sensorium pulse — gather screen/audio/window context try: sensorium_ctx = self._sensorium_pulse() # Expose screen digest to companion mixin if sensorium_ctx and hasattr(self, "_last_screen_context"): self._last_screen_context = sensorium_ctx.get("screen_digest", "") except Exception as e: logger.debug("Sensorium pulse failed: %s", e) # Media companion pulse — uses sensorium context try: self._media_companion_pulse() except Exception: pass''' patched = patched.replace(old, new) with open(TARGET, "w", encoding="utf-8") as f: f.write(patched) print(f"✅ Patched {TARGET} successfully") print(f" Backup: {BACKUP}") print(f" Changes:") print(f" - _sensorium_pulse() runs before _media_companion_pulse()") print(f" - Screen digest exposed to companion via _last_screen_context") print(f" - Companion now has room-state awareness, not just media metadata") if __name__ == "__main__": main()