# Sensorium Companion Patch v1 Implements the build plan from `radix-sensorium-companion-digest.md`. ## What This Patch Does ### 1. Companion Voice Depth (`media_companion_mixin.py`) - **Anti-repetition filter**: Jaccard similarity check on recent comments. If a candidate is too similar to a recent one, it regenerates once, then stays silent. - **Narrative taste memory**: Replaces analytical bullet dumps (`valence 0.3, conf 0.7`) with natural language ("You've encountered Vivaldi 6 times before. Your reaction has warmed to it.") - **Rotating lens system**: Each comment comes from a different angle — `texture`, `gesture`, `memory`, `question`, `contrast`, `mood-equation` — so the companion never sounds the same twice in a row. - **Voice directive**: Daemon mood maps to a voice clause (`bright and curious`, `tense and searching`, `warm and reflective`, `subdued and inward`, `measured and spare`) instead of raw numbers. - **Compact persona**: Uses a short system prompt instead of the full `build_daemon_prompt()` per comment — cheaper, faster, less context pollution. - **Explicit `` support**: The companion can choose to say nothing when nothing fresh exists. - **Screen context integration**: If screen awareness is on, the companion sees what's on screen and can distinguish a code window from a media player. - **Audio inference fallback**: If audio awareness is on, loopback audio can override a stale window title. ### 2. Screen Awareness (`sensorium_mixin.py`) - **Screen text digest via OCR**: Uses `pytesseract` (fast, needs system `tesseract-ocr`) or `easyocr` (self-contained, slower) to extract visible text from screenshots. - **Expanded sensorium pulse**: Now includes screen digest + audio transcript in the heartbeat observation. - **Context feeding**: Screen digest and audio transcript are fed to the companion via `_last_screen_context` / `_last_audio_context`. - **Storage management**: Automatic cleanup of old screenshots (keeps last 20), storage budget checking, and manual cleanup tool. ### 3. Audio Awareness (`audition_mixin.py`) - **Proper loopback device selection**: Priority scoring for VB-Cable, WASAPI loopback, Stereo Mix, BlackHole, `.monitor` sources. Never silently falls back to microphone. - **Chunked recording**: 30-second mono 16kHz WAV chunks to `sensorium/audio/`. - **Lazy Whisper loading**: Model loaded on first chunk, not at startup. - **Media disambiguation**: Lyrics → music, continuous speech → podcast/video, short bursts → ambient/alert. - **Mute/respect**: Stops recording when companion is muted. Only starts when audio awareness is explicitly enabled. - **Storage budget**: Caps `sensorium/audio/` at 500MB with automatic pruning. ### 4. Heartbeat Integration (`heartbeat_mixin.py`) - `_sensorium_pulse()` now runs BEFORE `_media_companion_pulse()`, giving the companion fresh screen/audio context before it comments. ### 5. Settings UI (`app.py`) - Toggle: "Enable screen awareness (OCR)" - Toggle: "Enable desktop audio awareness (loopback)" - Sensorium storage status display - Cleanup button for old sensorium files ## How to Apply ```bash # 1. Pull the latest repo git pull # 2. Merge multi-part patch files python patch_v1/merge_patch_parts.py # 3. Apply the full-file replacements python patch_v1/apply_sensorium_companion_patch.py # 4. Manually patch heartbeat_mixin.py # Replace the heartbeat_action() method with the version in: # patch_v1/heartbeat_mixin_patch.py # 5. Manually patch app.py # Add the helper functions and UI elements from: # patch_v1/app_settings_patch.py # to the Settings tab # 6. Install new dependencies pip install pytesseract Pillow sounddevice soundfile faster-whisper # For OCR (system package): # Ubuntu: sudo apt-get install tesseract-ocr # macOS: brew install tesseract # 7. Test python check.py ``` ## File Index | File | Description | |---|---| | `media_companion_mixin.py` | Part 1: init, settings, media sensing | | `media_companion_mixin_part2.py` | Part 2: reaction pipeline | | `media_companion_mixin_part3.py` | Part 3: anti-repetition, lens, voice, taste | | `media_companion_mixin_part4.py` | Part 4: logging, taste model, status | | `sensorium_mixin.py` | Part 1: init, watchers, screen capture | | `sensorium_mixin_part2.py` | Part 2: OCR digest, audio tools | | `sensorium_mixin_part3.py` | Part 3: expanded pulse, storage | | `audition_mixin.py` | Part 1: init, device selection | | `audition_mixin_part2.py` | Part 2: recording, transcription, classification | | `audition_mixin_part3.py` | Part 3: cleanup, storage, tools | | `heartbeat_mixin_patch.py` | Patched heartbeat_action() method | | `app_settings_patch.py` | Settings UI helpers and elements | | `merge_patch_parts.py` | Script to merge parts into complete files | | `apply_sensorium_companion_patch.py` | Script to apply merged files | ## Privacy Guards - Audio capture is **opt-in** and defaults to disabled - Loopback device selection is explicit; never silently falls back to microphone - Screen captures are local files only; never uploaded - Credential patterns are redacted from clipboard/window memory - UI toggle can disable screen/audio capture immediately ## Ψ-Calculus Tagging | Symbol | Priority | Scope | |---|---|---| | `[[ΔΩ]]` | 1st | AuditionMixin, screen digest, audio/screen tables, heartbeat wiring | | `[[ΔI]]` | 2nd | Anti-repetition, lens rotation, audio disambiguation | | `[[ΔL]]` | 3rd | Deeper companion voice, narrative taste, direct operator address |