fix(config): persist runtime settings across bot restarts

Add restore_runtime_settings() to ConfigManager that reads config_runtime.yaml
on startup and restores persisted values into globals:
- LANGUAGE_MODE, AUTONOMOUS_DEBUG, VOICE_DEBUG_MODE
- USE_CHESHIRE_CAT, PREFER_AMD_GPU, DM_MOOD

Add missing persistence calls to API endpoints:
- POST /language/set now persists to config_runtime.yaml
- POST /voice/debug-mode now persists to config_runtime.yaml
- POST /memory/toggle now persists to config_runtime.yaml

Call restore_runtime_settings() in on_ready() after evil/bipolar restore.

Resolves #22
This commit is contained in:
2026-02-18 12:18:12 +02:00
parent 8d5137046c
commit d44f08af18
3 changed files with 75 additions and 0 deletions

View File

@@ -102,6 +102,54 @@ class ConfigManager:
except Exception as e:
logger.error(f"❌ Failed to load GPU state: {e}")
def restore_runtime_settings(self):
"""
Restore persisted runtime settings from config_runtime.yaml into globals.
Called once at startup (in on_ready) so that settings changed via the
Web UI or API survive bot restarts.
Settings with their own persistence (EVIL_MODE, BIPOLAR_MODE) are
handled by their respective modules and are intentionally skipped here.
"""
import globals as g
# Map: config_runtime.yaml key path -> (globals attribute, converter)
_SETTINGS_MAP = {
"discord.language_mode": ("LANGUAGE_MODE", str),
"autonomous.debug_mode": ("AUTONOMOUS_DEBUG", bool),
"voice.debug_mode": ("VOICE_DEBUG_MODE", bool),
"memory.use_cheshire_cat": ("USE_CHESHIRE_CAT", bool),
"gpu.prefer_amd": ("PREFER_AMD_GPU", bool),
}
restored = []
for key_path, (attr, converter) in _SETTINGS_MAP.items():
value = self._get_nested_value(self.runtime_config, key_path)
if value is not None:
try:
setattr(g, attr, converter(value))
restored.append(f"{attr}={getattr(g, attr)}")
except (ValueError, TypeError) as exc:
logger.warning(f"⚠️ Could not restore {key_path}: {exc}")
# DM mood needs special handling (load description too)
dm_mood = self._get_nested_value(self.runtime_config, "runtime.mood.dm_mood")
if dm_mood and isinstance(dm_mood, str) and dm_mood in getattr(g, "AVAILABLE_MOODS", []):
g.DM_MOOD = dm_mood
try:
from utils.moods import load_mood_description
g.DM_MOOD_DESCRIPTION = load_mood_description(dm_mood)
except Exception:
g.DM_MOOD_DESCRIPTION = f"I'm feeling {dm_mood} today."
restored.append(f"DM_MOOD={dm_mood}")
if restored:
logger.info(f"🔄 Restored {len(restored)} runtime settings: {', '.join(restored)}")
else:
logger.debug(" No runtime settings to restore")
def get(self, key_path: str, default: Any = None) -> Any:
"""
Get configuration value with priority system.