File size: 8,002 Bytes
4e334ba | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #!/usr/bin/env python3
"""
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
# ================================================================
# PATCH 1: Add sensorium helper functions (after apply_audio_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)
# ================================================================
# PATCH 2: Add UI section in Settings tab
# Find the settings section and add sensorium controls
# ================================================================
# Find the end of the Settings tab to insert before it closes
# We'll insert after the temperament section
insert_marker = 'def build_temp_preview():'
ui_block = '''# ==================================================================
# GRADIO UI — SENSORIUM AWARENESS SECTION
# ==================================================================
'''
# Actually, we need to insert the UI controls into the Gradio Blocks section
# Find the Settings tab content and add sensorium section
# Look for the trigger_rem line which is near the end of settings
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)
# Also need to add the UI elements to the Settings tab
# Find a good insertion point in the Settings tab
# Look for the temperament accordion or similar
temp_marker = ' apply_temperament(expr, earnest, autonomy, temp):'
if temp_marker in patched:
# Insert UI block definition before the function
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.
'''
# Write patched file
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()
|