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:
23
bot/api.py
23
bot/api.py
@@ -307,6 +307,13 @@ def set_language_mode(language: str = "english"):
|
|||||||
model_used = globals.JAPANESE_TEXT_MODEL if language.lower() == "japanese" else globals.TEXT_MODEL
|
model_used = globals.JAPANESE_TEXT_MODEL if language.lower() == "japanese" else globals.TEXT_MODEL
|
||||||
logger.info(f"Language mode set to {language.lower()} (using {model_used})")
|
logger.info(f"Language mode set to {language.lower()} (using {model_used})")
|
||||||
|
|
||||||
|
# Persist so it survives restarts
|
||||||
|
try:
|
||||||
|
from config_manager import config_manager
|
||||||
|
config_manager.set("discord.language_mode", language.lower(), persist=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"language_mode": language.lower(),
|
"language_mode": language.lower(),
|
||||||
@@ -2963,6 +2970,14 @@ def set_voice_debug_mode(enabled: bool = Form(...)):
|
|||||||
"""Set voice debug mode (shows transcriptions and responses in text channel)"""
|
"""Set voice debug mode (shows transcriptions and responses in text channel)"""
|
||||||
globals.VOICE_DEBUG_MODE = enabled
|
globals.VOICE_DEBUG_MODE = enabled
|
||||||
logger.info(f"Voice debug mode set to: {enabled}")
|
logger.info(f"Voice debug mode set to: {enabled}")
|
||||||
|
|
||||||
|
# Persist so it survives restarts
|
||||||
|
try:
|
||||||
|
from config_manager import config_manager
|
||||||
|
config_manager.set("voice.debug_mode", enabled, persist=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"debug_mode": enabled,
|
"debug_mode": enabled,
|
||||||
@@ -3004,6 +3019,14 @@ async def toggle_cat_integration(enabled: bool = Form(...)):
|
|||||||
"""Toggle Cheshire Cat integration on/off."""
|
"""Toggle Cheshire Cat integration on/off."""
|
||||||
globals.USE_CHESHIRE_CAT = enabled
|
globals.USE_CHESHIRE_CAT = enabled
|
||||||
logger.info(f"🐱 Cheshire Cat integration {'ENABLED' if enabled else 'DISABLED'}")
|
logger.info(f"🐱 Cheshire Cat integration {'ENABLED' if enabled else 'DISABLED'}")
|
||||||
|
|
||||||
|
# Persist so it survives restarts
|
||||||
|
try:
|
||||||
|
from config_manager import config_manager
|
||||||
|
config_manager.set("memory.use_cheshire_cat", enabled, persist=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"enabled": globals.USE_CHESHIRE_CAT,
|
"enabled": globals.USE_CHESHIRE_CAT,
|
||||||
|
|||||||
@@ -105,6 +105,10 @@ async def on_ready():
|
|||||||
from utils.bipolar_mode import restore_bipolar_mode_on_startup
|
from utils.bipolar_mode import restore_bipolar_mode_on_startup
|
||||||
restore_bipolar_mode_on_startup()
|
restore_bipolar_mode_on_startup()
|
||||||
|
|
||||||
|
# Restore runtime settings (language, debug flags, etc.) from config_runtime.yaml
|
||||||
|
from config_manager import config_manager
|
||||||
|
config_manager.restore_runtime_settings()
|
||||||
|
|
||||||
# Initialize DM interaction analyzer
|
# Initialize DM interaction analyzer
|
||||||
if globals.OWNER_USER_ID and globals.OWNER_USER_ID != 0:
|
if globals.OWNER_USER_ID and globals.OWNER_USER_ID != 0:
|
||||||
init_dm_analyzer(globals.OWNER_USER_ID)
|
init_dm_analyzer(globals.OWNER_USER_ID)
|
||||||
|
|||||||
@@ -102,6 +102,54 @@ class ConfigManager:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"❌ Failed to load GPU state: {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:
|
def get(self, key_path: str, default: Any = None) -> Any:
|
||||||
"""
|
"""
|
||||||
Get configuration value with priority system.
|
Get configuration value with priority system.
|
||||||
|
|||||||
Reference in New Issue
Block a user