2025-12-07 17:15:09 +02:00
|
|
|
import discord
|
|
|
|
|
import asyncio
|
|
|
|
|
import threading
|
|
|
|
|
import uvicorn
|
|
|
|
|
import logging
|
|
|
|
|
import sys
|
|
|
|
|
import random
|
|
|
|
|
import string
|
|
|
|
|
import signal
|
|
|
|
|
import atexit
|
|
|
|
|
from api import app
|
|
|
|
|
|
2026-02-18 12:01:08 +02:00
|
|
|
# Import new configuration system
|
|
|
|
|
from config import CONFIG, SECRETS, validate_config, print_config_summary
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
from server_manager import server_manager
|
2026-02-20 15:37:57 +02:00
|
|
|
from config_manager import config_manager
|
2025-12-07 17:15:09 +02:00
|
|
|
from utils.scheduled import (
|
|
|
|
|
send_monday_video
|
|
|
|
|
)
|
|
|
|
|
from utils.image_handling import (
|
|
|
|
|
download_and_encode_image,
|
|
|
|
|
download_and_encode_media,
|
|
|
|
|
extract_video_frames,
|
|
|
|
|
analyze_image_with_qwen,
|
|
|
|
|
analyze_video_with_vision,
|
|
|
|
|
rephrase_as_miku,
|
|
|
|
|
extract_tenor_gif_url,
|
|
|
|
|
convert_gif_to_mp4,
|
|
|
|
|
extract_embed_content
|
|
|
|
|
)
|
|
|
|
|
from utils.core import (
|
|
|
|
|
is_miku_addressed,
|
|
|
|
|
)
|
|
|
|
|
from utils.moods import (
|
|
|
|
|
detect_mood_shift
|
|
|
|
|
)
|
|
|
|
|
from utils.media import(
|
|
|
|
|
overlay_username_with_ffmpeg
|
|
|
|
|
)
|
2025-12-07 17:50:08 +02:00
|
|
|
from utils.llm import query_llama
|
2025-12-07 17:15:09 +02:00
|
|
|
from utils.autonomous import (
|
2026-02-18 12:01:08 +02:00
|
|
|
setup_autonomous_speaking,
|
2025-12-07 17:15:09 +02:00
|
|
|
load_last_sent_tweets,
|
|
|
|
|
# V2 imports
|
|
|
|
|
on_message_event,
|
|
|
|
|
on_presence_update as autonomous_presence_update,
|
|
|
|
|
on_member_join as autonomous_member_join,
|
|
|
|
|
initialize_v2_system
|
|
|
|
|
)
|
|
|
|
|
from utils.dm_logger import dm_logger
|
|
|
|
|
from utils.dm_interaction_analyzer import init_dm_analyzer
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
from utils.logger import get_logger
|
2026-02-18 12:01:08 +02:00
|
|
|
from utils.task_tracker import create_tracked_task
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
import globals
|
|
|
|
|
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
# Initialize bot logger
|
|
|
|
|
logger = get_logger('bot')
|
|
|
|
|
|
2026-02-18 12:01:08 +02:00
|
|
|
# Validate configuration on startup
|
|
|
|
|
is_valid, validation_errors = validate_config()
|
|
|
|
|
if not is_valid:
|
|
|
|
|
logger.error("❌ Configuration validation failed!")
|
|
|
|
|
for error in validation_errors:
|
|
|
|
|
logger.error(f" - {error}")
|
|
|
|
|
logger.error("Please check your .env file and restart.")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
# Print configuration summary for debugging
|
|
|
|
|
if CONFIG.autonomous.debug_mode:
|
|
|
|
|
print_config_summary()
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
logging.basicConfig(
|
|
|
|
|
level=logging.INFO,
|
|
|
|
|
format="%(asctime)s %(levelname)s: %(message)s",
|
|
|
|
|
handlers=[
|
|
|
|
|
logging.FileHandler("bot.log", mode='a', encoding='utf-8'),
|
|
|
|
|
logging.StreamHandler(sys.stdout) # Optional: see logs in stdout too
|
|
|
|
|
],
|
|
|
|
|
force=True # Override previous configs
|
|
|
|
|
)
|
|
|
|
|
|
2026-01-19 00:29:44 +02:00
|
|
|
# Reduce noise from discord voice receiving library
|
|
|
|
|
# CryptoErrors are routine packet decode failures (joins/leaves/key negotiation)
|
|
|
|
|
# RTCP packets are control packets sent every ~1s
|
|
|
|
|
# Both are harmless and just clutter logs
|
|
|
|
|
logging.getLogger('discord.ext.voice_recv.reader').setLevel(logging.CRITICAL) # Only show critical errors
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
@globals.client.event
|
|
|
|
|
async def on_ready():
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f'🎤 MikuBot connected as {globals.client.user}')
|
|
|
|
|
logger.info(f'💬 DM support enabled - users can message Miku directly!')
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
globals.BOT_USER = globals.client.user
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
|
|
|
|
|
# Intercept external library loggers (APScheduler, etc.)
|
|
|
|
|
from utils.logger import intercept_external_loggers
|
|
|
|
|
intercept_external_loggers()
|
2025-12-07 17:15:09 +02:00
|
|
|
|
2026-01-02 17:11:58 +02:00
|
|
|
# Restore evil mode state from previous session (if any)
|
2026-03-01 00:26:22 +02:00
|
|
|
from utils.evil_mode import restore_evil_mode_on_startup, restore_evil_cat_state
|
2026-01-02 17:11:58 +02:00
|
|
|
restore_evil_mode_on_startup()
|
Implement Bipolar Mode: Dual persona arguments with webhooks, LLM arbiter, and persistent scoreboard
Major Features:
- Complete Bipolar Mode system allowing Regular Miku and Evil Miku to coexist and argue via webhooks
- LLM arbiter system using neutral model to judge argument winners with detailed reasoning
- Persistent scoreboard tracking wins, percentages, and last 50 results with timestamps and reasoning
- Automatic mode switching based on argument winner
- Webhook management per channel with profile pictures and display names
- Progressive probability system for dynamic argument lengths (starts at 10%, increases 5% per exchange, min 4 exchanges)
- Draw handling with penalty system (-5% end chance, continues argument)
- Integration with autonomous system for random argument triggers
Argument System:
- MIN_EXCHANGES = 4, progressive end chance starting at 10%
- Enhanced prompts for both personas (strategic, short, punchy responses 1-3 sentences)
- Evil Miku triumphant victory messages with gloating and satisfaction
- Regular Miku assertive defense (not passive, shows backbone)
- Message-based argument starting (can respond to specific messages via ID)
- Conversation history tracking per argument with special user_id
- Full context queries (personality, lore, lyrics, last 8 messages)
LLM Arbiter:
- Decisive prompt emphasizing picking winners (draws should be rare)
- Improved parsing with first-line exact matching and fallback counting
- Debug logging for decision transparency
- Arbiter reasoning stored in scoreboard history for review
- Uses neutral TEXT_MODEL (not evil) for unbiased judgment
Web UI & API:
- Bipolar mode toggle button (only visible when evil mode is on)
- Channel ID + Message ID input fields for argument triggering
- Scoreboard display with win percentages and recent history
- Manual argument trigger endpoint with string-based IDs
- GET /bipolar-mode/scoreboard endpoint for stats retrieval
- Real-time active arguments tracking (refreshes every 5 seconds)
Prompt Optimizations:
- All argument prompts limited to 1-3 sentences for impact
- Evil Miku system prompt with variable response length guidelines
- Removed walls of text, emphasizing brevity and precision
- "Sometimes the cruelest response is the shortest one"
Evil Miku Updates:
- Added height to lore (15.8m tall, 10x bigger than regular Miku)
- Height added to prompt facts for size-based belittling
- More strategic and calculating personality in arguments
Integration:
- Bipolar mode state restoration on bot startup
- Bot skips processing messages during active arguments
- Autonomous system checks for bipolar triggers after actions
- Import fixes (apply_evil_mode_changes/revert_evil_mode_changes)
Technical Details:
- State persistence via JSON (bipolar_mode_state.json, bipolar_webhooks.json, bipolar_scoreboard.json)
- Webhook caching per guild with fallback creation
- Event loop management with asyncio.create_task
- Rate limiting and argument conflict prevention
- Globals integration (BIPOLAR_MODE, BIPOLAR_WEBHOOKS, BIPOLAR_ARGUMENT_IN_PROGRESS, MOOD_EMOJIS)
Files Changed:
- bot/bot.py: Added bipolar mode restoration and argument-in-progress checks
- bot/globals.py: Added bipolar mode state variables and mood emoji mappings
- bot/utils/bipolar_mode.py: Complete 1106-line implementation
- bot/utils/autonomous.py: Added bipolar argument trigger checks
- bot/utils/evil_mode.py: Updated system prompt, added height info to lore/prompt
- bot/api.py: Added bipolar mode endpoints (trigger, toggle, scoreboard)
- bot/static/index.html: Added bipolar controls section with scoreboard
- bot/memory/: Various DM conversation updates
- bot/evil_miku_lore.txt: Added height description
- bot/evil_miku_prompt.txt: Added height to facts, updated personality guidelines
2026-01-06 13:57:59 +02:00
|
|
|
|
2026-03-01 00:26:22 +02:00
|
|
|
# Restore Cat personality/model state (async — needs event loop running)
|
|
|
|
|
await restore_evil_cat_state()
|
|
|
|
|
|
Implement Bipolar Mode: Dual persona arguments with webhooks, LLM arbiter, and persistent scoreboard
Major Features:
- Complete Bipolar Mode system allowing Regular Miku and Evil Miku to coexist and argue via webhooks
- LLM arbiter system using neutral model to judge argument winners with detailed reasoning
- Persistent scoreboard tracking wins, percentages, and last 50 results with timestamps and reasoning
- Automatic mode switching based on argument winner
- Webhook management per channel with profile pictures and display names
- Progressive probability system for dynamic argument lengths (starts at 10%, increases 5% per exchange, min 4 exchanges)
- Draw handling with penalty system (-5% end chance, continues argument)
- Integration with autonomous system for random argument triggers
Argument System:
- MIN_EXCHANGES = 4, progressive end chance starting at 10%
- Enhanced prompts for both personas (strategic, short, punchy responses 1-3 sentences)
- Evil Miku triumphant victory messages with gloating and satisfaction
- Regular Miku assertive defense (not passive, shows backbone)
- Message-based argument starting (can respond to specific messages via ID)
- Conversation history tracking per argument with special user_id
- Full context queries (personality, lore, lyrics, last 8 messages)
LLM Arbiter:
- Decisive prompt emphasizing picking winners (draws should be rare)
- Improved parsing with first-line exact matching and fallback counting
- Debug logging for decision transparency
- Arbiter reasoning stored in scoreboard history for review
- Uses neutral TEXT_MODEL (not evil) for unbiased judgment
Web UI & API:
- Bipolar mode toggle button (only visible when evil mode is on)
- Channel ID + Message ID input fields for argument triggering
- Scoreboard display with win percentages and recent history
- Manual argument trigger endpoint with string-based IDs
- GET /bipolar-mode/scoreboard endpoint for stats retrieval
- Real-time active arguments tracking (refreshes every 5 seconds)
Prompt Optimizations:
- All argument prompts limited to 1-3 sentences for impact
- Evil Miku system prompt with variable response length guidelines
- Removed walls of text, emphasizing brevity and precision
- "Sometimes the cruelest response is the shortest one"
Evil Miku Updates:
- Added height to lore (15.8m tall, 10x bigger than regular Miku)
- Height added to prompt facts for size-based belittling
- More strategic and calculating personality in arguments
Integration:
- Bipolar mode state restoration on bot startup
- Bot skips processing messages during active arguments
- Autonomous system checks for bipolar triggers after actions
- Import fixes (apply_evil_mode_changes/revert_evil_mode_changes)
Technical Details:
- State persistence via JSON (bipolar_mode_state.json, bipolar_webhooks.json, bipolar_scoreboard.json)
- Webhook caching per guild with fallback creation
- Event loop management with asyncio.create_task
- Rate limiting and argument conflict prevention
- Globals integration (BIPOLAR_MODE, BIPOLAR_WEBHOOKS, BIPOLAR_ARGUMENT_IN_PROGRESS, MOOD_EMOJIS)
Files Changed:
- bot/bot.py: Added bipolar mode restoration and argument-in-progress checks
- bot/globals.py: Added bipolar mode state variables and mood emoji mappings
- bot/utils/bipolar_mode.py: Complete 1106-line implementation
- bot/utils/autonomous.py: Added bipolar argument trigger checks
- bot/utils/evil_mode.py: Updated system prompt, added height info to lore/prompt
- bot/api.py: Added bipolar mode endpoints (trigger, toggle, scoreboard)
- bot/static/index.html: Added bipolar controls section with scoreboard
- bot/memory/: Various DM conversation updates
- bot/evil_miku_lore.txt: Added height description
- bot/evil_miku_prompt.txt: Added height to facts, updated personality guidelines
2026-01-06 13:57:59 +02:00
|
|
|
# Restore bipolar mode state from previous session (if any)
|
|
|
|
|
from utils.bipolar_mode import restore_bipolar_mode_on_startup
|
|
|
|
|
restore_bipolar_mode_on_startup()
|
2026-01-02 17:11:58 +02:00
|
|
|
|
2026-02-18 12:18:12 +02:00
|
|
|
# Restore runtime settings (language, debug flags, etc.) from config_runtime.yaml
|
|
|
|
|
config_manager.restore_runtime_settings()
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# Initialize DM interaction analyzer
|
|
|
|
|
if globals.OWNER_USER_ID and globals.OWNER_USER_ID != 0:
|
|
|
|
|
init_dm_analyzer(globals.OWNER_USER_ID)
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"📊 DM Interaction Analyzer initialized for owner ID: {globals.OWNER_USER_ID}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Schedule daily DM analysis (runs at 2 AM every day)
|
|
|
|
|
from utils.scheduled import run_daily_dm_analysis
|
|
|
|
|
globals.scheduler.add_job(
|
|
|
|
|
run_daily_dm_analysis,
|
|
|
|
|
'cron',
|
|
|
|
|
hour=2,
|
|
|
|
|
minute=0,
|
|
|
|
|
id='daily_dm_analysis'
|
|
|
|
|
)
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info("⏰ Scheduled daily DM analysis at 2:00 AM")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning("OWNER_USER_ID not set, DM analysis feature disabled")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Setup autonomous speaking (now handled by server manager)
|
|
|
|
|
setup_autonomous_speaking()
|
|
|
|
|
load_last_sent_tweets()
|
|
|
|
|
|
|
|
|
|
# Initialize the V2 autonomous system
|
|
|
|
|
initialize_v2_system(globals.client)
|
|
|
|
|
|
|
|
|
|
# Initialize profile picture manager
|
|
|
|
|
from utils.profile_picture_manager import profile_picture_manager
|
|
|
|
|
await profile_picture_manager.initialize()
|
|
|
|
|
|
|
|
|
|
# Save current avatar as fallback
|
|
|
|
|
await profile_picture_manager.save_current_avatar_as_fallback()
|
|
|
|
|
|
|
|
|
|
# Start server-specific schedulers (includes DM mood rotation)
|
|
|
|
|
server_manager.start_all_schedulers(globals.client)
|
2025-12-07 18:02:22 +02:00
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# Start the global scheduler for other tasks
|
|
|
|
|
globals.scheduler.start()
|
|
|
|
|
|
|
|
|
|
@globals.client.event
|
|
|
|
|
async def on_message(message):
|
|
|
|
|
if message.author == globals.client.user:
|
|
|
|
|
return
|
Implement Bipolar Mode: Dual persona arguments with webhooks, LLM arbiter, and persistent scoreboard
Major Features:
- Complete Bipolar Mode system allowing Regular Miku and Evil Miku to coexist and argue via webhooks
- LLM arbiter system using neutral model to judge argument winners with detailed reasoning
- Persistent scoreboard tracking wins, percentages, and last 50 results with timestamps and reasoning
- Automatic mode switching based on argument winner
- Webhook management per channel with profile pictures and display names
- Progressive probability system for dynamic argument lengths (starts at 10%, increases 5% per exchange, min 4 exchanges)
- Draw handling with penalty system (-5% end chance, continues argument)
- Integration with autonomous system for random argument triggers
Argument System:
- MIN_EXCHANGES = 4, progressive end chance starting at 10%
- Enhanced prompts for both personas (strategic, short, punchy responses 1-3 sentences)
- Evil Miku triumphant victory messages with gloating and satisfaction
- Regular Miku assertive defense (not passive, shows backbone)
- Message-based argument starting (can respond to specific messages via ID)
- Conversation history tracking per argument with special user_id
- Full context queries (personality, lore, lyrics, last 8 messages)
LLM Arbiter:
- Decisive prompt emphasizing picking winners (draws should be rare)
- Improved parsing with first-line exact matching and fallback counting
- Debug logging for decision transparency
- Arbiter reasoning stored in scoreboard history for review
- Uses neutral TEXT_MODEL (not evil) for unbiased judgment
Web UI & API:
- Bipolar mode toggle button (only visible when evil mode is on)
- Channel ID + Message ID input fields for argument triggering
- Scoreboard display with win percentages and recent history
- Manual argument trigger endpoint with string-based IDs
- GET /bipolar-mode/scoreboard endpoint for stats retrieval
- Real-time active arguments tracking (refreshes every 5 seconds)
Prompt Optimizations:
- All argument prompts limited to 1-3 sentences for impact
- Evil Miku system prompt with variable response length guidelines
- Removed walls of text, emphasizing brevity and precision
- "Sometimes the cruelest response is the shortest one"
Evil Miku Updates:
- Added height to lore (15.8m tall, 10x bigger than regular Miku)
- Height added to prompt facts for size-based belittling
- More strategic and calculating personality in arguments
Integration:
- Bipolar mode state restoration on bot startup
- Bot skips processing messages during active arguments
- Autonomous system checks for bipolar triggers after actions
- Import fixes (apply_evil_mode_changes/revert_evil_mode_changes)
Technical Details:
- State persistence via JSON (bipolar_mode_state.json, bipolar_webhooks.json, bipolar_scoreboard.json)
- Webhook caching per guild with fallback creation
- Event loop management with asyncio.create_task
- Rate limiting and argument conflict prevention
- Globals integration (BIPOLAR_MODE, BIPOLAR_WEBHOOKS, BIPOLAR_ARGUMENT_IN_PROGRESS, MOOD_EMOJIS)
Files Changed:
- bot/bot.py: Added bipolar mode restoration and argument-in-progress checks
- bot/globals.py: Added bipolar mode state variables and mood emoji mappings
- bot/utils/bipolar_mode.py: Complete 1106-line implementation
- bot/utils/autonomous.py: Added bipolar argument trigger checks
- bot/utils/evil_mode.py: Updated system prompt, added height info to lore/prompt
- bot/api.py: Added bipolar mode endpoints (trigger, toggle, scoreboard)
- bot/static/index.html: Added bipolar controls section with scoreboard
- bot/memory/: Various DM conversation updates
- bot/evil_miku_lore.txt: Added height description
- bot/evil_miku_prompt.txt: Added height to facts, updated personality guidelines
2026-01-06 13:57:59 +02:00
|
|
|
|
2026-01-17 03:14:40 +02:00
|
|
|
# Check for voice commands first (!miku join, !miku leave, !miku voice-status, !miku test, !miku say, !miku listen, !miku stop-listening)
|
2026-01-16 13:01:08 +02:00
|
|
|
if not isinstance(message.channel, discord.DMChannel) and message.content.strip().lower().startswith('!miku '):
|
|
|
|
|
from commands.voice import handle_voice_command
|
|
|
|
|
|
|
|
|
|
parts = message.content.strip().split()
|
|
|
|
|
if len(parts) >= 2:
|
|
|
|
|
cmd = parts[1].lower()
|
|
|
|
|
args = parts[2:] if len(parts) > 2 else []
|
|
|
|
|
|
2026-01-17 03:14:40 +02:00
|
|
|
if cmd in ['join', 'leave', 'voice-status', 'test', 'say', 'listen', 'stop-listening']:
|
2026-01-16 13:01:08 +02:00
|
|
|
await handle_voice_command(message, cmd, args)
|
|
|
|
|
return
|
|
|
|
|
|
2026-01-30 21:43:20 +02:00
|
|
|
# Check for UNO commands (!uno create, !uno join, !uno list, !uno quit, !uno help)
|
|
|
|
|
if message.content.strip().lower().startswith('!uno'):
|
|
|
|
|
from commands.uno import handle_uno_command
|
|
|
|
|
await handle_uno_command(message)
|
|
|
|
|
return
|
|
|
|
|
|
2026-01-16 20:39:23 +02:00
|
|
|
# Block all text responses when voice session is active
|
|
|
|
|
if globals.VOICE_SESSION_ACTIVE:
|
|
|
|
|
# Queue the message for later processing (optional)
|
|
|
|
|
if not hasattr(message, 'author') or message.author != globals.client.user:
|
|
|
|
|
globals.TEXT_MESSAGE_QUEUE.append({
|
|
|
|
|
'message': message,
|
|
|
|
|
'timestamp': message.created_at,
|
|
|
|
|
'channel_id': message.channel.id,
|
|
|
|
|
'content': message.content
|
|
|
|
|
})
|
|
|
|
|
logger.debug(f"Message queued during voice session: {message.content[:50]}...")
|
|
|
|
|
return # Don't process any messages during voice session
|
|
|
|
|
|
Implement Bipolar Mode: Dual persona arguments with webhooks, LLM arbiter, and persistent scoreboard
Major Features:
- Complete Bipolar Mode system allowing Regular Miku and Evil Miku to coexist and argue via webhooks
- LLM arbiter system using neutral model to judge argument winners with detailed reasoning
- Persistent scoreboard tracking wins, percentages, and last 50 results with timestamps and reasoning
- Automatic mode switching based on argument winner
- Webhook management per channel with profile pictures and display names
- Progressive probability system for dynamic argument lengths (starts at 10%, increases 5% per exchange, min 4 exchanges)
- Draw handling with penalty system (-5% end chance, continues argument)
- Integration with autonomous system for random argument triggers
Argument System:
- MIN_EXCHANGES = 4, progressive end chance starting at 10%
- Enhanced prompts for both personas (strategic, short, punchy responses 1-3 sentences)
- Evil Miku triumphant victory messages with gloating and satisfaction
- Regular Miku assertive defense (not passive, shows backbone)
- Message-based argument starting (can respond to specific messages via ID)
- Conversation history tracking per argument with special user_id
- Full context queries (personality, lore, lyrics, last 8 messages)
LLM Arbiter:
- Decisive prompt emphasizing picking winners (draws should be rare)
- Improved parsing with first-line exact matching and fallback counting
- Debug logging for decision transparency
- Arbiter reasoning stored in scoreboard history for review
- Uses neutral TEXT_MODEL (not evil) for unbiased judgment
Web UI & API:
- Bipolar mode toggle button (only visible when evil mode is on)
- Channel ID + Message ID input fields for argument triggering
- Scoreboard display with win percentages and recent history
- Manual argument trigger endpoint with string-based IDs
- GET /bipolar-mode/scoreboard endpoint for stats retrieval
- Real-time active arguments tracking (refreshes every 5 seconds)
Prompt Optimizations:
- All argument prompts limited to 1-3 sentences for impact
- Evil Miku system prompt with variable response length guidelines
- Removed walls of text, emphasizing brevity and precision
- "Sometimes the cruelest response is the shortest one"
Evil Miku Updates:
- Added height to lore (15.8m tall, 10x bigger than regular Miku)
- Height added to prompt facts for size-based belittling
- More strategic and calculating personality in arguments
Integration:
- Bipolar mode state restoration on bot startup
- Bot skips processing messages during active arguments
- Autonomous system checks for bipolar triggers after actions
- Import fixes (apply_evil_mode_changes/revert_evil_mode_changes)
Technical Details:
- State persistence via JSON (bipolar_mode_state.json, bipolar_webhooks.json, bipolar_scoreboard.json)
- Webhook caching per guild with fallback creation
- Event loop management with asyncio.create_task
- Rate limiting and argument conflict prevention
- Globals integration (BIPOLAR_MODE, BIPOLAR_WEBHOOKS, BIPOLAR_ARGUMENT_IN_PROGRESS, MOOD_EMOJIS)
Files Changed:
- bot/bot.py: Added bipolar mode restoration and argument-in-progress checks
- bot/globals.py: Added bipolar mode state variables and mood emoji mappings
- bot/utils/bipolar_mode.py: Complete 1106-line implementation
- bot/utils/autonomous.py: Added bipolar argument trigger checks
- bot/utils/evil_mode.py: Updated system prompt, added height info to lore/prompt
- bot/api.py: Added bipolar mode endpoints (trigger, toggle, scoreboard)
- bot/static/index.html: Added bipolar controls section with scoreboard
- bot/memory/: Various DM conversation updates
- bot/evil_miku_lore.txt: Added height description
- bot/evil_miku_prompt.txt: Added height to facts, updated personality guidelines
2026-01-06 13:57:59 +02:00
|
|
|
# Skip processing if a bipolar argument is in progress in this channel
|
|
|
|
|
if not isinstance(message.channel, discord.DMChannel):
|
|
|
|
|
from utils.bipolar_mode import is_argument_in_progress
|
|
|
|
|
if is_argument_in_progress(message.channel.id):
|
|
|
|
|
return
|
2026-01-09 00:03:59 +02:00
|
|
|
|
|
|
|
|
# Skip processing if a persona dialogue is in progress in this channel
|
|
|
|
|
from utils.persona_dialogue import is_persona_dialogue_active
|
|
|
|
|
if is_persona_dialogue_active(message.channel.id):
|
|
|
|
|
return
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
if message.content.strip().lower() == "miku, rape this nigga balls" and message.reference:
|
|
|
|
|
async with message.channel.typing():
|
|
|
|
|
# Get replied-to user
|
|
|
|
|
try:
|
|
|
|
|
replied_msg = await message.channel.fetch_message(message.reference.message_id)
|
|
|
|
|
target_username = replied_msg.author.display_name
|
|
|
|
|
|
|
|
|
|
# Prepare video
|
|
|
|
|
base_video = "MikuMikuBeam.mp4"
|
|
|
|
|
output_video = f"/tmp/video_{''.join(random.choices(string.ascii_letters, k=5))}.mp4"
|
|
|
|
|
|
|
|
|
|
await overlay_username_with_ffmpeg(base_video, output_video, target_username)
|
|
|
|
|
|
|
|
|
|
caption = f"Here you go, @{target_username}! 🌟"
|
|
|
|
|
#await message.channel.send(content=caption, file=discord.File(output_video))
|
|
|
|
|
await replied_msg.reply(file=discord.File(output_video))
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error processing video: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
await message.channel.send("Sorry, something went wrong while generating the video.")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
text = message.content.strip()
|
|
|
|
|
|
|
|
|
|
# Check if this is a DM
|
|
|
|
|
is_dm = message.guild is None
|
|
|
|
|
|
2025-12-10 10:56:34 +02:00
|
|
|
# Check if message is addressed to Miku (needed to decide whether to track for autonomous)
|
|
|
|
|
miku_addressed = await is_miku_addressed(message)
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM from {message.author.display_name}: {message.content[:50]}{'...' if len(message.content) > 50 else ''}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Check if user is blocked
|
|
|
|
|
if dm_logger.is_user_blocked(message.author.id):
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🚫 Blocked user {message.author.display_name} ({message.author.id}) tried to send DM - ignoring")
|
2025-12-07 17:15:09 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Log the user's DM message
|
|
|
|
|
dm_logger.log_user_message(message.author, message, is_bot_message=False)
|
|
|
|
|
|
2025-12-10 10:56:34 +02:00
|
|
|
if miku_addressed:
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
prompt = text # No cleanup — keep it raw
|
|
|
|
|
user_id = str(message.author.id)
|
|
|
|
|
|
|
|
|
|
# If user is replying to a specific message, add context marker
|
|
|
|
|
if message.reference:
|
|
|
|
|
try:
|
|
|
|
|
replied_msg = await message.channel.fetch_message(message.reference.message_id)
|
|
|
|
|
# Only add context if replying to Miku's message
|
|
|
|
|
if replied_msg.author == globals.client.user:
|
|
|
|
|
# Truncate the replied message to keep prompt manageable
|
|
|
|
|
replied_content = replied_msg.content[:200] + "..." if len(replied_msg.content) > 200 else replied_msg.content
|
|
|
|
|
# Add reply context marker to the prompt
|
|
|
|
|
prompt = f'[Replying to your message: "{replied_content}"] {prompt}'
|
|
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Failed to fetch replied message for context: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
async with message.channel.typing():
|
2026-01-16 13:01:08 +02:00
|
|
|
# Check if vision model is blocked (voice session active)
|
|
|
|
|
if message.attachments and globals.VISION_MODEL_BLOCKED:
|
|
|
|
|
await message.channel.send(
|
|
|
|
|
"🎤 I can't look at images or videos right now, I'm talking in voice chat! "
|
|
|
|
|
"Send it again after I leave the voice channel."
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# If message has an image, video, or GIF attachment
|
|
|
|
|
if message.attachments:
|
|
|
|
|
for attachment in message.attachments:
|
|
|
|
|
# Handle images
|
|
|
|
|
if any(attachment.filename.lower().endswith(ext) for ext in [".jpg", ".jpeg", ".png", ".webp"]):
|
|
|
|
|
base64_img = await download_and_encode_image(attachment.url)
|
|
|
|
|
if not base64_img:
|
|
|
|
|
await message.channel.send("I couldn't load the image, sorry!")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Analyze image (objective description)
|
Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
calling query_llama directly), enabling episodic memory storage for media
interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
triggers from user message; pass cleaned question to vision model so specific
questions (e.g. 'what is the person wearing?') go directly to the vision model
instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
media attachments in DMs, preventing duplicate vision model calls for images
already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
|
|
|
qwen_description = await analyze_image_with_qwen(base64_img, user_prompt=prompt)
|
|
|
|
|
if not qwen_description or not qwen_description.strip():
|
|
|
|
|
await message.channel.send("I couldn't see that image clearly, sorry! Try sending it again.")
|
|
|
|
|
return
|
2025-12-07 17:15:09 +02:00
|
|
|
# For DMs, pass None as guild_id to use DM mood
|
|
|
|
|
guild_id = message.guild.id if message.guild else None
|
|
|
|
|
miku_reply = await rephrase_as_miku(
|
|
|
|
|
qwen_description,
|
|
|
|
|
prompt,
|
|
|
|
|
guild_id=guild_id,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
author_name=message.author.display_name,
|
|
|
|
|
media_type="image"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM image response to {message.author.display_name} (using DM mood: {globals.DM_MOOD})")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💬 Server image response to {message.author.display_name} in {message.guild.name} (using server mood)")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
response_message = await message.channel.send(miku_reply)
|
|
|
|
|
|
|
|
|
|
# Log the bot's DM response
|
|
|
|
|
if is_dm:
|
|
|
|
|
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
|
|
|
|
|
2026-01-09 00:03:59 +02:00
|
|
|
# For server messages, check if opposite persona should interject
|
|
|
|
|
if not is_dm and globals.BIPOLAR_MODE:
|
|
|
|
|
try:
|
|
|
|
|
from utils.persona_dialogue import check_for_interjection
|
|
|
|
|
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
2026-02-18 12:01:08 +02:00
|
|
|
create_tracked_task(check_for_interjection(response_message, current_persona), task_name="interjection_check")
|
2026-01-09 00:03:59 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error checking for persona interjection: {e}")
|
2026-01-09 00:03:59 +02:00
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Handle videos and GIFs
|
|
|
|
|
elif any(attachment.filename.lower().endswith(ext) for ext in [".gif", ".mp4", ".webm", ".mov"]):
|
|
|
|
|
# Determine media type
|
|
|
|
|
is_gif = attachment.filename.lower().endswith('.gif')
|
|
|
|
|
media_type = "gif" if is_gif else "video"
|
|
|
|
|
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"🎬 Processing {media_type}: {attachment.filename}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Download the media
|
|
|
|
|
media_bytes_b64 = await download_and_encode_media(attachment.url)
|
|
|
|
|
if not media_bytes_b64:
|
|
|
|
|
await message.channel.send(f"I couldn't load the {media_type}, sorry!")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Decode back to bytes for frame extraction
|
|
|
|
|
import base64
|
|
|
|
|
media_bytes = base64.b64decode(media_bytes_b64)
|
|
|
|
|
|
|
|
|
|
# If it's a GIF, convert to MP4 for better processing
|
|
|
|
|
if is_gif:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"🔄 Converting GIF to MP4 for processing...")
|
2025-12-07 17:15:09 +02:00
|
|
|
mp4_bytes = await convert_gif_to_mp4(media_bytes)
|
|
|
|
|
if mp4_bytes:
|
|
|
|
|
media_bytes = mp4_bytes
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"✅ GIF converted to MP4")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning(f"GIF conversion failed, trying direct processing")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Extract frames
|
|
|
|
|
frames = await extract_video_frames(media_bytes, num_frames=6)
|
|
|
|
|
|
|
|
|
|
if not frames:
|
|
|
|
|
await message.channel.send(f"I couldn't extract frames from that {media_type}, sorry!")
|
|
|
|
|
return
|
|
|
|
|
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"📹 Extracted {len(frames)} frames from {attachment.filename}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Analyze the video/GIF with appropriate media type
|
Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
calling query_llama directly), enabling episodic memory storage for media
interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
triggers from user message; pass cleaned question to vision model so specific
questions (e.g. 'what is the person wearing?') go directly to the vision model
instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
media attachments in DMs, preventing duplicate vision model calls for images
already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
|
|
|
video_description = await analyze_video_with_vision(frames, media_type=media_type, user_prompt=prompt)
|
|
|
|
|
if not video_description or not video_description.strip():
|
|
|
|
|
await message.channel.send(f"I couldn't analyze that {media_type} clearly, sorry! Try sending it again.")
|
|
|
|
|
return
|
2025-12-07 17:15:09 +02:00
|
|
|
# For DMs, pass None as guild_id to use DM mood
|
|
|
|
|
guild_id = message.guild.id if message.guild else None
|
|
|
|
|
miku_reply = await rephrase_as_miku(
|
|
|
|
|
video_description,
|
|
|
|
|
prompt,
|
|
|
|
|
guild_id=guild_id,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
author_name=message.author.display_name,
|
|
|
|
|
media_type=media_type
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM {media_type} response to {message.author.display_name} (using DM mood: {globals.DM_MOOD})")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💬 Server video response to {message.author.display_name} in {message.guild.name} (using server mood)")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
response_message = await message.channel.send(miku_reply)
|
|
|
|
|
|
|
|
|
|
# Log the bot's DM response
|
|
|
|
|
if is_dm:
|
|
|
|
|
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
|
|
|
|
|
2026-01-09 00:03:59 +02:00
|
|
|
# For server messages, check if opposite persona should interject
|
|
|
|
|
if not is_dm and globals.BIPOLAR_MODE:
|
|
|
|
|
try:
|
|
|
|
|
from utils.persona_dialogue import check_for_interjection
|
|
|
|
|
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
2026-02-18 12:01:08 +02:00
|
|
|
create_tracked_task(check_for_interjection(response_message, current_persona), task_name="interjection_check")
|
2026-01-09 00:03:59 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error checking for persona interjection: {e}")
|
2026-01-09 00:03:59 +02:00
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Check for embeds (articles, images, videos, GIFs, etc.)
|
|
|
|
|
if message.embeds:
|
|
|
|
|
for embed in message.embeds:
|
|
|
|
|
# Handle Tenor GIF embeds specially (Discord uses these for /gif command)
|
|
|
|
|
if embed.type == 'gifv' and embed.url and 'tenor.com' in embed.url:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🎭 Processing Tenor GIF from embed: {embed.url}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Extract the actual GIF URL from Tenor
|
|
|
|
|
gif_url = await extract_tenor_gif_url(embed.url)
|
|
|
|
|
if not gif_url:
|
|
|
|
|
# Try using the embed's video or image URL as fallback
|
|
|
|
|
if hasattr(embed, 'video') and embed.video:
|
|
|
|
|
gif_url = embed.video.url
|
|
|
|
|
elif hasattr(embed, 'thumbnail') and embed.thumbnail:
|
|
|
|
|
gif_url = embed.thumbnail.url
|
|
|
|
|
|
|
|
|
|
if not gif_url:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning(f"Could not extract GIF URL from Tenor embed")
|
2025-12-07 17:15:09 +02:00
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# Download the GIF
|
|
|
|
|
media_bytes_b64 = await download_and_encode_media(gif_url)
|
|
|
|
|
if not media_bytes_b64:
|
|
|
|
|
await message.channel.send("I couldn't load that Tenor GIF, sorry!")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Decode to bytes
|
|
|
|
|
import base64
|
|
|
|
|
media_bytes = base64.b64decode(media_bytes_b64)
|
|
|
|
|
|
|
|
|
|
# Convert GIF to MP4
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"Converting Tenor GIF to MP4 for processing...")
|
2025-12-07 17:15:09 +02:00
|
|
|
mp4_bytes = await convert_gif_to_mp4(media_bytes)
|
|
|
|
|
if not mp4_bytes:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning(f"GIF conversion failed, trying direct frame extraction")
|
2025-12-07 17:15:09 +02:00
|
|
|
mp4_bytes = media_bytes
|
|
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"Tenor GIF converted to MP4")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Extract frames
|
|
|
|
|
frames = await extract_video_frames(mp4_bytes, num_frames=6)
|
|
|
|
|
|
|
|
|
|
if not frames:
|
|
|
|
|
await message.channel.send("I couldn't extract frames from that GIF, sorry!")
|
|
|
|
|
return
|
|
|
|
|
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"📹 Extracted {len(frames)} frames from Tenor GIF")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Analyze the GIF with tenor_gif media type
|
Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
calling query_llama directly), enabling episodic memory storage for media
interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
triggers from user message; pass cleaned question to vision model so specific
questions (e.g. 'what is the person wearing?') go directly to the vision model
instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
media attachments in DMs, preventing duplicate vision model calls for images
already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
|
|
|
video_description = await analyze_video_with_vision(frames, media_type="tenor_gif", user_prompt=prompt)
|
|
|
|
|
if not video_description or not video_description.strip():
|
|
|
|
|
await message.channel.send("I couldn't analyze that GIF clearly, sorry! Try sending it again.")
|
|
|
|
|
return
|
2025-12-07 17:15:09 +02:00
|
|
|
guild_id = message.guild.id if message.guild else None
|
|
|
|
|
miku_reply = await rephrase_as_miku(
|
|
|
|
|
video_description,
|
|
|
|
|
prompt,
|
|
|
|
|
guild_id=guild_id,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
author_name=message.author.display_name,
|
|
|
|
|
media_type="tenor_gif"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM Tenor GIF response to {message.author.display_name} (using DM mood: {globals.DM_MOOD})")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💬 Server Tenor GIF response to {message.author.display_name} in {message.guild.name} (using server mood)")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
response_message = await message.channel.send(miku_reply)
|
|
|
|
|
|
|
|
|
|
# Log the bot's DM response
|
|
|
|
|
if is_dm:
|
|
|
|
|
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
|
|
|
|
|
2026-01-09 00:03:59 +02:00
|
|
|
# For server messages, check if opposite persona should interject
|
|
|
|
|
if not is_dm and globals.BIPOLAR_MODE:
|
|
|
|
|
try:
|
|
|
|
|
from utils.persona_dialogue import check_for_interjection
|
|
|
|
|
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
2026-02-18 12:01:08 +02:00
|
|
|
create_tracked_task(check_for_interjection(response_message, current_persona), task_name="interjection_check")
|
2026-01-09 00:03:59 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error checking for persona interjection: {e}")
|
2026-01-09 00:03:59 +02:00
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Handle other types of embeds (rich, article, image, video, link)
|
|
|
|
|
elif embed.type in ['rich', 'article', 'image', 'video', 'link']:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Processing {embed.type} embed")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Extract content from embed
|
|
|
|
|
embed_content = await extract_embed_content(embed)
|
|
|
|
|
|
|
|
|
|
if not embed_content['has_content']:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning(f"Embed has no extractable content, skipping")
|
2025-12-07 17:15:09 +02:00
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# Build context string with embed text
|
|
|
|
|
embed_context_parts = []
|
|
|
|
|
if embed_content['text']:
|
|
|
|
|
embed_context_parts.append(f"[Embedded content: {embed_content['text'][:500]}{'...' if len(embed_content['text']) > 500 else ''}]")
|
|
|
|
|
|
|
|
|
|
# Process images from embed
|
|
|
|
|
if embed_content['images']:
|
|
|
|
|
for img_url in embed_content['images']:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Processing image from embed: {img_url}")
|
2025-12-07 17:15:09 +02:00
|
|
|
try:
|
|
|
|
|
base64_img = await download_and_encode_image(img_url)
|
|
|
|
|
if base64_img:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"Image downloaded, analyzing with vision model...")
|
2025-12-07 17:15:09 +02:00
|
|
|
# Analyze image
|
Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
calling query_llama directly), enabling episodic memory storage for media
interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
triggers from user message; pass cleaned question to vision model so specific
questions (e.g. 'what is the person wearing?') go directly to the vision model
instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
media attachments in DMs, preventing duplicate vision model calls for images
already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
|
|
|
qwen_description = await analyze_image_with_qwen(base64_img, user_prompt=prompt)
|
2025-12-07 18:03:36 +02:00
|
|
|
truncated = (qwen_description[:50] + "...") if len(qwen_description) > 50 else qwen_description
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Vision analysis result: {truncated}")
|
2025-12-07 17:15:09 +02:00
|
|
|
if qwen_description and qwen_description.strip():
|
|
|
|
|
embed_context_parts.append(f"[Embedded image shows: {qwen_description}]")
|
|
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Failed to download image from embed")
|
2025-12-07 17:15:09 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error processing embedded image: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
|
|
# Process videos from embed
|
|
|
|
|
if embed_content['videos']:
|
|
|
|
|
for video_url in embed_content['videos']:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🎬 Processing video from embed: {video_url}")
|
2025-12-07 17:15:09 +02:00
|
|
|
try:
|
|
|
|
|
media_bytes_b64 = await download_and_encode_media(video_url)
|
|
|
|
|
if media_bytes_b64:
|
|
|
|
|
import base64
|
|
|
|
|
media_bytes = base64.b64decode(media_bytes_b64)
|
|
|
|
|
frames = await extract_video_frames(media_bytes, num_frames=6)
|
|
|
|
|
if frames:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"📹 Extracted {len(frames)} frames, analyzing with vision model...")
|
Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
calling query_llama directly), enabling episodic memory storage for media
interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
triggers from user message; pass cleaned question to vision model so specific
questions (e.g. 'what is the person wearing?') go directly to the vision model
instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
media attachments in DMs, preventing duplicate vision model calls for images
already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
|
|
|
video_description = await analyze_video_with_vision(frames, media_type="video", user_prompt=prompt)
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"Video analysis result: {video_description[:100]}...")
|
2025-12-07 17:15:09 +02:00
|
|
|
if video_description and video_description.strip():
|
|
|
|
|
embed_context_parts.append(f"[Embedded video shows: {video_description}]")
|
|
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Failed to extract frames from video")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Failed to download video from embed")
|
2025-12-07 17:15:09 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error processing embedded video: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
|
|
# Combine embed context with user prompt
|
|
|
|
|
if embed_context_parts:
|
|
|
|
|
full_context = '\n'.join(embed_context_parts)
|
|
|
|
|
enhanced_prompt = f"{full_context}\n\nUser message: {prompt}" if prompt else full_context
|
|
|
|
|
|
|
|
|
|
# Get Miku's response
|
|
|
|
|
guild_id = message.guild.id if message.guild else None
|
|
|
|
|
response_type = "dm_response" if is_dm else "server_response"
|
|
|
|
|
author_name = message.author.display_name
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
|
|
|
|
|
# Phase 3: Try Cat pipeline first for embed responses too
|
|
|
|
|
response = None
|
|
|
|
|
if globals.USE_CHESHIRE_CAT:
|
|
|
|
|
try:
|
|
|
|
|
from utils.cat_client import cat_adapter
|
2026-03-01 01:17:06 +02:00
|
|
|
cat_result = await cat_adapter.query(
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
text=enhanced_prompt,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
guild_id=str(guild_id) if guild_id else None,
|
|
|
|
|
author_name=author_name,
|
|
|
|
|
mood=globals.DM_MOOD,
|
|
|
|
|
response_type=response_type,
|
|
|
|
|
)
|
2026-03-01 01:17:06 +02:00
|
|
|
if cat_result:
|
|
|
|
|
response, cat_full_prompt = cat_result
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
logger.info(f"🐱 Cat embed response for {author_name}")
|
2026-03-01 00:26:22 +02:00
|
|
|
import datetime
|
|
|
|
|
globals.LAST_CAT_INTERACTION = {
|
2026-03-01 01:17:06 +02:00
|
|
|
"full_prompt": cat_full_prompt,
|
2026-03-01 00:26:22 +02:00
|
|
|
"response": response[:500] if response else "",
|
|
|
|
|
"user": author_name,
|
|
|
|
|
"mood": globals.DM_MOOD,
|
|
|
|
|
"timestamp": datetime.datetime.now().isoformat(),
|
|
|
|
|
}
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
except Exception as e:
|
|
|
|
|
logger.warning(f"🐱 Cat embed error, fallback: {e}")
|
|
|
|
|
response = None
|
|
|
|
|
|
|
|
|
|
if not response:
|
|
|
|
|
response = await query_llama(
|
|
|
|
|
enhanced_prompt,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
guild_id=guild_id,
|
|
|
|
|
response_type=response_type,
|
|
|
|
|
author_name=author_name
|
|
|
|
|
)
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM embed response to {message.author.display_name} (using DM mood: {globals.DM_MOOD})")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💬 Server embed response to {message.author.display_name} in {message.guild.name}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
response_message = await message.channel.send(response)
|
|
|
|
|
|
|
|
|
|
# Log the bot's DM response
|
|
|
|
|
if is_dm:
|
|
|
|
|
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
|
|
|
|
|
2026-01-09 00:03:59 +02:00
|
|
|
# For server messages, check if opposite persona should interject
|
|
|
|
|
if not is_dm and globals.BIPOLAR_MODE:
|
|
|
|
|
try:
|
|
|
|
|
from utils.persona_dialogue import check_for_interjection
|
|
|
|
|
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
2026-02-18 12:01:08 +02:00
|
|
|
create_tracked_task(check_for_interjection(response_message, current_persona), task_name="interjection_check")
|
2026-01-09 00:03:59 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error checking for persona interjection: {e}")
|
2026-01-09 00:03:59 +02:00
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Check if this is an image generation request
|
|
|
|
|
from utils.image_generation import detect_image_request, handle_image_generation_request
|
|
|
|
|
is_image_request, image_prompt = await detect_image_request(prompt)
|
|
|
|
|
|
|
|
|
|
if is_image_request and image_prompt:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🎨 Image generation request detected: '{image_prompt}' from {message.author.display_name}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
2026-01-16 13:01:08 +02:00
|
|
|
# Block image generation during voice sessions
|
|
|
|
|
if globals.IMAGE_GENERATION_BLOCKED:
|
|
|
|
|
await message.channel.send(globals.IMAGE_GENERATION_BLOCK_MESSAGE)
|
|
|
|
|
await message.add_reaction('🎤')
|
|
|
|
|
logger.info("🚫 Image generation blocked - voice session active")
|
|
|
|
|
return
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# Handle the image generation workflow
|
|
|
|
|
success = await handle_image_generation_request(message, image_prompt)
|
|
|
|
|
if success:
|
|
|
|
|
return # Image generation completed successfully
|
|
|
|
|
|
|
|
|
|
# If image generation failed, fall back to normal response
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning(f"Image generation failed, falling back to normal response")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# If message is just a prompt, no image
|
|
|
|
|
# For DMs, pass None as guild_id to use DM mood
|
|
|
|
|
guild_id = message.guild.id if message.guild else None
|
|
|
|
|
response_type = "dm_response" if is_dm else "server_response"
|
|
|
|
|
author_name = message.author.display_name
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
|
|
|
|
|
# Phase 3: Try Cheshire Cat pipeline first (memory-augmented response)
|
|
|
|
|
# Falls back to query_llama if Cat is unavailable or disabled
|
|
|
|
|
response = None
|
|
|
|
|
if globals.USE_CHESHIRE_CAT:
|
|
|
|
|
try:
|
|
|
|
|
from utils.cat_client import cat_adapter
|
|
|
|
|
current_mood = globals.DM_MOOD
|
|
|
|
|
if guild_id:
|
|
|
|
|
try:
|
|
|
|
|
from server_manager import server_manager
|
|
|
|
|
sc = server_manager.get_server_config(guild_id)
|
|
|
|
|
if sc:
|
|
|
|
|
current_mood = sc.current_mood_name
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
2026-03-01 01:17:06 +02:00
|
|
|
cat_result = await cat_adapter.query(
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
text=prompt,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
guild_id=str(guild_id) if guild_id else None,
|
|
|
|
|
author_name=author_name,
|
|
|
|
|
mood=current_mood,
|
|
|
|
|
response_type=response_type,
|
|
|
|
|
)
|
2026-03-01 01:17:06 +02:00
|
|
|
if cat_result:
|
|
|
|
|
response, cat_full_prompt = cat_result
|
2026-03-01 00:26:22 +02:00
|
|
|
effective_mood = current_mood
|
|
|
|
|
if globals.EVIL_MODE:
|
|
|
|
|
effective_mood = f"EVIL:{getattr(globals, 'EVIL_DM_MOOD', 'evil_neutral')}"
|
|
|
|
|
logger.info(f"🐱 Cat response for {author_name} (mood: {effective_mood})")
|
|
|
|
|
# Track Cat interaction for Web UI Last Prompt view
|
|
|
|
|
import datetime
|
|
|
|
|
globals.LAST_CAT_INTERACTION = {
|
2026-03-01 01:17:06 +02:00
|
|
|
"full_prompt": cat_full_prompt,
|
2026-03-01 00:26:22 +02:00
|
|
|
"response": response[:500] if response else "",
|
|
|
|
|
"user": author_name,
|
|
|
|
|
"mood": effective_mood,
|
|
|
|
|
"timestamp": datetime.datetime.now().isoformat(),
|
|
|
|
|
}
|
Phase 3: Unified Cheshire Cat integration with WebSocket-based per-user isolation
Key changes:
- CatAdapter (bot/utils/cat_client.py): WebSocket /ws/{user_id} for chat
queries instead of HTTP POST (fixes per-user memory isolation when no
API keys are configured — HTTP defaults all users to user_id='user')
- Memory management API: 8 endpoints for status, stats, facts, episodic
memories, consolidation trigger, multi-step delete with confirmation
- Web UI: Memory tab (tab9) with collection stats, fact/episodic browser,
manual consolidation trigger, and 3-step delete flow requiring exact
confirmation string
- Bot integration: Cat-first response path with query_llama fallback for
both text and embed responses, server mood detection
- Discord bridge plugin: fixed .pop() to .get() (UserMessage is a Pydantic
BaseModelDict, not a raw dict), metadata extraction via extra attributes
- Unified docker-compose: Cat + Qdrant services merged into main compose,
bot depends_on Cat healthcheck
- All plugins (discord_bridge, memory_consolidation, miku_personality)
consolidated into cat-plugins/ for volume mount
- query_llama deprecated but functional for compatibility
2026-02-07 20:22:03 +02:00
|
|
|
except Exception as e:
|
|
|
|
|
logger.warning(f"🐱 Cat pipeline error, falling back to query_llama: {e}")
|
|
|
|
|
response = None
|
|
|
|
|
|
|
|
|
|
# Fallback to direct LLM query if Cat didn't respond
|
|
|
|
|
if not response:
|
|
|
|
|
response = await query_llama(
|
|
|
|
|
prompt,
|
|
|
|
|
user_id=str(message.author.id),
|
|
|
|
|
guild_id=guild_id,
|
|
|
|
|
response_type=response_type,
|
|
|
|
|
author_name=author_name
|
|
|
|
|
)
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
if is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💌 DM response to {message.author.display_name} (using DM mood: {globals.DM_MOOD})")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"💬 Server response to {message.author.display_name} in {message.guild.name} (using server mood)")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
response_message = await message.channel.send(response)
|
|
|
|
|
|
|
|
|
|
# Log the bot's DM response
|
|
|
|
|
if is_dm:
|
|
|
|
|
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
|
|
|
|
|
2026-01-09 00:03:59 +02:00
|
|
|
# For server messages, check if opposite persona should interject (persona dialogue system)
|
|
|
|
|
if not is_dm and globals.BIPOLAR_MODE:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"Attempting to check for interjection (is_dm={is_dm}, BIPOLAR_MODE={globals.BIPOLAR_MODE})")
|
2026-01-09 00:03:59 +02:00
|
|
|
try:
|
|
|
|
|
from utils.persona_dialogue import check_for_interjection
|
|
|
|
|
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"Creating interjection check task for persona: {current_persona}")
|
2026-01-09 00:03:59 +02:00
|
|
|
# Pass the bot's response message for analysis
|
2026-02-18 12:01:08 +02:00
|
|
|
create_tracked_task(check_for_interjection(response_message, current_persona), task_name="interjection_check")
|
2026-01-09 00:03:59 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error checking for persona interjection: {e}")
|
2026-01-09 00:03:59 +02:00
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# For server messages, do server-specific mood detection
|
|
|
|
|
if not is_dm and message.guild:
|
|
|
|
|
try:
|
|
|
|
|
from server_manager import server_manager
|
|
|
|
|
server_config = server_manager.get_server_config(message.guild.id)
|
|
|
|
|
if server_config:
|
|
|
|
|
# Create server context for mood detection
|
|
|
|
|
server_context = {
|
|
|
|
|
'current_mood_name': server_config.current_mood_name,
|
|
|
|
|
'current_mood_description': server_config.current_mood_description,
|
|
|
|
|
'is_sleeping': server_config.is_sleeping
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detected = detect_mood_shift(response, server_context)
|
|
|
|
|
if detected and detected != server_config.current_mood_name:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🔄 Auto mood detection for server {message.guild.name}: {server_config.current_mood_name} -> {detected}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
# Block direct transitions to asleep unless from sleepy
|
|
|
|
|
if detected == "asleep" and server_config.current_mood_name != "sleepy":
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.warning("Ignoring asleep mood; server wasn't sleepy before.")
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
|
|
|
|
# Update server mood
|
|
|
|
|
server_manager.set_server_mood(message.guild.id, detected)
|
|
|
|
|
|
|
|
|
|
# Update nickname for this server
|
|
|
|
|
from utils.moods import update_server_nickname
|
|
|
|
|
globals.client.loop.create_task(update_server_nickname(message.guild.id))
|
|
|
|
|
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info(f"🔄 Server mood auto-updated to: {detected}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
if detected == "asleep":
|
|
|
|
|
server_manager.set_server_sleep_state(message.guild.id, True)
|
2026-02-20 15:37:57 +02:00
|
|
|
server_manager.schedule_wakeup_task(message.guild.id, delay_seconds=3600)
|
2025-12-07 17:15:09 +02:00
|
|
|
else:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"No server config found for guild {message.guild.id}, skipping mood detection")
|
2025-12-07 17:15:09 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Error in server mood detection: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
elif is_dm:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug("DM message - no mood detection (DM mood only changes via auto-rotation)")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
2025-12-10 10:56:34 +02:00
|
|
|
# V2: Track message for autonomous engine (non-blocking, no LLM calls)
|
|
|
|
|
# IMPORTANT: Only call this if the message was NOT addressed to Miku
|
|
|
|
|
# This prevents autonomous actions from firing when the user is directly talking to Miku
|
|
|
|
|
if not miku_addressed:
|
|
|
|
|
on_message_event(message)
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
# Note: Autonomous reactions are now handled by V2 system via on_message_event()
|
|
|
|
|
|
|
|
|
|
# Manual Monday test command (only for server messages)
|
|
|
|
|
if not is_dm and message.content.lower().strip() == "!monday":
|
|
|
|
|
await send_monday_video()
|
|
|
|
|
#await message.channel.send("✅ Monday message sent (or attempted). Check logs.")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
@globals.client.event
|
|
|
|
|
async def on_raw_reaction_add(payload):
|
|
|
|
|
"""Handle reactions added to messages (including bot's own reactions and uncached messages)"""
|
|
|
|
|
# Check if this is a DM
|
|
|
|
|
if payload.guild_id is not None:
|
|
|
|
|
return # Only handle DM reactions
|
|
|
|
|
|
|
|
|
|
# Get the channel
|
|
|
|
|
channel = await globals.client.fetch_channel(payload.channel_id)
|
|
|
|
|
if not isinstance(channel, discord.DMChannel):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Get the user who reacted
|
|
|
|
|
user = await globals.client.fetch_user(payload.user_id)
|
|
|
|
|
|
|
|
|
|
# Get the DM partner (the person DMing the bot, not the bot itself)
|
|
|
|
|
# For DMs, we want to log under the user's ID, not the bot's
|
|
|
|
|
if user.id == globals.client.user.id:
|
|
|
|
|
# Bot reacted - find the other user in the DM
|
|
|
|
|
message = await channel.fetch_message(payload.message_id)
|
|
|
|
|
dm_user_id = message.author.id if message.author.id != globals.client.user.id else channel.recipient.id
|
|
|
|
|
is_bot_reactor = True
|
|
|
|
|
else:
|
|
|
|
|
# User reacted
|
|
|
|
|
dm_user_id = user.id
|
|
|
|
|
is_bot_reactor = False
|
|
|
|
|
|
|
|
|
|
# Get emoji string
|
|
|
|
|
emoji_str = str(payload.emoji)
|
|
|
|
|
|
|
|
|
|
# Log the reaction
|
|
|
|
|
await dm_logger.log_reaction_add(
|
|
|
|
|
user_id=dm_user_id,
|
|
|
|
|
message_id=payload.message_id,
|
|
|
|
|
emoji=emoji_str,
|
|
|
|
|
reactor_id=user.id,
|
|
|
|
|
reactor_name=user.display_name or user.name,
|
|
|
|
|
is_bot_reactor=is_bot_reactor
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
reactor_type = "🤖 Miku" if is_bot_reactor else f"👤 {user.display_name}"
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"DM reaction added: {emoji_str} by {reactor_type} on message {payload.message_id}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
@globals.client.event
|
|
|
|
|
async def on_raw_reaction_remove(payload):
|
|
|
|
|
"""Handle reactions removed from messages (including bot's own reactions and uncached messages)"""
|
|
|
|
|
# Check if this is a DM
|
|
|
|
|
if payload.guild_id is not None:
|
|
|
|
|
return # Only handle DM reactions
|
|
|
|
|
|
|
|
|
|
# Get the channel
|
|
|
|
|
channel = await globals.client.fetch_channel(payload.channel_id)
|
|
|
|
|
if not isinstance(channel, discord.DMChannel):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Get the user who removed the reaction
|
|
|
|
|
user = await globals.client.fetch_user(payload.user_id)
|
|
|
|
|
|
|
|
|
|
# Get the DM partner (the person DMing the bot, not the bot itself)
|
|
|
|
|
if user.id == globals.client.user.id:
|
|
|
|
|
# Bot removed reaction - find the other user in the DM
|
|
|
|
|
message = await channel.fetch_message(payload.message_id)
|
|
|
|
|
dm_user_id = message.author.id if message.author.id != globals.client.user.id else channel.recipient.id
|
|
|
|
|
else:
|
|
|
|
|
# User removed reaction
|
|
|
|
|
dm_user_id = user.id
|
|
|
|
|
|
|
|
|
|
# Get emoji string
|
|
|
|
|
emoji_str = str(payload.emoji)
|
|
|
|
|
|
|
|
|
|
# Log the reaction removal
|
|
|
|
|
await dm_logger.log_reaction_remove(
|
|
|
|
|
user_id=dm_user_id,
|
|
|
|
|
message_id=payload.message_id,
|
|
|
|
|
emoji=emoji_str,
|
|
|
|
|
reactor_id=user.id
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
reactor_type = "🤖 Miku" if user.id == globals.client.user.id else f"👤 {user.display_name}"
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.debug(f"DM reaction removed: {emoji_str} by {reactor_type} from message {payload.message_id}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
@globals.client.event
|
|
|
|
|
async def on_presence_update(before, after):
|
|
|
|
|
"""Track user presence changes for autonomous V2 system"""
|
|
|
|
|
# Discord.py passes before/after Member objects with different states
|
|
|
|
|
# We pass the 'after' member and both states for comparison
|
|
|
|
|
autonomous_presence_update(after, before, after)
|
|
|
|
|
|
|
|
|
|
@globals.client.event
|
|
|
|
|
async def on_member_join(member):
|
|
|
|
|
"""Track member joins for autonomous V2 system"""
|
|
|
|
|
autonomous_member_join(member)
|
|
|
|
|
|
2026-01-20 23:06:17 +02:00
|
|
|
@globals.client.event
|
|
|
|
|
async def on_voice_state_update(member: discord.Member, before: discord.VoiceState, after: discord.VoiceState):
|
|
|
|
|
"""Track voice channel join/leave for voice call management."""
|
|
|
|
|
from utils.voice_manager import VoiceSessionManager
|
|
|
|
|
|
|
|
|
|
session_manager = VoiceSessionManager()
|
|
|
|
|
if not session_manager.active_session:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Check if this is our voice channel
|
|
|
|
|
if before.channel != session_manager.active_session.voice_channel and \
|
|
|
|
|
after.channel != session_manager.active_session.voice_channel:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# User joined our voice channel
|
|
|
|
|
if before.channel != after.channel and after.channel == session_manager.active_session.voice_channel:
|
|
|
|
|
logger.info(f"👤 {member.name} joined voice channel")
|
|
|
|
|
await session_manager.active_session.on_user_join(member.id)
|
|
|
|
|
|
|
|
|
|
# Auto-start listening if this is a voice call
|
|
|
|
|
if session_manager.active_session.call_user_id == member.id:
|
|
|
|
|
await session_manager.active_session.start_listening(member)
|
|
|
|
|
|
|
|
|
|
# User left our voice channel
|
|
|
|
|
elif before.channel == session_manager.active_session.voice_channel and \
|
|
|
|
|
after.channel != before.channel:
|
|
|
|
|
logger.info(f"👤 {member.name} left voice channel")
|
|
|
|
|
await session_manager.active_session.on_user_leave(member.id)
|
|
|
|
|
|
|
|
|
|
# Stop listening to this user
|
|
|
|
|
await session_manager.active_session.stop_listening(member.id)
|
|
|
|
|
|
2025-12-07 17:15:09 +02:00
|
|
|
def start_api():
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
# Set log_level to "critical" to silence uvicorn's access logs
|
|
|
|
|
# Our custom api.requests middleware handles HTTP logging with better formatting and filtering
|
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=3939, log_level="critical")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
|
|
|
|
def save_autonomous_state():
|
|
|
|
|
"""Save autonomous context on shutdown"""
|
|
|
|
|
try:
|
|
|
|
|
from utils.autonomous import autonomous_engine
|
|
|
|
|
autonomous_engine.save_context()
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.info("💾 Saved autonomous context on shutdown")
|
2025-12-07 17:15:09 +02:00
|
|
|
except Exception as e:
|
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.
2026-01-10 20:46:19 +02:00
|
|
|
logger.error(f"Failed to save autonomous context on shutdown: {e}")
|
2025-12-07 17:15:09 +02:00
|
|
|
|
2026-02-18 12:08:32 +02:00
|
|
|
async def graceful_shutdown():
|
|
|
|
|
"""
|
|
|
|
|
Perform a full async cleanup before the bot exits.
|
|
|
|
|
|
|
|
|
|
Shutdown sequence:
|
|
|
|
|
1. End active voice sessions (disconnect, release GPU locks)
|
|
|
|
|
2. Save autonomous engine state
|
|
|
|
|
3. Stop the APScheduler
|
|
|
|
|
4. Cancel all tracked background tasks
|
|
|
|
|
5. Close the Discord gateway connection
|
|
|
|
|
"""
|
|
|
|
|
logger.warning("🛑 Graceful shutdown initiated...")
|
|
|
|
|
|
|
|
|
|
# 1. End active voice session (cleans up audio, STT, GPU locks, etc.)
|
|
|
|
|
try:
|
|
|
|
|
from utils.voice_manager import VoiceSessionManager
|
|
|
|
|
session_mgr = VoiceSessionManager()
|
|
|
|
|
if session_mgr.active_session:
|
|
|
|
|
logger.info("🎙️ Ending active voice session...")
|
|
|
|
|
await session_mgr.end_session()
|
|
|
|
|
logger.info("✓ Voice session ended")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error ending voice session during shutdown: {e}")
|
|
|
|
|
|
|
|
|
|
# 2. Persist autonomous engine state
|
|
|
|
|
save_autonomous_state()
|
|
|
|
|
|
|
|
|
|
# 3. Shut down the APScheduler
|
|
|
|
|
try:
|
|
|
|
|
if globals.scheduler.running:
|
|
|
|
|
globals.scheduler.shutdown(wait=False)
|
|
|
|
|
logger.info("✓ Scheduler stopped")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error stopping scheduler: {e}")
|
|
|
|
|
|
|
|
|
|
# 4. Cancel all tracked background tasks
|
|
|
|
|
try:
|
|
|
|
|
from utils.task_tracker import _active_tasks
|
|
|
|
|
pending = [t for t in _active_tasks if not t.done()]
|
|
|
|
|
if pending:
|
|
|
|
|
logger.info(f"Cancelling {len(pending)} background tasks...")
|
|
|
|
|
for t in pending:
|
|
|
|
|
t.cancel()
|
|
|
|
|
await asyncio.gather(*pending, return_exceptions=True)
|
|
|
|
|
logger.info("✓ Background tasks cancelled")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error cancelling background tasks: {e}")
|
|
|
|
|
|
|
|
|
|
# 5. Close the Discord gateway connection
|
|
|
|
|
try:
|
|
|
|
|
if not globals.client.is_closed():
|
|
|
|
|
await globals.client.close()
|
|
|
|
|
logger.info("✓ Discord client closed")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Error closing Discord client: {e}")
|
|
|
|
|
|
|
|
|
|
logger.warning("🛑 Graceful shutdown complete")
|
|
|
|
|
|
|
|
|
|
def _handle_shutdown_signal(sig, _frame):
|
|
|
|
|
"""Schedule the async shutdown from a sync signal handler."""
|
|
|
|
|
sig_name = signal.Signals(sig).name
|
|
|
|
|
logger.warning(f"Received {sig_name}, scheduling graceful shutdown...")
|
|
|
|
|
# Schedule the coroutine on the running event loop
|
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
|
if loop.is_running():
|
|
|
|
|
loop.create_task(graceful_shutdown())
|
|
|
|
|
else:
|
|
|
|
|
# Fallback: just save state synchronously
|
|
|
|
|
save_autonomous_state()
|
|
|
|
|
|
|
|
|
|
# Register signal handlers (async-aware)
|
|
|
|
|
signal.signal(signal.SIGTERM, _handle_shutdown_signal)
|
|
|
|
|
signal.signal(signal.SIGINT, _handle_shutdown_signal)
|
|
|
|
|
|
|
|
|
|
# Keep atexit as a last-resort sync fallback
|
2025-12-07 17:15:09 +02:00
|
|
|
atexit.register(save_autonomous_state)
|
|
|
|
|
|
|
|
|
|
threading.Thread(target=start_api, daemon=True).start()
|
|
|
|
|
globals.client.run(globals.DISCORD_BOT_TOKEN)
|