| |
| """ |
| apply_app_sensorium_settings_patch.py — Patches app.py to add Settings UI |
| toggles for screen awareness, desktop audio awareness, and sensorium status. |
| |
| Adds: |
| 1. Helper functions: toggle_screen_awareness, toggle_audio_awareness, |
| get_sensorium_status, do_sensorium_cleanup |
| 2. UI section in Settings tab: "Sensorium Awareness" accordion with toggles |
| 3. Event handlers wired to the new UI controls |
| |
| Run from the Sir Radix project root: |
| python apply_app_sensorium_settings_patch.py |
| """ |
| import sys |
| import os |
| import shutil |
| from datetime import datetime |
|
|
| TARGET = "app.py" |
| BACKUP = f"app.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 |
|
|
| |
| |
| |
| insert_after = '''def apply_audio_source(source): |
| try: |
| mapping = { |
| "Auto": "auto", |
| "Microphone": "microphone", |
| "Desktop (VB-Cable/Loopback)": "desktop", |
| } |
| clean = mapping.get(source, source.lower().strip()) |
| if hasattr(daemon, "set_audio_source"): |
| daemon.set_audio_source(clean) |
| else: |
| os.environ["RADIX_AUDIO_SOURCE"] = clean |
| return f"Audio source: {clean}" |
| except Exception as e: |
| logger.exception("Audio source update failed") |
| return f"Error: {e}"''' |
|
|
| new_helpers = insert_after + ''' |
| |
| # ================================================================== |
| # SENSORIUM AWARENESS SETTINGS |
| # ================================================================== |
| def toggle_screen_awareness(enabled): |
| try: |
| daemon.set_screen_awareness(enabled) |
| status = "enabled" if enabled else "disabled" |
| return f"Screen awareness {status}.", get_sensorium_status_md() |
| except Exception as e: |
| return f"Error: {e}", get_sensorium_status_md() |
| |
| def toggle_audio_awareness(enabled): |
| try: |
| daemon.set_audio_awareness(enabled) |
| if hasattr(daemon, "set_audition_enabled"): |
| daemon.set_audition_enabled(enabled) |
| status = "enabled" if enabled else "disabled" |
| return f"Audio awareness {status}.", get_sensorium_status_md() |
| except Exception as e: |
| return f"Error: {e}", get_sensorium_status_md() |
| |
| def get_sensorium_status_md(): |
| try: |
| s = daemon.get_sensorium_status() |
| lines = ["**Sensorium Status**\\n"] |
| screen = "🟢 ON" if s.get("screen_enabled") else "🔴 OFF" |
| audio = "🟢 ON" if s.get("audio_enabled") else "🔴 OFF" |
| lines.append(f"- Screen awareness: **{screen}**") |
| lines.append(f"- Audio awareness: **{audio}**") |
| lines.append(f"- OCR available: `{s.get('ocr_available', False)}`") |
| lines.append(f"- Screen digest interval: every {s.get('screen_digest_interval', '?')} heartbeats") |
| if s.get("last_screen_digest"): |
| lines.append(f"\\n**Last screen digest:**\\n> {s['last_screen_digest'][:150]}...") |
| if s.get("last_audio_transcript"): |
| lines.append(f"\\n**Last audio transcript:**\\n> {s['last_audio_transcript'][:150]}...") |
| return "\\n".join(lines) |
| except Exception as e: |
| return f"⚠️ Sensorium status error: {e}" |
| |
| def do_sensorium_cleanup(): |
| try: |
| daemon._prune_sensorium_storage(max_gb=1.0) |
| return "Sensorium storage pruned to 1GB cap.", get_sensorium_status_md() |
| except Exception as e: |
| return f"Error: {e}", get_sensorium_status_md()''' |
|
|
| patched = patched.replace(insert_after, new_helpers) |
|
|
| |
| |
| |
| |
| |
| |
| insert_marker = 'def build_temp_preview():' |
| ui_block = '''# ================================================================== |
| # GRADIO UI — SENSORIUM AWARENESS SECTION |
| # ================================================================== |
| |
| ''' |
|
|
| |
| |
| |
| settings_marker = ' trigger_rem.click(lambda: daemon.pseudo_rem_cycle(), outputs=[tx_status])\n review_code.click(lambda: daemon.review_own_code(), outputs=[tx_status])' |
|
|
| if settings_marker in patched: |
| sensorium_bindings = settings_marker + ''' |
| # Sensorium awareness event handlers |
| screen_awareness_btn.click(fn=toggle_screen_awareness, inputs=[screen_toggle], outputs=[sensorium_result, sensorium_status_md]) |
| audio_awareness_btn.click(fn=toggle_audio_awareness, inputs=[audio_toggle], outputs=[sensorium_result, sensorium_status_md]) |
| refresh_sensorium_btn.click(fn=get_sensorium_status_md, outputs=[sensorium_status_md]) |
| sensorium_cleanup_btn.click(fn=do_sensorium_cleanup, outputs=[sensorium_result, sensorium_status_md])''' |
| patched = patched.replace(settings_marker, sensorium_bindings) |
|
|
| |
| |
| |
| temp_marker = ' apply_temperament(expr, earnest, autonomy, temp):' |
| if temp_marker in patched: |
| |
| ui_definition = '''# ================================================================== |
| # SENSORIUM UI ELEMENTS (defined for use in Settings tab) |
| # ================================================================== |
| # These are created when the Settings tab is built. |
| # The actual Gradio components are inserted into the Settings tab below. |
| |
| ''' |
|
|
| |
| 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" - toggle_screen_awareness() / toggle_audio_awareness() helpers") |
| print(f" - get_sensorium_status_md() for UI display") |
| print(f" - do_sensorium_cleanup() for storage management") |
| print(f" - Event handlers for sensorium toggles") |
| print(f" ") |
| print(f" ⚠️ MANUAL STEP REQUIRED:") |
| print(f" You need to add these Gradio components to your Settings tab:") |
| print(f" ") |
| print(f" with gr.Accordion('Sensorium Awareness', open=False):") |
| print(f" sensorium_status_md = gr.Markdown(value=get_sensorium_status_md())") |
| print(f" with gr.Row():") |
| print(f" screen_toggle = gr.Checkbox(label='Enable Screen Awareness', value=False)") |
| print(f" screen_awareness_btn = gr.Button('Apply', size='sm')") |
| print(f" with gr.Row():") |
| print(f" audio_toggle = gr.Checkbox(label='Enable Desktop Audio', value=False)") |
| print(f" audio_awareness_btn = gr.Button('Apply', size='sm')") |
| print(f" with gr.Row():") |
| print(f" refresh_sensorium_btn = gr.Button('⟳ Refresh', size='sm')") |
| print(f" sensorium_cleanup_btn = gr.Button('🗑 Prune Storage', size='sm')") |
| print(f" sensorium_result = gr.Markdown()") |
| print(f" ") |
| print(f" Also rename the old 'apply_audio_btn' to 'audio_source_btn' to avoid") |
| print(f" the duplicate binding bug you found.") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|