feat: Implement comprehensive non-hierarchical logging system
- Created new logging infrastructure with per-component filtering - Added 6 log levels: DEBUG, INFO, API, WARNING, ERROR, CRITICAL - Implemented non-hierarchical level control (any combination can be enabled) - Migrated 917 print() statements across 31 files to structured logging - Created web UI (system.html) for runtime configuration with dark theme - Added global level controls to enable/disable levels across all components - Added timestamp format control (off/time/date/datetime options) - Implemented log rotation (10MB per file, 5 backups) - Added API endpoints for dynamic log configuration - Configured HTTP request logging with filtering via api.requests component - Intercepted APScheduler logs with proper formatting - Fixed persistence paths to use /app/memory for Docker volume compatibility - Fixed checkbox display bug in web UI (enabled_levels now properly shown) - Changed System Settings button to open in same tab instead of new window Components: bot, api, api.requests, autonomous, persona, vision, llm, conversation, mood, dm, scheduled, gpu, media, server, commands, sentiment, core, apscheduler All settings persist across container restarts via JSON config.
This commit is contained in:
@@ -12,6 +12,9 @@ from typing import Dict, List, Optional
|
||||
from collections import deque
|
||||
import discord
|
||||
from .autonomous_persistence import save_autonomous_context, load_autonomous_context, apply_context_to_signals
|
||||
from utils.logger import get_logger
|
||||
|
||||
logger = get_logger('autonomous')
|
||||
|
||||
@dataclass
|
||||
class ContextSignals:
|
||||
@@ -238,13 +241,13 @@ class AutonomousEngine:
|
||||
time_since_startup = time.time() - self.bot_startup_time
|
||||
if time_since_startup < 120: # 2 minutes
|
||||
if debug:
|
||||
print(f"⏳ [V2 Debug] Startup cooldown active ({time_since_startup:.0f}s / 120s)")
|
||||
logger.debug(f"[V2 Debug] Startup cooldown active ({time_since_startup:.0f}s / 120s)")
|
||||
return None
|
||||
|
||||
# Never act when asleep
|
||||
if ctx.current_mood == "asleep":
|
||||
if debug:
|
||||
print(f"💤 [V2 Debug] Mood is 'asleep' - no action taken")
|
||||
logger.debug(f"[V2 Debug] Mood is 'asleep' - no action taken")
|
||||
return None
|
||||
|
||||
# Get mood personality
|
||||
@@ -254,14 +257,14 @@ class AutonomousEngine:
|
||||
self._update_activity_metrics(guild_id)
|
||||
|
||||
if debug:
|
||||
print(f"\n🔍 [V2 Debug] Decision Check for Guild {guild_id}")
|
||||
print(f" Triggered by message: {triggered_by_message}")
|
||||
print(f" Mood: {ctx.current_mood} (energy={profile['energy']:.2f}, sociability={profile['sociability']:.2f}, impulsiveness={profile['impulsiveness']:.2f})")
|
||||
print(f" Momentum: {ctx.conversation_momentum:.2f}")
|
||||
print(f" Messages (5min/1hr): {ctx.messages_last_5min}/{ctx.messages_last_hour}")
|
||||
print(f" Messages since appearance: {ctx.messages_since_last_appearance}")
|
||||
print(f" Time since last action: {ctx.time_since_last_action:.0f}s")
|
||||
print(f" Active activities: {len(ctx.users_started_activity)}")
|
||||
logger.debug(f"\n[V2 Debug] Decision Check for Guild {guild_id}")
|
||||
logger.debug(f" Triggered by message: {triggered_by_message}")
|
||||
logger.debug(f" Mood: {ctx.current_mood} (energy={profile['energy']:.2f}, sociability={profile['sociability']:.2f}, impulsiveness={profile['impulsiveness']:.2f})")
|
||||
logger.debug(f" Momentum: {ctx.conversation_momentum:.2f}")
|
||||
logger.debug(f" Messages (5min/1hr): {ctx.messages_last_5min}/{ctx.messages_last_hour}")
|
||||
logger.debug(f" Messages since appearance: {ctx.messages_since_last_appearance}")
|
||||
logger.debug(f" Time since last action: {ctx.time_since_last_action:.0f}s")
|
||||
logger.debug(f" Active activities: {len(ctx.users_started_activity)}")
|
||||
|
||||
# --- Decision Logic ---
|
||||
|
||||
@@ -272,7 +275,7 @@ class AutonomousEngine:
|
||||
# 1. CONVERSATION JOIN (high priority when momentum is high)
|
||||
if self._should_join_conversation(ctx, profile, debug):
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: join_conversation")
|
||||
logger.debug(f"[V2 Debug] DECISION: join_conversation")
|
||||
return "join_conversation"
|
||||
|
||||
# 2. USER ENGAGEMENT (someone interesting appeared)
|
||||
@@ -280,17 +283,17 @@ class AutonomousEngine:
|
||||
if triggered_by_message:
|
||||
# Convert to join_conversation when message-triggered
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: join_conversation (engage_user converted due to message trigger)")
|
||||
logger.debug(f"[V2 Debug] DECISION: join_conversation (engage_user converted due to message trigger)")
|
||||
return "join_conversation"
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: engage_user")
|
||||
logger.debug(f"[V2 Debug] DECISION: engage_user")
|
||||
return "engage_user"
|
||||
|
||||
# 3. FOMO RESPONSE (lots of activity without her)
|
||||
# When FOMO triggers, join the conversation instead of saying something random
|
||||
if self._should_respond_to_fomo(ctx, profile, debug):
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: join_conversation (FOMO)")
|
||||
logger.debug(f"[V2 Debug] DECISION: join_conversation (FOMO)")
|
||||
return "join_conversation" # Jump in and respond to what's being said
|
||||
|
||||
# 4. BORED/LONELY (quiet for too long, depending on mood)
|
||||
@@ -299,29 +302,29 @@ class AutonomousEngine:
|
||||
if self._should_break_silence(ctx, profile, debug):
|
||||
if triggered_by_message:
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: join_conversation (break silence, but message just sent)")
|
||||
logger.debug(f"[V2 Debug] DECISION: join_conversation (break silence, but message just sent)")
|
||||
return "join_conversation" # Respond to the message instead of random general statement
|
||||
else:
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: general (break silence)")
|
||||
logger.debug(f"[V2 Debug] DECISION: general (break silence)")
|
||||
return "general"
|
||||
|
||||
# 5. SHARE TWEET (low activity, wants to share something)
|
||||
# Skip this entirely when triggered by message - would be inappropriate to ignore user's message
|
||||
if not triggered_by_message and self._should_share_content(ctx, profile, debug):
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: share_tweet")
|
||||
logger.debug(f"[V2 Debug] DECISION: share_tweet")
|
||||
return "share_tweet"
|
||||
|
||||
# 6. CHANGE PROFILE PICTURE (very rare, once per day)
|
||||
# Skip this entirely when triggered by message
|
||||
if not triggered_by_message and self._should_change_profile_picture(ctx, profile, debug):
|
||||
if debug:
|
||||
print(f"✅ [V2 Debug] DECISION: change_profile_picture")
|
||||
logger.debug(f"[V2 Debug] DECISION: change_profile_picture")
|
||||
return "change_profile_picture"
|
||||
|
||||
if debug:
|
||||
print(f"❌ [V2 Debug] DECISION: None (no conditions met)")
|
||||
logger.debug(f"[V2 Debug] DECISION: None (no conditions met)")
|
||||
|
||||
return None
|
||||
|
||||
@@ -341,10 +344,10 @@ class AutonomousEngine:
|
||||
result = all(conditions.values())
|
||||
|
||||
if debug:
|
||||
print(f" [Join Conv] momentum={ctx.conversation_momentum:.2f} > {mood_adjusted:.2f}? {conditions['momentum_check']}")
|
||||
print(f" [Join Conv] messages={ctx.messages_since_last_appearance} >= 5? {conditions['messages_check']}")
|
||||
print(f" [Join Conv] cooldown={ctx.time_since_last_action:.0f}s > 300s? {conditions['cooldown_check']}")
|
||||
print(f" [Join Conv] impulsive roll? {conditions['impulsiveness_roll']} | Result: {result}")
|
||||
logger.debug(f" [Join Conv] momentum={ctx.conversation_momentum:.2f} > {mood_adjusted:.2f}? {conditions['momentum_check']}")
|
||||
logger.debug(f" [Join Conv] messages={ctx.messages_since_last_appearance} >= 5? {conditions['messages_check']}")
|
||||
logger.debug(f" [Join Conv] cooldown={ctx.time_since_last_action:.0f}s > 300s? {conditions['cooldown_check']}")
|
||||
logger.debug(f" [Join Conv] impulsive roll? {conditions['impulsiveness_roll']} | Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
@@ -361,8 +364,8 @@ class AutonomousEngine:
|
||||
|
||||
if debug and has_activities:
|
||||
activities = [name for name, ts in ctx.users_started_activity]
|
||||
print(f" [Engage] activities={activities}, cooldown={ctx.time_since_last_action:.0f}s > 1800s? {cooldown_ok}")
|
||||
print(f" [Engage] roll={roll:.2f} < {threshold:.2f}? {roll_ok} | Result: {result}")
|
||||
logger.debug(f" [Engage] activities={activities}, cooldown={ctx.time_since_last_action:.0f}s > 1800s? {cooldown_ok}")
|
||||
logger.debug(f" [Engage] roll={roll:.2f} < {threshold:.2f}? {roll_ok} | Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
@@ -378,9 +381,9 @@ class AutonomousEngine:
|
||||
result = msgs_check and momentum_check and cooldown_check
|
||||
|
||||
if debug:
|
||||
print(f" [FOMO] messages={ctx.messages_since_last_appearance} > {fomo_threshold:.0f}? {msgs_check}")
|
||||
print(f" [FOMO] momentum={ctx.conversation_momentum:.2f} > 0.3? {momentum_check}")
|
||||
print(f" [FOMO] cooldown={ctx.time_since_last_action:.0f}s > 900s? {cooldown_check} | Result: {result}")
|
||||
logger.debug(f" [FOMO] messages={ctx.messages_since_last_appearance} > {fomo_threshold:.0f}? {msgs_check}")
|
||||
logger.debug(f" [FOMO] momentum={ctx.conversation_momentum:.2f} > 0.3? {momentum_check}")
|
||||
logger.debug(f" [FOMO] cooldown={ctx.time_since_last_action:.0f}s > 900s? {cooldown_check} | Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
@@ -397,9 +400,9 @@ class AutonomousEngine:
|
||||
result = quiet_check and silence_check and energy_ok
|
||||
|
||||
if debug:
|
||||
print(f" [Silence] msgs_last_hour={ctx.messages_last_hour} < 5? {quiet_check}")
|
||||
print(f" [Silence] time={ctx.time_since_last_action:.0f}s > {min_silence:.0f}s? {silence_check}")
|
||||
print(f" [Silence] energy roll={energy_roll:.2f} < {profile['energy']:.2f}? {energy_ok} | Result: {result}")
|
||||
logger.debug(f" [Silence] msgs_last_hour={ctx.messages_last_hour} < 5? {quiet_check}")
|
||||
logger.debug(f" [Silence] time={ctx.time_since_last_action:.0f}s > {min_silence:.0f}s? {silence_check}")
|
||||
logger.debug(f" [Silence] energy roll={energy_roll:.2f} < {profile['energy']:.2f}? {energy_ok} | Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
@@ -416,10 +419,10 @@ class AutonomousEngine:
|
||||
result = quiet_check and cooldown_check and energy_ok and mood_ok
|
||||
|
||||
if debug:
|
||||
print(f" [Share] msgs_last_hour={ctx.messages_last_hour} < 10? {quiet_check}")
|
||||
print(f" [Share] cooldown={ctx.time_since_last_action:.0f}s > 3600s? {cooldown_check}")
|
||||
print(f" [Share] energy roll={energy_roll:.2f} < {energy_threshold:.2f}? {energy_ok}")
|
||||
print(f" [Share] mood '{ctx.current_mood}' appropriate? {mood_ok} | Result: {result}")
|
||||
logger.debug(f" [Share] msgs_last_hour={ctx.messages_last_hour} < 10? {quiet_check}")
|
||||
logger.debug(f" [Share] cooldown={ctx.time_since_last_action:.0f}s > 3600s? {cooldown_check}")
|
||||
logger.debug(f" [Share] energy roll={energy_roll:.2f} < {energy_threshold:.2f}? {energy_ok}")
|
||||
logger.debug(f" [Share] mood '{ctx.current_mood}' appropriate? {mood_ok} | Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
@@ -447,11 +450,11 @@ class AutonomousEngine:
|
||||
|
||||
if hours_since_change < 20: # At least 20 hours between changes
|
||||
if debug:
|
||||
print(f" [PFP] Last change {hours_since_change:.1f}h ago, waiting...")
|
||||
logger.debug(f" [PFP] Last change {hours_since_change:.1f}h ago, waiting...")
|
||||
return False
|
||||
except Exception as e:
|
||||
if debug:
|
||||
print(f" [PFP] Error checking last change: {e}")
|
||||
logger.debug(f" [PFP] Error checking last change: {e}")
|
||||
|
||||
# Only consider changing during certain hours (10 AM - 10 PM)
|
||||
hour = ctx.hour_of_day
|
||||
@@ -472,11 +475,11 @@ class AutonomousEngine:
|
||||
result = time_check and quiet_check and cooldown_check and roll_ok
|
||||
|
||||
if debug:
|
||||
print(f" [PFP] hour={hour}, time_ok={time_check}")
|
||||
print(f" [PFP] msgs_last_hour={ctx.messages_last_hour} < 5? {quiet_check}")
|
||||
print(f" [PFP] cooldown={ctx.time_since_last_action:.0f}s > 5400s? {cooldown_check}")
|
||||
print(f" [PFP] mood_boost={mood_boost}, roll={roll:.4f} < {base_chance:.4f}? {roll_ok}")
|
||||
print(f" [PFP] Result: {result}")
|
||||
logger.debug(f" [PFP] hour={hour}, time_ok={time_check}")
|
||||
logger.debug(f" [PFP] msgs_last_hour={ctx.messages_last_hour} < 5? {quiet_check}")
|
||||
logger.debug(f" [PFP] cooldown={ctx.time_since_last_action:.0f}s > 5400s? {cooldown_check}")
|
||||
logger.debug(f" [PFP] mood_boost={mood_boost}, roll={roll:.4f} < {base_chance:.4f}? {roll_ok}")
|
||||
logger.debug(f" [PFP] Result: {result}")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
Reference in New Issue
Block a user